Skip to content

Commit 75045f7

Browse files
thejhKAGA-KOKO
authored andcommitted
x86/extable: Introduce _ASM_EXTABLE_UA for uaccess fixups
Currently, most fixups for attempting to access userspace memory are handled using _ASM_EXTABLE, which is also used for various other types of fixups (e.g. safe MSR access, IRET failures, and a bunch of other things). In order to make it possible to add special safety checks to uaccess fixups (in particular, checking whether the fault address is actually in userspace), introduce a new exception table handler ex_handler_uaccess() and wire it up to all the user access fixups (excluding ones that already use _ASM_EXTABLE_EX). Signed-off-by: Jann Horn <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Tested-by: Kees Cook <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: [email protected] Cc: [email protected] Cc: Masami Hiramatsu <[email protected]> Cc: "Naveen N. Rao" <[email protected]> Cc: Anil S Keshavamurthy <[email protected]> Cc: "David S. Miller" <[email protected]> Cc: Alexander Viro <[email protected]> Cc: [email protected] Cc: Borislav Petkov <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent e3e4d50 commit 75045f7

File tree

12 files changed

+160
-142
lines changed

12 files changed

+160
-142
lines changed

arch/x86/include/asm/asm.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@
130130
# define _ASM_EXTABLE(from, to) \
131131
_ASM_EXTABLE_HANDLE(from, to, ex_handler_default)
132132

133+
# define _ASM_EXTABLE_UA(from, to) \
134+
_ASM_EXTABLE_HANDLE(from, to, ex_handler_uaccess)
135+
133136
# define _ASM_EXTABLE_FAULT(from, to) \
134137
_ASM_EXTABLE_HANDLE(from, to, ex_handler_fault)
135138

@@ -165,8 +168,8 @@
165168
jmp copy_user_handle_tail
166169
.previous
167170

168-
_ASM_EXTABLE(100b,103b)
169-
_ASM_EXTABLE(101b,103b)
171+
_ASM_EXTABLE_UA(100b, 103b)
172+
_ASM_EXTABLE_UA(101b, 103b)
170173
.endm
171174

172175
#else
@@ -182,6 +185,9 @@
182185
# define _ASM_EXTABLE(from, to) \
183186
_ASM_EXTABLE_HANDLE(from, to, ex_handler_default)
184187

188+
# define _ASM_EXTABLE_UA(from, to) \
189+
_ASM_EXTABLE_HANDLE(from, to, ex_handler_uaccess)
190+
185191
# define _ASM_EXTABLE_FAULT(from, to) \
186192
_ASM_EXTABLE_HANDLE(from, to, ex_handler_fault)
187193

arch/x86/include/asm/fpu/internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ static inline void copy_fxregs_to_kernel(struct fpu *fpu)
226226
"3: movl $-2,%[err]\n\t" \
227227
"jmp 2b\n\t" \
228228
".popsection\n\t" \
229-
_ASM_EXTABLE(1b, 3b) \
229+
_ASM_EXTABLE_UA(1b, 3b) \
230230
: [err] "=r" (err) \
231231
: "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \
232232
: "memory")

arch/x86/include/asm/futex.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"3:\tmov\t%3, %1\n" \
2121
"\tjmp\t2b\n" \
2222
"\t.previous\n" \
23-
_ASM_EXTABLE(1b, 3b) \
23+
_ASM_EXTABLE_UA(1b, 3b) \
2424
: "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
2525
: "i" (-EFAULT), "0" (oparg), "1" (0))
2626

@@ -36,8 +36,8 @@
3636
"4:\tmov\t%5, %1\n" \
3737
"\tjmp\t3b\n" \
3838
"\t.previous\n" \
39-
_ASM_EXTABLE(1b, 4b) \
40-
_ASM_EXTABLE(2b, 4b) \
39+
_ASM_EXTABLE_UA(1b, 4b) \
40+
_ASM_EXTABLE_UA(2b, 4b) \
4141
: "=&a" (oldval), "=&r" (ret), \
4242
"+m" (*uaddr), "=&r" (tem) \
4343
: "r" (oparg), "i" (-EFAULT), "1" (0))

arch/x86/include/asm/uaccess.h

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
198198
"4: movl %3,%0\n" \
199199
" jmp 3b\n" \
200200
".previous\n" \
201-
_ASM_EXTABLE(1b, 4b) \
202-
_ASM_EXTABLE(2b, 4b) \
201+
_ASM_EXTABLE_UA(1b, 4b) \
202+
_ASM_EXTABLE_UA(2b, 4b) \
203203
: "=r" (err) \
204204
: "A" (x), "r" (addr), "i" (errret), "0" (err))
205205

@@ -340,8 +340,8 @@ do { \
340340
" xorl %%edx,%%edx\n" \
341341
" jmp 3b\n" \
342342
".previous\n" \
343-
_ASM_EXTABLE(1b, 4b) \
344-
_ASM_EXTABLE(2b, 4b) \
343+
_ASM_EXTABLE_UA(1b, 4b) \
344+
_ASM_EXTABLE_UA(2b, 4b) \
345345
: "=r" (retval), "=&A"(x) \
346346
: "m" (__m(__ptr)), "m" __m(((u32 __user *)(__ptr)) + 1), \
347347
"i" (errret), "0" (retval)); \
@@ -386,7 +386,7 @@ do { \
386386
" xor"itype" %"rtype"1,%"rtype"1\n" \
387387
" jmp 2b\n" \
388388
".previous\n" \
389-
_ASM_EXTABLE(1b, 3b) \
389+
_ASM_EXTABLE_UA(1b, 3b) \
390390
: "=r" (err), ltype(x) \
391391
: "m" (__m(addr)), "i" (errret), "0" (err))
392392

@@ -398,7 +398,7 @@ do { \
398398
"3: mov %3,%0\n" \
399399
" jmp 2b\n" \
400400
".previous\n" \
401-
_ASM_EXTABLE(1b, 3b) \
401+
_ASM_EXTABLE_UA(1b, 3b) \
402402
: "=r" (err), ltype(x) \
403403
: "m" (__m(addr)), "i" (errret), "0" (err))
404404

@@ -474,7 +474,7 @@ struct __large_struct { unsigned long buf[100]; };
474474
"3: mov %3,%0\n" \
475475
" jmp 2b\n" \
476476
".previous\n" \
477-
_ASM_EXTABLE(1b, 3b) \
477+
_ASM_EXTABLE_UA(1b, 3b) \
478478
: "=r"(err) \
479479
: ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
480480

@@ -602,7 +602,7 @@ extern void __cmpxchg_wrong_size(void)
602602
"3:\tmov %3, %0\n" \
603603
"\tjmp 2b\n" \
604604
"\t.previous\n" \
605-
_ASM_EXTABLE(1b, 3b) \
605+
_ASM_EXTABLE_UA(1b, 3b) \
606606
: "+r" (__ret), "=a" (__old), "+m" (*(ptr)) \
607607
: "i" (-EFAULT), "q" (__new), "1" (__old) \
608608
: "memory" \
@@ -618,7 +618,7 @@ extern void __cmpxchg_wrong_size(void)
618618
"3:\tmov %3, %0\n" \
619619
"\tjmp 2b\n" \
620620
"\t.previous\n" \
621-
_ASM_EXTABLE(1b, 3b) \
621+
_ASM_EXTABLE_UA(1b, 3b) \
622622
: "+r" (__ret), "=a" (__old), "+m" (*(ptr)) \
623623
: "i" (-EFAULT), "r" (__new), "1" (__old) \
624624
: "memory" \
@@ -634,7 +634,7 @@ extern void __cmpxchg_wrong_size(void)
634634
"3:\tmov %3, %0\n" \
635635
"\tjmp 2b\n" \
636636
"\t.previous\n" \
637-
_ASM_EXTABLE(1b, 3b) \
637+
_ASM_EXTABLE_UA(1b, 3b) \
638638
: "+r" (__ret), "=a" (__old), "+m" (*(ptr)) \
639639
: "i" (-EFAULT), "r" (__new), "1" (__old) \
640640
: "memory" \
@@ -653,7 +653,7 @@ extern void __cmpxchg_wrong_size(void)
653653
"3:\tmov %3, %0\n" \
654654
"\tjmp 2b\n" \
655655
"\t.previous\n" \
656-
_ASM_EXTABLE(1b, 3b) \
656+
_ASM_EXTABLE_UA(1b, 3b) \
657657
: "+r" (__ret), "=a" (__old), "+m" (*(ptr)) \
658658
: "i" (-EFAULT), "r" (__new), "1" (__old) \
659659
: "memory" \

arch/x86/lib/checksum_32.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,11 +273,11 @@ unsigned int csum_partial_copy_generic (const char *src, char *dst,
273273

274274
#define SRC(y...) \
275275
9999: y; \
276-
_ASM_EXTABLE(9999b, 6001f)
276+
_ASM_EXTABLE_UA(9999b, 6001f)
277277

278278
#define DST(y...) \
279279
9999: y; \
280-
_ASM_EXTABLE(9999b, 6002f)
280+
_ASM_EXTABLE_UA(9999b, 6002f)
281281

282282
#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
283283

arch/x86/lib/copy_user_64.S

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -92,26 +92,26 @@ ENTRY(copy_user_generic_unrolled)
9292
60: jmp copy_user_handle_tail /* ecx is zerorest also */
9393
.previous
9494

95-
_ASM_EXTABLE(1b,30b)
96-
_ASM_EXTABLE(2b,30b)
97-
_ASM_EXTABLE(3b,30b)
98-
_ASM_EXTABLE(4b,30b)
99-
_ASM_EXTABLE(5b,30b)
100-
_ASM_EXTABLE(6b,30b)
101-
_ASM_EXTABLE(7b,30b)
102-
_ASM_EXTABLE(8b,30b)
103-
_ASM_EXTABLE(9b,30b)
104-
_ASM_EXTABLE(10b,30b)
105-
_ASM_EXTABLE(11b,30b)
106-
_ASM_EXTABLE(12b,30b)
107-
_ASM_EXTABLE(13b,30b)
108-
_ASM_EXTABLE(14b,30b)
109-
_ASM_EXTABLE(15b,30b)
110-
_ASM_EXTABLE(16b,30b)
111-
_ASM_EXTABLE(18b,40b)
112-
_ASM_EXTABLE(19b,40b)
113-
_ASM_EXTABLE(21b,50b)
114-
_ASM_EXTABLE(22b,50b)
95+
_ASM_EXTABLE_UA(1b, 30b)
96+
_ASM_EXTABLE_UA(2b, 30b)
97+
_ASM_EXTABLE_UA(3b, 30b)
98+
_ASM_EXTABLE_UA(4b, 30b)
99+
_ASM_EXTABLE_UA(5b, 30b)
100+
_ASM_EXTABLE_UA(6b, 30b)
101+
_ASM_EXTABLE_UA(7b, 30b)
102+
_ASM_EXTABLE_UA(8b, 30b)
103+
_ASM_EXTABLE_UA(9b, 30b)
104+
_ASM_EXTABLE_UA(10b, 30b)
105+
_ASM_EXTABLE_UA(11b, 30b)
106+
_ASM_EXTABLE_UA(12b, 30b)
107+
_ASM_EXTABLE_UA(13b, 30b)
108+
_ASM_EXTABLE_UA(14b, 30b)
109+
_ASM_EXTABLE_UA(15b, 30b)
110+
_ASM_EXTABLE_UA(16b, 30b)
111+
_ASM_EXTABLE_UA(18b, 40b)
112+
_ASM_EXTABLE_UA(19b, 40b)
113+
_ASM_EXTABLE_UA(21b, 50b)
114+
_ASM_EXTABLE_UA(22b, 50b)
115115
ENDPROC(copy_user_generic_unrolled)
116116
EXPORT_SYMBOL(copy_user_generic_unrolled)
117117

@@ -156,8 +156,8 @@ ENTRY(copy_user_generic_string)
156156
jmp copy_user_handle_tail
157157
.previous
158158

159-
_ASM_EXTABLE(1b,11b)
160-
_ASM_EXTABLE(3b,12b)
159+
_ASM_EXTABLE_UA(1b, 11b)
160+
_ASM_EXTABLE_UA(3b, 12b)
161161
ENDPROC(copy_user_generic_string)
162162
EXPORT_SYMBOL(copy_user_generic_string)
163163

@@ -189,7 +189,7 @@ ENTRY(copy_user_enhanced_fast_string)
189189
jmp copy_user_handle_tail
190190
.previous
191191

192-
_ASM_EXTABLE(1b,12b)
192+
_ASM_EXTABLE_UA(1b, 12b)
193193
ENDPROC(copy_user_enhanced_fast_string)
194194
EXPORT_SYMBOL(copy_user_enhanced_fast_string)
195195

@@ -319,27 +319,27 @@ ENTRY(__copy_user_nocache)
319319
jmp copy_user_handle_tail
320320
.previous
321321

322-
_ASM_EXTABLE(1b,.L_fixup_4x8b_copy)
323-
_ASM_EXTABLE(2b,.L_fixup_4x8b_copy)
324-
_ASM_EXTABLE(3b,.L_fixup_4x8b_copy)
325-
_ASM_EXTABLE(4b,.L_fixup_4x8b_copy)
326-
_ASM_EXTABLE(5b,.L_fixup_4x8b_copy)
327-
_ASM_EXTABLE(6b,.L_fixup_4x8b_copy)
328-
_ASM_EXTABLE(7b,.L_fixup_4x8b_copy)
329-
_ASM_EXTABLE(8b,.L_fixup_4x8b_copy)
330-
_ASM_EXTABLE(9b,.L_fixup_4x8b_copy)
331-
_ASM_EXTABLE(10b,.L_fixup_4x8b_copy)
332-
_ASM_EXTABLE(11b,.L_fixup_4x8b_copy)
333-
_ASM_EXTABLE(12b,.L_fixup_4x8b_copy)
334-
_ASM_EXTABLE(13b,.L_fixup_4x8b_copy)
335-
_ASM_EXTABLE(14b,.L_fixup_4x8b_copy)
336-
_ASM_EXTABLE(15b,.L_fixup_4x8b_copy)
337-
_ASM_EXTABLE(16b,.L_fixup_4x8b_copy)
338-
_ASM_EXTABLE(20b,.L_fixup_8b_copy)
339-
_ASM_EXTABLE(21b,.L_fixup_8b_copy)
340-
_ASM_EXTABLE(30b,.L_fixup_4b_copy)
341-
_ASM_EXTABLE(31b,.L_fixup_4b_copy)
342-
_ASM_EXTABLE(40b,.L_fixup_1b_copy)
343-
_ASM_EXTABLE(41b,.L_fixup_1b_copy)
322+
_ASM_EXTABLE_UA(1b, .L_fixup_4x8b_copy)
323+
_ASM_EXTABLE_UA(2b, .L_fixup_4x8b_copy)
324+
_ASM_EXTABLE_UA(3b, .L_fixup_4x8b_copy)
325+
_ASM_EXTABLE_UA(4b, .L_fixup_4x8b_copy)
326+
_ASM_EXTABLE_UA(5b, .L_fixup_4x8b_copy)
327+
_ASM_EXTABLE_UA(6b, .L_fixup_4x8b_copy)
328+
_ASM_EXTABLE_UA(7b, .L_fixup_4x8b_copy)
329+
_ASM_EXTABLE_UA(8b, .L_fixup_4x8b_copy)
330+
_ASM_EXTABLE_UA(9b, .L_fixup_4x8b_copy)
331+
_ASM_EXTABLE_UA(10b, .L_fixup_4x8b_copy)
332+
_ASM_EXTABLE_UA(11b, .L_fixup_4x8b_copy)
333+
_ASM_EXTABLE_UA(12b, .L_fixup_4x8b_copy)
334+
_ASM_EXTABLE_UA(13b, .L_fixup_4x8b_copy)
335+
_ASM_EXTABLE_UA(14b, .L_fixup_4x8b_copy)
336+
_ASM_EXTABLE_UA(15b, .L_fixup_4x8b_copy)
337+
_ASM_EXTABLE_UA(16b, .L_fixup_4x8b_copy)
338+
_ASM_EXTABLE_UA(20b, .L_fixup_8b_copy)
339+
_ASM_EXTABLE_UA(21b, .L_fixup_8b_copy)
340+
_ASM_EXTABLE_UA(30b, .L_fixup_4b_copy)
341+
_ASM_EXTABLE_UA(31b, .L_fixup_4b_copy)
342+
_ASM_EXTABLE_UA(40b, .L_fixup_1b_copy)
343+
_ASM_EXTABLE_UA(41b, .L_fixup_1b_copy)
344344
ENDPROC(__copy_user_nocache)
345345
EXPORT_SYMBOL(__copy_user_nocache)

arch/x86/lib/csum-copy_64.S

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,18 @@
3131

3232
.macro source
3333
10:
34-
_ASM_EXTABLE(10b, .Lbad_source)
34+
_ASM_EXTABLE_UA(10b, .Lbad_source)
3535
.endm
3636

3737
.macro dest
3838
20:
39-
_ASM_EXTABLE(20b, .Lbad_dest)
39+
_ASM_EXTABLE_UA(20b, .Lbad_dest)
4040
.endm
4141

42+
/*
43+
* No _ASM_EXTABLE_UA; this is used for intentional prefetch on a
44+
* potentially unmapped kernel address.
45+
*/
4246
.macro ignore L=.Lignore
4347
30:
4448
_ASM_EXTABLE(30b, \L)

arch/x86/lib/getuser.S

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,12 @@ bad_get_user_8:
132132
END(bad_get_user_8)
133133
#endif
134134

135-
_ASM_EXTABLE(1b,bad_get_user)
136-
_ASM_EXTABLE(2b,bad_get_user)
137-
_ASM_EXTABLE(3b,bad_get_user)
135+
_ASM_EXTABLE_UA(1b, bad_get_user)
136+
_ASM_EXTABLE_UA(2b, bad_get_user)
137+
_ASM_EXTABLE_UA(3b, bad_get_user)
138138
#ifdef CONFIG_X86_64
139-
_ASM_EXTABLE(4b,bad_get_user)
139+
_ASM_EXTABLE_UA(4b, bad_get_user)
140140
#else
141-
_ASM_EXTABLE(4b,bad_get_user_8)
142-
_ASM_EXTABLE(5b,bad_get_user_8)
141+
_ASM_EXTABLE_UA(4b, bad_get_user_8)
142+
_ASM_EXTABLE_UA(5b, bad_get_user_8)
143143
#endif

arch/x86/lib/putuser.S

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,10 @@ bad_put_user:
9494
EXIT
9595
END(bad_put_user)
9696

97-
_ASM_EXTABLE(1b,bad_put_user)
98-
_ASM_EXTABLE(2b,bad_put_user)
99-
_ASM_EXTABLE(3b,bad_put_user)
100-
_ASM_EXTABLE(4b,bad_put_user)
97+
_ASM_EXTABLE_UA(1b, bad_put_user)
98+
_ASM_EXTABLE_UA(2b, bad_put_user)
99+
_ASM_EXTABLE_UA(3b, bad_put_user)
100+
_ASM_EXTABLE_UA(4b, bad_put_user)
101101
#ifdef CONFIG_X86_32
102-
_ASM_EXTABLE(5b,bad_put_user)
102+
_ASM_EXTABLE_UA(5b, bad_put_user)
103103
#endif

0 commit comments

Comments
 (0)