Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'uaccess' into fixes

+123 -89
+1 -74
arch/arm/include/asm/assembler.h
··· 18 18 #endif 19 19 20 20 #include <asm/ptrace.h> 21 - #include <asm/domain.h> 22 21 #include <asm/opcodes-virt.h> 23 22 #include <asm/asm-offsets.h> 24 23 #include <asm/page.h> 25 24 #include <asm/thread_info.h> 25 + #include <asm/uaccess-asm.h> 26 26 27 27 #define IOMEM(x) (x) 28 28 ··· 444 444 \name: 445 445 .asciz "\string" 446 446 .size \name , . - \name 447 - .endm 448 - 449 - .macro csdb 450 - #ifdef CONFIG_THUMB2_KERNEL 451 - .inst.w 0xf3af8014 452 - #else 453 - .inst 0xe320f014 454 - #endif 455 - .endm 456 - 457 - .macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req 458 - #ifndef CONFIG_CPU_USE_DOMAINS 459 - adds \tmp, \addr, #\size - 1 460 - sbcscc \tmp, \tmp, \limit 461 - bcs \bad 462 - #ifdef CONFIG_CPU_SPECTRE 463 - movcs \addr, #0 464 - csdb 465 - #endif 466 - #endif 467 - .endm 468 - 469 - .macro uaccess_mask_range_ptr, addr:req, size:req, limit:req, tmp:req 470 - #ifdef CONFIG_CPU_SPECTRE 471 - sub \tmp, \limit, #1 472 - subs \tmp, \tmp, \addr @ tmp = limit - 1 - addr 473 - addhs \tmp, \tmp, #1 @ if (tmp >= 0) { 474 - subshs \tmp, \tmp, \size @ tmp = limit - (addr + size) } 475 - movlo \addr, #0 @ if (tmp < 0) addr = NULL 476 - csdb 477 - #endif 478 - .endm 479 - 480 - .macro uaccess_disable, tmp, isb=1 481 - #ifdef CONFIG_CPU_SW_DOMAIN_PAN 482 - /* 483 - * Whenever we re-enter userspace, the domains should always be 484 - * set appropriately. 485 - */ 486 - mov \tmp, #DACR_UACCESS_DISABLE 487 - mcr p15, 0, \tmp, c3, c0, 0 @ Set domain register 488 - .if \isb 489 - instr_sync 490 - .endif 491 - #endif 492 - .endm 493 - 494 - .macro uaccess_enable, tmp, isb=1 495 - #ifdef CONFIG_CPU_SW_DOMAIN_PAN 496 - /* 497 - * Whenever we re-enter userspace, the domains should always be 498 - * set appropriately. 499 - */ 500 - mov \tmp, #DACR_UACCESS_ENABLE 501 - mcr p15, 0, \tmp, c3, c0, 0 502 - .if \isb 503 - instr_sync 504 - .endif 505 - #endif 506 - .endm 507 - 508 - .macro uaccess_save, tmp 509 - #ifdef CONFIG_CPU_SW_DOMAIN_PAN 510 - mrc p15, 0, \tmp, c3, c0, 0 511 - str \tmp, [sp, #SVC_DACR] 512 - #endif 513 - .endm 514 - 515 - .macro uaccess_restore 516 - #ifdef CONFIG_CPU_SW_DOMAIN_PAN 517 - ldr r0, [sp, #SVC_DACR] 518 - mcr p15, 0, r0, c3, c0, 0 519 - #endif 520 447 .endm 521 448 522 449 .irp c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo
+117
arch/arm/include/asm/uaccess-asm.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + 3 + #ifndef __ASM_UACCESS_ASM_H__ 4 + #define __ASM_UACCESS_ASM_H__ 5 + 6 + #include <asm/asm-offsets.h> 7 + #include <asm/domain.h> 8 + #include <asm/memory.h> 9 + #include <asm/thread_info.h> 10 + 11 + .macro csdb 12 + #ifdef CONFIG_THUMB2_KERNEL 13 + .inst.w 0xf3af8014 14 + #else 15 + .inst 0xe320f014 16 + #endif 17 + .endm 18 + 19 + .macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req 20 + #ifndef CONFIG_CPU_USE_DOMAINS 21 + adds \tmp, \addr, #\size - 1 22 + sbcscc \tmp, \tmp, \limit 23 + bcs \bad 24 + #ifdef CONFIG_CPU_SPECTRE 25 + movcs \addr, #0 26 + csdb 27 + #endif 28 + #endif 29 + .endm 30 + 31 + .macro uaccess_mask_range_ptr, addr:req, size:req, limit:req, tmp:req 32 + #ifdef CONFIG_CPU_SPECTRE 33 + sub \tmp, \limit, #1 34 + subs \tmp, \tmp, \addr @ tmp = limit - 1 - addr 35 + addhs \tmp, \tmp, #1 @ if (tmp >= 0) { 36 + subshs \tmp, \tmp, \size @ tmp = limit - (addr + size) } 37 + movlo \addr, #0 @ if (tmp < 0) addr = NULL 38 + csdb 39 + #endif 40 + .endm 41 + 42 + .macro uaccess_disable, tmp, isb=1 43 + #ifdef CONFIG_CPU_SW_DOMAIN_PAN 44 + /* 45 + * Whenever we re-enter userspace, the domains should always be 46 + * set appropriately. 47 + */ 48 + mov \tmp, #DACR_UACCESS_DISABLE 49 + mcr p15, 0, \tmp, c3, c0, 0 @ Set domain register 50 + .if \isb 51 + instr_sync 52 + .endif 53 + #endif 54 + .endm 55 + 56 + .macro uaccess_enable, tmp, isb=1 57 + #ifdef CONFIG_CPU_SW_DOMAIN_PAN 58 + /* 59 + * Whenever we re-enter userspace, the domains should always be 60 + * set appropriately. 61 + */ 62 + mov \tmp, #DACR_UACCESS_ENABLE 63 + mcr p15, 0, \tmp, c3, c0, 0 64 + .if \isb 65 + instr_sync 66 + .endif 67 + #endif 68 + .endm 69 + 70 + #if defined(CONFIG_CPU_SW_DOMAIN_PAN) || defined(CONFIG_CPU_USE_DOMAINS) 71 + #define DACR(x...) x 72 + #else 73 + #define DACR(x...) 74 + #endif 75 + 76 + /* 77 + * Save the address limit on entry to a privileged exception. 78 + * 79 + * If we are using the DACR for kernel access by the user accessors 80 + * (CONFIG_CPU_USE_DOMAINS=y), always reset the DACR kernel domain 81 + * back to client mode, whether or not \disable is set. 82 + * 83 + * If we are using SW PAN, set the DACR user domain to no access 84 + * if \disable is set. 85 + */ 86 + .macro uaccess_entry, tsk, tmp0, tmp1, tmp2, disable 87 + ldr \tmp1, [\tsk, #TI_ADDR_LIMIT] 88 + mov \tmp2, #TASK_SIZE 89 + str \tmp2, [\tsk, #TI_ADDR_LIMIT] 90 + DACR( mrc p15, 0, \tmp0, c3, c0, 0) 91 + DACR( str \tmp0, [sp, #SVC_DACR]) 92 + str \tmp1, [sp, #SVC_ADDR_LIMIT] 93 + .if \disable && IS_ENABLED(CONFIG_CPU_SW_DOMAIN_PAN) 94 + /* kernel=client, user=no access */ 95 + mov \tmp2, #DACR_UACCESS_DISABLE 96 + mcr p15, 0, \tmp2, c3, c0, 0 97 + instr_sync 98 + .elseif IS_ENABLED(CONFIG_CPU_USE_DOMAINS) 99 + /* kernel=client */ 100 + bic \tmp2, \tmp0, #domain_mask(DOMAIN_KERNEL) 101 + orr \tmp2, \tmp2, #domain_val(DOMAIN_KERNEL, DOMAIN_CLIENT) 102 + mcr p15, 0, \tmp2, c3, c0, 0 103 + instr_sync 104 + .endif 105 + .endm 106 + 107 + /* Restore the user access state previously saved by uaccess_entry */ 108 + .macro uaccess_exit, tsk, tmp0, tmp1 109 + ldr \tmp1, [sp, #SVC_ADDR_LIMIT] 110 + DACR( ldr \tmp0, [sp, #SVC_DACR]) 111 + str \tmp1, [\tsk, #TI_ADDR_LIMIT] 112 + DACR( mcr p15, 0, \tmp0, c3, c0, 0) 113 + .endm 114 + 115 + #undef DACR 116 + 117 + #endif /* __ASM_UACCESS_ASM_H__ */
+2 -9
arch/arm/kernel/entry-armv.S
··· 27 27 #include <asm/unistd.h> 28 28 #include <asm/tls.h> 29 29 #include <asm/system_info.h> 30 + #include <asm/uaccess-asm.h> 30 31 31 32 #include "entry-header.S" 32 33 #include <asm/entry-macro-multi.S> ··· 180 179 stmia r7, {r2 - r6} 181 180 182 181 get_thread_info tsk 183 - ldr r0, [tsk, #TI_ADDR_LIMIT] 184 - mov r1, #TASK_SIZE 185 - str r1, [tsk, #TI_ADDR_LIMIT] 186 - str r0, [sp, #SVC_ADDR_LIMIT] 187 - 188 - uaccess_save r0 189 - .if \uaccess 190 - uaccess_disable r0 191 - .endif 182 + uaccess_entry tsk, r0, r1, r2, \uaccess 192 183 193 184 .if \trace 194 185 #ifdef CONFIG_TRACE_IRQFLAGS
+3 -6
arch/arm/kernel/entry-header.S
··· 6 6 #include <asm/asm-offsets.h> 7 7 #include <asm/errno.h> 8 8 #include <asm/thread_info.h> 9 + #include <asm/uaccess-asm.h> 9 10 #include <asm/v7m.h> 10 11 11 12 @ Bad Abort numbers ··· 218 217 blne trace_hardirqs_off 219 218 #endif 220 219 .endif 221 - ldr r1, [sp, #SVC_ADDR_LIMIT] 222 - uaccess_restore 223 - str r1, [tsk, #TI_ADDR_LIMIT] 220 + uaccess_exit tsk, r0, r1 224 221 225 222 #ifndef CONFIG_THUMB2_KERNEL 226 223 @ ARM mode SVC restore ··· 262 263 @ on the stack remains correct). 263 264 @ 264 265 .macro svc_exit_via_fiq 265 - ldr r1, [sp, #SVC_ADDR_LIMIT] 266 - uaccess_restore 267 - str r1, [tsk, #TI_ADDR_LIMIT] 266 + uaccess_exit tsk, r0, r1 268 267 #ifndef CONFIG_THUMB2_KERNEL 269 268 @ ARM mode restore 270 269 mov r0, sp