diff options
author | Andi Kleen <ak@suse.de> | 2006-07-10 17:06:24 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-10 15:12:33 -0700 |
commit | 2c87e2cd0b57f63c226cd51f55ccc36867541a24 (patch) | |
tree | 78de73e00823aa0b29ebc2570e67207f42f957f0 /arch/x86_64 | |
parent | 1cfcea1b2d67987ddb84dc75f454321bcf536555 (diff) | |
download | linux-stable-2c87e2cd0b57f63c226cd51f55ccc36867541a24.tar.gz linux-stable-2c87e2cd0b57f63c226cd51f55ccc36867541a24.tar.bz2 linux-stable-2c87e2cd0b57f63c226cd51f55ccc36867541a24.zip |
[PATCH] x86_64: Fix access check in ptrace compat
We can't safely directly access an compat_alloc_user_space() pointer
with the siginfo copy functions. Bounce it through the stack.
Noticed by Al Viro using sparse
[ This was only added post 2.6.17, not in any released kernel ]
Cc: Al Viro <viro@ftp.linux.org.uk>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64')
-rw-r--r-- | arch/x86_64/ia32/ptrace32.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c index a590b7a0d92d..659c0722f6b8 100644 --- a/arch/x86_64/ia32/ptrace32.c +++ b/arch/x86_64/ia32/ptrace32.c @@ -202,17 +202,24 @@ static long ptrace32_siginfo(unsigned request, u32 pid, u32 addr, u32 data) { int ret; compat_siginfo_t *si32 = (compat_siginfo_t *)compat_ptr(data); + siginfo_t ssi; siginfo_t *si = compat_alloc_user_space(sizeof(siginfo_t)); if (request == PTRACE_SETSIGINFO) { - ret = copy_siginfo_from_user32(si, si32); + memset(&ssi, 0, sizeof(siginfo_t)); + ret = copy_siginfo_from_user32(&ssi, si32); if (ret) return ret; + if (copy_to_user(si, &ssi, sizeof(siginfo_t))) + return -EFAULT; } ret = sys_ptrace(request, pid, addr, (unsigned long)si); if (ret) return ret; - if (request == PTRACE_GETSIGINFO) - ret = copy_siginfo_to_user32(si32, si); + if (request == PTRACE_GETSIGINFO) { + if (copy_from_user(&ssi, si, sizeof(siginfo_t))) + return -EFAULT; + ret = copy_siginfo_to_user32(si32, &ssi); + } return ret; } |