diff options
author | Andreas Schwab <schwab@suse.de> | 2008-11-06 03:49:00 +0300 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-11-11 11:42:22 +0300 |
commit | 77eb50aefa5dd2337246dce8b66e18e837c1a8bc (patch) | |
tree | 76232c81ab3f3badfbd45b5793dc4637fd2ed0dd /arch/powerpc/kernel/signal_32.c | |
parent | ec5d7657f746c46b5fbb3dbec6d0f7d8b6b82961 (diff) | |
download | linux-77eb50aefa5dd2337246dce8b66e18e837c1a8bc.tar.xz |
powerpc: Fix msr check in compat_sys_swapcontext
The new context may not be 16-byte aligned, so the real address of the
mcontext structure should be read from the uc_regs pointer instead of
directly using the (unaligned) uc_mcontext field.
Signed-off-by: Andreas Schwab <schwab@suse.de>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/signal_32.c')
-rw-r--r-- | arch/powerpc/kernel/signal_32.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index a6a43103655e..b13abf305996 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -941,9 +941,21 @@ long sys_swapcontext(struct ucontext __user *old_ctx, #ifdef CONFIG_PPC64 unsigned long new_msr = 0; - if (new_ctx && - get_user(new_msr, &new_ctx->uc_mcontext.mc_gregs[PT_MSR])) - return -EFAULT; + if (new_ctx) { + struct mcontext __user *mcp; + u32 cmcp; + + /* + * Get pointer to the real mcontext. No need for + * access_ok since we are dealing with compat + * pointers. + */ + if (__get_user(cmcp, &new_ctx->uc_regs)) + return -EFAULT; + mcp = (struct mcontext __user *)(u64)cmcp; + if (__get_user(new_msr, &mcp->mc_gregs[PT_MSR])) + return -EFAULT; + } /* * Check that the context is not smaller than the original * size (with VMX but without VSX) |