Skip to content

Commit 2190fed

Browse files
author
Russell King
committed
ARM: entry: provide uaccess assembly macro hooks
Provide hooks into the kernel entry and exit paths to permit control of userspace visibility to the kernel. The intended use is: - on entry to kernel from user, uaccess_disable will be called to disable userspace visibility - on exit from kernel to user, uaccess_enable will be called to enable userspace visibility - on entry from a kernel exception, uaccess_save_and_disable will be called to save the current userspace visibility setting, and disable access - on exit from a kernel exception, uaccess_restore will be called to restore the userspace visibility as it was before the exception occurred. These hooks allows us to keep userspace visibility disabled for the vast majority of the kernel, except for localised regions where we want to explicitly access userspace. Signed-off-by: Russell King <[email protected]>
1 parent aa06e5c commit 2190fed

File tree

11 files changed

+55
-11
lines changed

11 files changed

+55
-11
lines changed

arch/arm/include/asm/assembler.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,23 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
445445
#endif
446446
.endm
447447

448+
.macro uaccess_disable, tmp, isb=1
449+
.endm
450+
451+
.macro uaccess_enable, tmp, isb=1
452+
.endm
453+
454+
.macro uaccess_save, tmp
455+
.endm
456+
457+
.macro uaccess_restore
458+
.endm
459+
460+
.macro uaccess_save_and_disable, tmp
461+
uaccess_save \tmp
462+
uaccess_disable \tmp
463+
.endm
464+
448465
.irp c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo
449466
.macro ret\c, reg
450467
#if __LINUX_ARM_ARCH__ < 6

arch/arm/kernel/entry-armv.S

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,10 @@ ENDPROC(__und_invalid)
149149
#define SPFIX(code...)
150150
#endif
151151

152-
.macro svc_entry, stack_hole=0, trace=1
152+
.macro svc_entry, stack_hole=0, trace=1, uaccess=1
153153
UNWIND(.fnstart )
154154
UNWIND(.save {r0 - pc} )
155-
sub sp, sp, #(S_FRAME_SIZE + \stack_hole - 4)
155+
sub sp, sp, #(S_FRAME_SIZE + 8 + \stack_hole - 4)
156156
#ifdef CONFIG_THUMB2_KERNEL
157157
SPFIX( str r0, [sp] ) @ temporarily saved
158158
SPFIX( mov r0, sp )
@@ -167,7 +167,7 @@ ENDPROC(__und_invalid)
167167
ldmia r0, {r3 - r5}
168168
add r7, sp, #S_SP - 4 @ here for interlock avoidance
169169
mov r6, #-1 @ "" "" "" ""
170-
add r2, sp, #(S_FRAME_SIZE + \stack_hole - 4)
170+
add r2, sp, #(S_FRAME_SIZE + 8 + \stack_hole - 4)
171171
SPFIX( addeq r2, r2, #4 )
172172
str r3, [sp, #-4]! @ save the "real" r0 copied
173173
@ from the exception stack
@@ -185,6 +185,11 @@ ENDPROC(__und_invalid)
185185
@
186186
stmia r7, {r2 - r6}
187187

188+
uaccess_save r0
189+
.if \uaccess
190+
uaccess_disable r0
191+
.endif
192+
188193
.if \trace
189194
#ifdef CONFIG_TRACE_IRQFLAGS
190195
bl trace_hardirqs_off
@@ -194,7 +199,7 @@ ENDPROC(__und_invalid)
194199

195200
.align 5
196201
__dabt_svc:
197-
svc_entry
202+
svc_entry uaccess=0
198203
mov r2, sp
199204
dabt_helper
200205
THUMB( ldr r5, [sp, #S_PSR] ) @ potentially updated CPSR
@@ -368,7 +373,7 @@ ENDPROC(__fiq_abt)
368373
#error "sizeof(struct pt_regs) must be a multiple of 8"
369374
#endif
370375

371-
.macro usr_entry, trace=1
376+
.macro usr_entry, trace=1, uaccess=1
372377
UNWIND(.fnstart )
373378
UNWIND(.cantunwind ) @ don't unwind the user space
374379
sub sp, sp, #S_FRAME_SIZE
@@ -400,6 +405,10 @@ ENDPROC(__fiq_abt)
400405
ARM( stmdb r0, {sp, lr}^ )
401406
THUMB( store_user_sp_lr r0, r1, S_SP - S_PC )
402407

408+
.if \uaccess
409+
uaccess_disable ip
410+
.endif
411+
403412
@ Enable the alignment trap while in kernel mode
404413
ATRAP( teq r8, r7)
405414
ATRAP( mcrne p15, 0, r8, c1, c0, 0)
@@ -435,7 +444,7 @@ ENDPROC(__fiq_abt)
435444

436445
.align 5
437446
__dabt_usr:
438-
usr_entry
447+
usr_entry uaccess=0
439448
kuser_cmpxchg_check
440449
mov r2, sp
441450
dabt_helper
@@ -458,7 +467,7 @@ ENDPROC(__irq_usr)
458467

459468
.align 5
460469
__und_usr:
461-
usr_entry
470+
usr_entry uaccess=0
462471

463472
mov r2, r4
464473
mov r3, r5
@@ -484,6 +493,8 @@ __und_usr:
484493
1: ldrt r0, [r4]
485494
ARM_BE8(rev r0, r0) @ little endian instruction
486495

496+
uaccess_disable ip
497+
487498
@ r0 = 32-bit ARM instruction which caused the exception
488499
@ r2 = PC value for the following instruction (:= regs->ARM_pc)
489500
@ r4 = PC value for the faulting instruction
@@ -518,9 +529,10 @@ __und_usr_thumb:
518529
2: ldrht r5, [r4]
519530
ARM_BE8(rev16 r5, r5) @ little endian instruction
520531
cmp r5, #0xe800 @ 32bit instruction if xx != 0
521-
blo __und_usr_fault_16 @ 16bit undefined instruction
532+
blo __und_usr_fault_16_pan @ 16bit undefined instruction
522533
3: ldrht r0, [r2]
523534
ARM_BE8(rev16 r0, r0) @ little endian instruction
535+
uaccess_disable ip
524536
add r2, r2, #2 @ r2 is PC + 2, make it PC + 4
525537
str r2, [sp, #S_PC] @ it's a 2x16bit instr, update
526538
orr r0, r0, r5, lsl #16
@@ -715,6 +727,8 @@ ENDPROC(no_fp)
715727
__und_usr_fault_32:
716728
mov r1, #4
717729
b 1f
730+
__und_usr_fault_16_pan:
731+
uaccess_disable ip
718732
__und_usr_fault_16:
719733
mov r1, #2
720734
1: mov r0, sp

arch/arm/kernel/entry-common.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ ENTRY(vector_swi)
173173
USER( ldr scno, [lr, #-4] ) @ get SWI instruction
174174
#endif
175175

176+
uaccess_disable tbl
177+
176178
adr tbl, sys_call_table @ load syscall table pointer
177179

178180
#if defined(CONFIG_OABI_COMPAT)

arch/arm/kernel/entry-header.S

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@
215215
blne trace_hardirqs_off
216216
#endif
217217
.endif
218+
uaccess_restore
218219

219220
#ifndef CONFIG_THUMB2_KERNEL
220221
@ ARM mode SVC restore
@@ -258,6 +259,7 @@
258259
@ on the stack remains correct).
259260
@
260261
.macro svc_exit_via_fiq
262+
uaccess_restore
261263
#ifndef CONFIG_THUMB2_KERNEL
262264
@ ARM mode restore
263265
mov r0, sp
@@ -287,6 +289,7 @@
287289

288290

289291
.macro restore_user_regs, fast = 0, offset = 0
292+
uaccess_enable r1, isb=0
290293
#ifndef CONFIG_THUMB2_KERNEL
291294
@ ARM mode restore
292295
mov r2, sp

arch/arm/mm/abort-ev4.S

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ ENTRY(v4_early_abort)
1919
mrc p15, 0, r1, c5, c0, 0 @ get FSR
2020
mrc p15, 0, r0, c6, c0, 0 @ get FAR
2121
ldr r3, [r4] @ read aborted ARM instruction
22+
uaccess_disable ip @ disable userspace access
2223
bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
2324
tst r3, #1 << 20 @ L = 1 -> write?
2425
orreq r1, r1, #1 << 11 @ yes.

arch/arm/mm/abort-ev5t.S

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ ENTRY(v5t_early_abort)
2121
mrc p15, 0, r0, c6, c0, 0 @ get FAR
2222
do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3
2323
ldreq r3, [r4] @ read aborted ARM instruction
24+
uaccess_disable ip @ disable user access
2425
bic r1, r1, #1 << 11 @ clear bits 11 of FSR
2526
teq_ldrd tmp=ip, insn=r3 @ insn was LDRD?
2627
beq do_DataAbort @ yes

arch/arm/mm/abort-ev5tj.S

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ ENTRY(v5tj_early_abort)
2424
bne do_DataAbort
2525
do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3
2626
ldreq r3, [r4] @ read aborted ARM instruction
27+
uaccess_disable ip @ disable userspace access
2728
teq_ldrd tmp=ip, insn=r3 @ insn was LDRD?
2829
beq do_DataAbort @ yes
2930
tst r3, #1 << 20 @ L = 0 -> write

arch/arm/mm/abort-ev6.S

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,18 @@ ENTRY(v6_early_abort)
2626
ldr ip, =0x4107b36
2727
mrc p15, 0, r3, c0, c0, 0 @ get processor id
2828
teq ip, r3, lsr #4 @ r0 ARM1136?
29-
bne do_DataAbort
29+
bne 1f
3030
tst r5, #PSR_J_BIT @ Java?
3131
tsteq r5, #PSR_T_BIT @ Thumb?
32-
bne do_DataAbort
32+
bne 1f
3333
bic r1, r1, #1 << 11 @ clear bit 11 of FSR
3434
ldr r3, [r4] @ read aborted ARM instruction
3535
ARM_BE8(rev r3, r3)
3636

3737
teq_ldrd tmp=ip, insn=r3 @ insn was LDRD?
38-
beq do_DataAbort @ yes
38+
beq 1f @ yes
3939
tst r3, #1 << 20 @ L = 0 -> write
4040
orreq r1, r1, #1 << 11 @ yes.
4141
#endif
42+
1: uaccess_disable ip @ disable userspace access
4243
b do_DataAbort

arch/arm/mm/abort-ev7.S

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
ENTRY(v7_early_abort)
1616
mrc p15, 0, r1, c5, c0, 0 @ get FSR
1717
mrc p15, 0, r0, c6, c0, 0 @ get FAR
18+
uaccess_disable ip @ disable userspace access
1819

1920
/*
2021
* V6 code adjusts the returned DFSR.

arch/arm/mm/abort-lv4t.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ ENTRY(v4t_late_abort)
2626
#endif
2727
bne .data_thumb_abort
2828
ldr r8, [r4] @ read arm instruction
29+
uaccess_disable ip @ disable userspace access
2930
tst r8, #1 << 20 @ L = 1 -> write?
3031
orreq r1, r1, #1 << 11 @ yes.
3132
and r7, r8, #15 << 24
@@ -155,6 +156,7 @@ ENTRY(v4t_late_abort)
155156

156157
.data_thumb_abort:
157158
ldrh r8, [r4] @ read instruction
159+
uaccess_disable ip @ disable userspace access
158160
tst r8, #1 << 11 @ L = 1 -> write?
159161
orreq r1, r1, #1 << 8 @ yes
160162
and r7, r8, #15 << 12

0 commit comments

Comments
 (0)