aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2006-07-10 11:06:24 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-07-10 18:12:33 -0400
commit2c87e2cd0b57f63c226cd51f55ccc36867541a24 (patch)
tree78de73e00823aa0b29ebc2570e67207f42f957f0
parent1cfcea1b2d67987ddb84dc75f454321bcf536555 (diff)
[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>
-rw-r--r--arch/x86_64/ia32/ptrace32.c13
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)
202{ 202{
203 int ret; 203 int ret;
204 compat_siginfo_t *si32 = (compat_siginfo_t *)compat_ptr(data); 204 compat_siginfo_t *si32 = (compat_siginfo_t *)compat_ptr(data);
205 siginfo_t ssi;
205 siginfo_t *si = compat_alloc_user_space(sizeof(siginfo_t)); 206 siginfo_t *si = compat_alloc_user_space(sizeof(siginfo_t));
206 if (request == PTRACE_SETSIGINFO) { 207 if (request == PTRACE_SETSIGINFO) {
207 ret = copy_siginfo_from_user32(si, si32); 208 memset(&ssi, 0, sizeof(siginfo_t));
209 ret = copy_siginfo_from_user32(&ssi, si32);
208 if (ret) 210 if (ret)
209 return ret; 211 return ret;
212 if (copy_to_user(si, &ssi, sizeof(siginfo_t)))
213 return -EFAULT;
210 } 214 }
211 ret = sys_ptrace(request, pid, addr, (unsigned long)si); 215 ret = sys_ptrace(request, pid, addr, (unsigned long)si);
212 if (ret) 216 if (ret)
213 return ret; 217 return ret;
214 if (request == PTRACE_GETSIGINFO) 218 if (request == PTRACE_GETSIGINFO) {
215 ret = copy_siginfo_to_user32(si32, si); 219 if (copy_from_user(&ssi, si, sizeof(siginfo_t)))
220 return -EFAULT;
221 ret = copy_siginfo_to_user32(si32, &ssi);
222 }
216 return ret; 223 return ret;
217} 224}
218 225