Contents of /trunk/kernel26-magellan/patches-2.6.35-r3/0301-2.6.35-CVE-2010-3301.patch
Parent Directory | Revision Log
Revision 1137 -
(show annotations)
(download)
Mon Sep 20 07:44:10 2010 UTC (14 years ago) by niro
File size: 7138 byte(s)
Mon Sep 20 07:44:10 2010 UTC (14 years ago) by niro
File size: 7138 byte(s)
-fixed patch
1 | From c41d68a513c71e35a14f66d71782d27a79a81ea6 Mon Sep 17 00:00:00 2001 |
2 | From: H. Peter Anvin <hpa@linux.intel.com> |
3 | Date: Tue, 7 Sep 2010 16:16:18 -0700 |
4 | Subject: [PATCH] compat: Make compat_alloc_user_space() incorporate the access_ok() |
5 | |
6 | compat_alloc_user_space() expects the caller to independently call |
7 | access_ok() to verify the returned area. A missing call could |
8 | introduce problems on some architectures. |
9 | |
10 | This patch incorporates the access_ok() check into |
11 | compat_alloc_user_space() and also adds a sanity check on the length. |
12 | The existing compat_alloc_user_space() implementations are renamed |
13 | arch_compat_alloc_user_space() and are used as part of the |
14 | implementation of the new global function. |
15 | |
16 | This patch assumes NULL will cause __get_user()/__put_user() to either |
17 | fail or access userspace on all architectures. This should be |
18 | followed by checking the return value of compat_access_user_space() |
19 | for NULL in the callers, at which time the access_ok() in the callers |
20 | can also be removed. |
21 | |
22 | Reported-by: Ben Hawkes <hawkes@sota.gen.nz> |
23 | Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> |
24 | Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> |
25 | Acked-by: Chris Metcalf <cmetcalf@tilera.com> |
26 | Acked-by: David S. Miller <davem@davemloft.net> |
27 | Acked-by: Ingo Molnar <mingo@elte.hu> |
28 | Acked-by: Thomas Gleixner <tglx@linutronix.de> |
29 | Acked-by: Tony Luck <tony.luck@intel.com> |
30 | Cc: Andrew Morton <akpm@linux-foundation.org> |
31 | Cc: Arnd Bergmann <arnd@arndb.de> |
32 | Cc: Fenghua Yu <fenghua.yu@intel.com> |
33 | Cc: H. Peter Anvin <hpa@zytor.com> |
34 | Cc: Heiko Carstens <heiko.carstens@de.ibm.com> |
35 | Cc: Helge Deller <deller@gmx.de> |
36 | Cc: James Bottomley <jejb@parisc-linux.org> |
37 | Cc: Kyle McMartin <kyle@mcmartin.ca> |
38 | Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> |
39 | Cc: Paul Mackerras <paulus@samba.org> |
40 | Cc: Ralf Baechle <ralf@linux-mips.org> |
41 | Cc: <stable@kernel.org> |
42 | --- |
43 | arch/ia64/include/asm/compat.h | 2 +- |
44 | arch/mips/include/asm/compat.h | 2 +- |
45 | arch/parisc/include/asm/compat.h | 2 +- |
46 | arch/powerpc/include/asm/compat.h | 2 +- |
47 | arch/s390/include/asm/compat.h | 2 +- |
48 | arch/sparc/include/asm/compat.h | 2 +- |
49 | arch/x86/include/asm/compat.h | 2 +- |
50 | include/linux/compat.h | 3 +++ |
51 | kernel/compat.c | 21 +++++++++++++++++++++ |
52 | 10 files changed, 32 insertions(+), 8 deletions(-) |
53 | |
54 | diff --git a/arch/ia64/include/asm/compat.h b/arch/ia64/include/asm/compat.h |
55 | index f90edc8..9301a28 100644 |
56 | --- a/arch/ia64/include/asm/compat.h |
57 | +++ b/arch/ia64/include/asm/compat.h |
58 | @@ -199,7 +199,7 @@ ptr_to_compat(void __user *uptr) |
59 | } |
60 | |
61 | static __inline__ void __user * |
62 | -compat_alloc_user_space (long len) |
63 | +arch_compat_alloc_user_space (long len) |
64 | { |
65 | struct pt_regs *regs = task_pt_regs(current); |
66 | return (void __user *) (((regs->r12 & 0xffffffff) & -16) - len); |
67 | diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h |
68 | index 613f691..dbc5106 100644 |
69 | --- a/arch/mips/include/asm/compat.h |
70 | +++ b/arch/mips/include/asm/compat.h |
71 | @@ -145,7 +145,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) |
72 | return (u32)(unsigned long)uptr; |
73 | } |
74 | |
75 | -static inline void __user *compat_alloc_user_space(long len) |
76 | +static inline void __user *arch_compat_alloc_user_space(long len) |
77 | { |
78 | struct pt_regs *regs = (struct pt_regs *) |
79 | ((unsigned long) current_thread_info() + THREAD_SIZE - 32) - 1; |
80 | diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h |
81 | index 02b77ba..efa0b60 100644 |
82 | --- a/arch/parisc/include/asm/compat.h |
83 | +++ b/arch/parisc/include/asm/compat.h |
84 | @@ -147,7 +147,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) |
85 | return (u32)(unsigned long)uptr; |
86 | } |
87 | |
88 | -static __inline__ void __user *compat_alloc_user_space(long len) |
89 | +static __inline__ void __user *arch_compat_alloc_user_space(long len) |
90 | { |
91 | struct pt_regs *regs = ¤t->thread.regs; |
92 | return (void __user *)regs->gr[30]; |
93 | diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h |
94 | index 396d21a..a11d4ea 100644 |
95 | --- a/arch/powerpc/include/asm/compat.h |
96 | +++ b/arch/powerpc/include/asm/compat.h |
97 | @@ -134,7 +134,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) |
98 | return (u32)(unsigned long)uptr; |
99 | } |
100 | |
101 | -static inline void __user *compat_alloc_user_space(long len) |
102 | +static inline void __user *arch_compat_alloc_user_space(long len) |
103 | { |
104 | struct pt_regs *regs = current->thread.regs; |
105 | unsigned long usp = regs->gpr[1]; |
106 | diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h |
107 | index 104f200..a875c2f 100644 |
108 | --- a/arch/s390/include/asm/compat.h |
109 | +++ b/arch/s390/include/asm/compat.h |
110 | @@ -181,7 +181,7 @@ static inline int is_compat_task(void) |
111 | |
112 | #endif |
113 | |
114 | -static inline void __user *compat_alloc_user_space(long len) |
115 | +static inline void __user *arch_compat_alloc_user_space(long len) |
116 | { |
117 | unsigned long stack; |
118 | |
119 | diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h |
120 | index 5016f76..6f57325 100644 |
121 | --- a/arch/sparc/include/asm/compat.h |
122 | +++ b/arch/sparc/include/asm/compat.h |
123 | @@ -167,7 +167,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) |
124 | return (u32)(unsigned long)uptr; |
125 | } |
126 | |
127 | -static inline void __user *compat_alloc_user_space(long len) |
128 | +static inline void __user *arch_compat_alloc_user_space(long len) |
129 | { |
130 | struct pt_regs *regs = current_thread_info()->kregs; |
131 | unsigned long usp = regs->u_regs[UREG_I6]; |
132 | diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h |
133 | index 306160e..1d9cd27 100644 |
134 | --- a/arch/x86/include/asm/compat.h |
135 | +++ b/arch/x86/include/asm/compat.h |
136 | @@ -205,7 +205,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) |
137 | return (u32)(unsigned long)uptr; |
138 | } |
139 | |
140 | -static inline void __user *compat_alloc_user_space(long len) |
141 | +static inline void __user *arch_compat_alloc_user_space(long len) |
142 | { |
143 | struct pt_regs *regs = task_pt_regs(current); |
144 | return (void __user *)regs->sp - len; |
145 | diff --git a/include/linux/compat.h b/include/linux/compat.h |
146 | index 9ddc878..5778b55 100644 |
147 | --- a/include/linux/compat.h |
148 | +++ b/include/linux/compat.h |
149 | @@ -360,5 +360,8 @@ extern ssize_t compat_rw_copy_check_uvector(int type, |
150 | const struct compat_iovec __user *uvector, unsigned long nr_segs, |
151 | unsigned long fast_segs, struct iovec *fast_pointer, |
152 | struct iovec **ret_pointer); |
153 | + |
154 | +extern void __user *compat_alloc_user_space(unsigned long len); |
155 | + |
156 | #endif /* CONFIG_COMPAT */ |
157 | #endif /* _LINUX_COMPAT_H */ |
158 | diff --git a/kernel/compat.c b/kernel/compat.c |
159 | index e167efc..c9e2ec0 100644 |
160 | --- a/kernel/compat.c |
161 | +++ b/kernel/compat.c |
162 | @@ -1126,3 +1126,24 @@ compat_sys_sysinfo(struct compat_sysinfo __user *info) |
163 | |
164 | return 0; |
165 | } |
166 | + |
167 | +/* |
168 | + * Allocate user-space memory for the duration of a single system call, |
169 | + * in order to marshall parameters inside a compat thunk. |
170 | + */ |
171 | +void __user *compat_alloc_user_space(unsigned long len) |
172 | +{ |
173 | + void __user *ptr; |
174 | + |
175 | + /* If len would occupy more than half of the entire compat space... */ |
176 | + if (unlikely(len > (((compat_uptr_t)~0) >> 1))) |
177 | + return NULL; |
178 | + |
179 | + ptr = arch_compat_alloc_user_space(len); |
180 | + |
181 | + if (unlikely(!access_ok(VERIFY_WRITE, ptr, len))) |
182 | + return NULL; |
183 | + |
184 | + return ptr; |
185 | +} |
186 | +EXPORT_SYMBOL_GPL(compat_alloc_user_space); |
187 | -- |
188 | 1.7.2.3 |
189 |