]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Linus Torvalds <torvalds@linux-foundation.org> |
2 | Date: Sat, 1 Aug 2009 17:34:56 +0000 (-0700) | |
3 | Subject: do_sigaltstack: avoid copying 'stack_t' as a structure to user space | |
4 | Git-commit: 0083fc2c50e6c5127c2802ad323adf8143ab7856 | |
5 | Patch-mainline: 2.6.31 | |
6 | References: bnc#527848 | |
7 | ||
8 | do_sigaltstack: avoid copying 'stack_t' as a structure to user space | |
9 | ||
10 | Ulrich Drepper correctly points out that there is generally padding in | |
11 | the structure on 64-bit hosts, and that copying the structure from | |
12 | kernel to user space can leak information from the kernel stack in those | |
13 | padding bytes. | |
14 | ||
15 | Avoid the whole issue by just copying the three members one by one | |
16 | instead, which also means that the function also can avoid the need for | |
17 | a stack frame. This also happens to match how we copy the new structure | |
18 | from user space, so it all even makes sense. | |
19 | ||
20 | [ The obvious solution of adding a memset() generates horrid code, gcc | |
21 | does really stupid things. ] | |
22 | ||
23 | Reported-by: Ulrich Drepper <drepper@redhat.com> | |
24 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | |
25 | Acked-by: Jeff Mahoney <jeffm@suse.com> | |
26 | --- | |
27 | ||
28 | kernel/signal.c | 15 ++++++++------- | |
29 | 1 file changed, 8 insertions(+), 7 deletions(-) | |
30 | ||
31 | --- a/kernel/signal.c | |
32 | +++ b/kernel/signal.c | |
33 | @@ -2353,11 +2353,9 @@ do_sigaltstack (const stack_t __user *us | |
34 | stack_t oss; | |
35 | int error; | |
36 | ||
37 | - if (uoss) { | |
38 | - oss.ss_sp = (void __user *) current->sas_ss_sp; | |
39 | - oss.ss_size = current->sas_ss_size; | |
40 | - oss.ss_flags = sas_ss_flags(sp); | |
41 | - } | |
42 | + oss.ss_sp = (void __user *) current->sas_ss_sp; | |
43 | + oss.ss_size = current->sas_ss_size; | |
44 | + oss.ss_flags = sas_ss_flags(sp); | |
45 | ||
46 | if (uss) { | |
47 | void __user *ss_sp; | |
48 | @@ -2400,13 +2398,16 @@ do_sigaltstack (const stack_t __user *us | |
49 | current->sas_ss_size = ss_size; | |
50 | } | |
51 | ||
52 | + error = 0; | |
53 | if (uoss) { | |
54 | error = -EFAULT; | |
55 | - if (copy_to_user(uoss, &oss, sizeof(oss))) | |
56 | + if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss))) | |
57 | goto out; | |
58 | + error = __put_user(oss.ss_sp, &uoss->ss_sp) | | |
59 | + __put_user(oss.ss_size, &uoss->ss_size) | | |
60 | + __put_user(oss.ss_flags, &uoss->ss_flags); | |
61 | } | |
62 | ||
63 | - error = 0; | |
64 | out: | |
65 | return error; | |
66 | } |