summaryrefslogtreecommitdiffstats
path: root/meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.33-copy-checks.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.33-copy-checks.patch')
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.33-copy-checks.patch275
1 files changed, 275 insertions, 0 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.33-copy-checks.patch b/meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.33-copy-checks.patch
new file mode 100644
index 0000000000..720fda24e8
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.33-copy-checks.patch
@@ -0,0 +1,275 @@
1From 524a1da3c45683cec77480acc6cab1d33ae8d5cb Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sat, 26 Sep 2009 12:36:21 +0200
4Subject: [PATCH] x86: Use __builtin_object_size to validate the buffer size for copy_from_user
5
6gcc (4.x) supports the __builtin_object_size() builtin, which reports the
7size of an object that a pointer point to, when known at compile time.
8If the buffer size is not known at compile time, a constant -1 is returned.
9
10This patch uses this feature to add a sanity check to copy_from_user();
11if the target buffer is known to be smaller than the copy size, the copy
12is aborted and a WARNing is emitted in memory debug mode.
13
14These extra checks compile away when the object size is not known,
15or if both the buffer size and the copy length are constants.
16
17Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
18Reviewed-by: Ingo Molnar <mingo@elte.hu>
19---
20 arch/x86/include/asm/uaccess_32.h | 19 ++++++++++++++++++-
21 arch/x86/include/asm/uaccess_64.h | 19 ++++++++++++++++++-
22 arch/x86/kernel/x8664_ksyms_64.c | 2 +-
23 arch/x86/lib/copy_user_64.S | 4 ++--
24 arch/x86/lib/usercopy_32.c | 4 ++--
25 include/linux/compiler-gcc4.h | 2 ++
26 include/linux/compiler.h | 4 ++++
27 7 files changed, 47 insertions(+), 7 deletions(-)
28
29diff --git a/arch/x86/include/asm/uaccess_32.h b/arch/x86/include/asm/uaccess_32.h
30index 632fb44..582d6ae 100644
31--- a/arch/x86/include/asm/uaccess_32.h
32+++ b/arch/x86/include/asm/uaccess_32.h
33@@ -187,9 +187,26 @@ __copy_from_user_inatomic_nocache(void *to, const void __user *from,
34
35 unsigned long __must_check copy_to_user(void __user *to,
36 const void *from, unsigned long n);
37-unsigned long __must_check copy_from_user(void *to,
38+unsigned long __must_check _copy_from_user(void *to,
39 const void __user *from,
40 unsigned long n);
41+
42+static inline unsigned long __must_check copy_from_user(void *to,
43+ const void __user *from,
44+ unsigned long n)
45+{
46+ int sz = __compiletime_object_size(to);
47+ int ret = -EFAULT;
48+
49+ if (likely(sz == -1 || sz >= n))
50+ ret = _copy_from_user(to, from, n);
51+#ifdef CONFIG_DEBUG_VM
52+ else
53+ WARN(1, "Buffer overflow detected!\n");
54+#endif
55+ return ret;
56+}
57+
58 long __must_check strncpy_from_user(char *dst, const char __user *src,
59 long count);
60 long __must_check __strncpy_from_user(char *dst,
61diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h
62index db24b21..ce6fec7 100644
63--- a/arch/x86/include/asm/uaccess_64.h
64+++ b/arch/x86/include/asm/uaccess_64.h
65@@ -21,10 +21,27 @@ copy_user_generic(void *to, const void *from, unsigned len);
66 __must_check unsigned long
67 copy_to_user(void __user *to, const void *from, unsigned len);
68 __must_check unsigned long
69-copy_from_user(void *to, const void __user *from, unsigned len);
70+_copy_from_user(void *to, const void __user *from, unsigned len);
71 __must_check unsigned long
72 copy_in_user(void __user *to, const void __user *from, unsigned len);
73
74+static inline unsigned long __must_check copy_from_user(void *to,
75+ const void __user *from,
76+ unsigned long n)
77+{
78+ int sz = __compiletime_object_size(to);
79+ int ret = -EFAULT;
80+
81+ if (likely(sz == -1 || sz >= n))
82+ ret = _copy_from_user(to, from, n);
83+#ifdef CONFIG_DEBUG_VM
84+ else
85+ WARN(1, "Buffer overflow detected!\n");
86+#endif
87+ return ret;
88+}
89+
90+
91 static __always_inline __must_check
92 int __copy_from_user(void *dst, const void __user *src, unsigned size)
93 {
94diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c
95index 3909e3b..a0cdd8c 100644
96--- a/arch/x86/kernel/x8664_ksyms_64.c
97+++ b/arch/x86/kernel/x8664_ksyms_64.c
98@@ -30,7 +30,7 @@ EXPORT_SYMBOL(__put_user_8);
99
100 EXPORT_SYMBOL(copy_user_generic);
101 EXPORT_SYMBOL(__copy_user_nocache);
102-EXPORT_SYMBOL(copy_from_user);
103+EXPORT_SYMBOL(_copy_from_user);
104 EXPORT_SYMBOL(copy_to_user);
105 EXPORT_SYMBOL(__copy_from_user_inatomic);
106
107diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S
108index 6ba0f7b..4be3c41 100644
109--- a/arch/x86/lib/copy_user_64.S
110+++ b/arch/x86/lib/copy_user_64.S
111@@ -78,7 +78,7 @@ ENTRY(copy_to_user)
112 ENDPROC(copy_to_user)
113
114 /* Standard copy_from_user with segment limit checking */
115-ENTRY(copy_from_user)
116+ENTRY(_copy_from_user)
117 CFI_STARTPROC
118 GET_THREAD_INFO(%rax)
119 movq %rsi,%rcx
120@@ -88,7 +88,7 @@ ENTRY(copy_from_user)
121 jae bad_from_user
122 ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
123 CFI_ENDPROC
124-ENDPROC(copy_from_user)
125+ENDPROC(_copy_from_user)
126
127 ENTRY(copy_user_generic)
128 CFI_STARTPROC
129diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c
130index 1f118d4..8498684 100644
131--- a/arch/x86/lib/usercopy_32.c
132+++ b/arch/x86/lib/usercopy_32.c
133@@ -874,7 +874,7 @@ EXPORT_SYMBOL(copy_to_user);
134 * data to the requested size using zero bytes.
135 */
136 unsigned long
137-copy_from_user(void *to, const void __user *from, unsigned long n)
138+_copy_from_user(void *to, const void __user *from, unsigned long n)
139 {
140 if (access_ok(VERIFY_READ, from, n))
141 n = __copy_from_user(to, from, n);
142@@ -882,4 +882,4 @@ copy_from_user(void *to, const void __user *from, unsigned long n)
143 memset(to, 0, n);
144 return n;
145 }
146-EXPORT_SYMBOL(copy_from_user);
147+EXPORT_SYMBOL(_copy_from_user);
148diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
149index 450fa59..a3aef5d 100644
150--- a/include/linux/compiler-gcc4.h
151+++ b/include/linux/compiler-gcc4.h
152@@ -37,3 +37,5 @@
153 #define __cold __attribute__((__cold__))
154
155 #endif
156+
157+#define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
158diff --git a/include/linux/compiler.h b/include/linux/compiler.h
159index 9d4c4b0..9c42853 100644
160--- a/include/linux/compiler.h
161+++ b/include/linux/compiler.h
162@@ -185,6 +185,10 @@ extern void __chk_io_ptr(const volatile void __iomem *);
163 # define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
164 #endif
165
166+/* Compile time object size, -1 for unknown */
167+#ifndef __compiletime_object_size
168+# define __compiletime_object_size(obj) -1
169+#endif
170 /*
171 * Prevent the compiler from merging or refetching accesses. The compiler
172 * is also forbidden from reordering successive instances of ACCESS_ONCE(),
173--
1741.6.0.6
175
176From 350cf3cd513e6759ae6852946532a47249f25600 Mon Sep 17 00:00:00 2001
177From: Arjan van de Ven <arjan@linux.intel.com>
178Date: Wed, 30 Sep 2009 12:57:46 +0200
179Subject: [PATCH] x86: Turn the copy_from_user check into an (optional) compile time warning
180
181A previous patch added the buffer size check to copy_from_user().
182
183One of the things learned from analyzing the result of the previous patch
184is that in general, gcc is really good at proving that the code contains
185sufficient security checks to not need to do a runtime check. But that
186for those cases where gcc could not prove this, there was a relatively
187high percentage of real security issues.
188
189This patch turns the case of "gcc cannot prove" into a compile time
190warning, as long as a sufficiently new gcc is in use.
191The objective is that these warnings will trigger developers checking
192new cases out before a security hole enters a linux kernel release.
193
194Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
195---
196 arch/x86/include/asm/uaccess_32.h | 12 +++++++++---
197 arch/x86/lib/usercopy_32.c | 6 ++++++
198 include/linux/compiler-gcc4.h | 3 +++
199 include/linux/compiler.h | 4 ++++
200 4 files changed, 22 insertions(+), 3 deletions(-)
201
202diff --git a/arch/x86/include/asm/uaccess_32.h b/arch/x86/include/asm/uaccess_32.h
203index 582d6ae..7826639 100644
204--- a/arch/x86/include/asm/uaccess_32.h
205+++ b/arch/x86/include/asm/uaccess_32.h
206@@ -191,6 +191,13 @@ unsigned long __must_check _copy_from_user(void *to,
207 const void __user *from,
208 unsigned long n);
209
210+
211+extern void copy_from_user_overflow(void)
212+#ifdef CONFIG_DEBUG_STACKOVERFLOW
213+ __compiletime_warning("copy_from_user buffer size is not provably correct")
214+#endif
215+;
216+
217 static inline unsigned long __must_check copy_from_user(void *to,
218 const void __user *from,
219 unsigned long n)
220@@ -200,10 +207,9 @@ static inline unsigned long __must_check copy_from_user(void *to,
221
222 if (likely(sz == -1 || sz >= n))
223 ret = _copy_from_user(to, from, n);
224-#ifdef CONFIG_DEBUG_VM
225 else
226- WARN(1, "Buffer overflow detected!\n");
227-#endif
228+ copy_from_user_overflow();
229+
230 return ret;
231 }
232
233diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c
234index 8498684..e218d5d 100644
235--- a/arch/x86/lib/usercopy_32.c
236+++ b/arch/x86/lib/usercopy_32.c
237@@ -883,3 +883,9 @@ _copy_from_user(void *to, const void __user *from, unsigned long n)
238 return n;
239 }
240 EXPORT_SYMBOL(_copy_from_user);
241+
242+void copy_from_user_overflow(void)
243+{
244+ WARN(1, "Buffer overflow detected!\n");
245+}
246+EXPORT_SYMBOL(copy_from_user_overflow);
247diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
248index a3aef5d..f1709c1 100644
249--- a/include/linux/compiler-gcc4.h
250+++ b/include/linux/compiler-gcc4.h
251@@ -39,3 +39,6 @@
252 #endif
253
254 #define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
255+#if __GNUC_MINOR__ >= 4
256+#define __compiletime_warning(message) __attribute__((warning(message)))
257+#endif
258diff --git a/include/linux/compiler.h b/include/linux/compiler.h
259index 9c42853..241dfd8 100644
260--- a/include/linux/compiler.h
261+++ b/include/linux/compiler.h
262@@ -189,6 +189,10 @@ extern void __chk_io_ptr(const volatile void __iomem *);
263 #ifndef __compiletime_object_size
264 # define __compiletime_object_size(obj) -1
265 #endif
266+#ifndef __compiletime_warning
267+# define __compiletime_warning(message)
268+#endif
269+
270 /*
271 * Prevent the compiler from merging or refetching accesses. The compiler
272 * is also forbidden from reordering successive instances of ACCESS_ONCE(),
273--
2741.6.2.5
275