From: Oleg Nesterov on
sys_personality(personality) is obviously wrong. It calls set_personality()
which always sets current->personality = personality and then does

if (current->personality != personality)
return -EINVAL;

If this "u_long" argument doesn't fit into "unsigned int" ->personality,
we return -EINVAL but change the caller's ->personality.

Move this check up to ensure the overflow is not possible, before calling
set_personality() which never fails.

Pointed-out-by: Wenming Zhang <wezhang(a)redhat.com>
Signed-off-by: Oleg Nesterov <oleg(a)redhat.com>
---

kernel/exec_domain.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

--- 34-rc1/kernel/exec_domain.c~1_CK_OVERFLOW_EARLIER 2009-04-06 00:03:42.000000000 +0200
+++ 34-rc1/kernel/exec_domain.c 2010-05-27 15:15:12.000000000 +0200
@@ -193,9 +193,9 @@ SYSCALL_DEFINE1(personality, u_long, per
u_long old = current->personality;

if (personality != 0xffffffff) {
- set_personality(personality);
- if (current->personality != personality)
+ if ((unsigned int)personality != personality)
return -EINVAL;
+ set_personality(personality);
}

return (long)old;

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/