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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rmk/linux

Pull ARM updates from Russell King:

- disable jump label and high PTE for PREEMPT RT kernels

- fix input operand modification in load_unaligned_zeropad()

- fix hash_name() / fault path induced warnings

- fix branch predictor hardening

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rmk/linux:
ARM: fix branch predictor hardening
ARM: fix hash_name() fault
ARM: allow __do_kernel_fault() to report execution of memory faults
ARM: group is_permission_fault() with is_translation_fault()
ARM: 9464/1: fix input-only operand modification in load_unaligned_zeropad()
ARM: 9461/1: Disable HIGHPTE on PREEMPT_RT kernels
ARM: 9459/1: Disable jump-label on PREEMPT_RT

+87 -33
+2 -2
arch/arm/Kconfig
··· 82 82 select HAS_IOPORT 83 83 select HAVE_ARCH_AUDITSYSCALL if AEABI && !OABI_COMPAT 84 84 select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6 85 - select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU 85 + select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU && (!PREEMPT_RT || !SMP) 86 86 select HAVE_ARCH_KFENCE if MMU && !XIP_KERNEL 87 87 select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU 88 88 select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL ··· 1213 1213 1214 1214 config HIGHPTE 1215 1215 bool "Allocate 2nd-level pagetables from highmem" if EXPERT 1216 - depends on HIGHMEM 1216 + depends on HIGHMEM && !PREEMPT_RT 1217 1217 default y 1218 1218 help 1219 1219 The VM uses one page of physical memory for each page table.
+5 -5
arch/arm/include/asm/word-at-a-time.h
··· 67 67 */ 68 68 static inline unsigned long load_unaligned_zeropad(const void *addr) 69 69 { 70 - unsigned long ret, offset; 70 + unsigned long ret, tmp; 71 71 72 72 /* Load word from unaligned pointer addr */ 73 73 asm( ··· 75 75 "2:\n" 76 76 " .pushsection .text.fixup,\"ax\"\n" 77 77 " .align 2\n" 78 - "3: and %1, %2, #0x3\n" 79 - " bic %2, %2, #0x3\n" 80 - " ldr %0, [%2]\n" 78 + "3: bic %1, %2, #0x3\n" 79 + " ldr %0, [%1]\n" 80 + " and %1, %2, #0x3\n" 81 81 " lsl %1, %1, #0x3\n" 82 82 #ifndef __ARMEB__ 83 83 " lsr %0, %0, %1\n" ··· 90 90 " .align 3\n" 91 91 " .long 1b, 3b\n" 92 92 " .popsection" 93 - : "=&r" (ret), "=&r" (offset) 93 + : "=&r" (ret), "=&r" (tmp) 94 94 : "r" (addr), "Qo" (*(unsigned long *)addr)); 95 95 96 96 return ret;
+5 -1
arch/arm/mm/alignment.c
··· 19 19 #include <linux/init.h> 20 20 #include <linux/sched/signal.h> 21 21 #include <linux/uaccess.h> 22 + #include <linux/unaligned.h> 22 23 23 24 #include <asm/cp15.h> 24 25 #include <asm/system_info.h> 25 - #include <linux/unaligned.h> 26 + #include <asm/system_misc.h> 26 27 #include <asm/opcodes.h> 27 28 28 29 #include "fault.h" ··· 809 808 int isize = 4; 810 809 int thumb2_32b = 0; 811 810 int fault; 811 + 812 + if (addr >= TASK_SIZE && user_mode(regs)) 813 + harden_branch_predictor(); 812 814 813 815 if (interrupts_enabled(regs)) 814 816 local_irq_enable();
+75 -25
arch/arm/mm/fault.c
··· 128 128 return false; 129 129 } 130 130 131 + static inline bool is_permission_fault(unsigned int fsr) 132 + { 133 + int fs = fsr_fs(fsr); 134 + #ifdef CONFIG_ARM_LPAE 135 + if ((fs & FS_MMU_NOLL_MASK) == FS_PERM_NOLL) 136 + return true; 137 + #else 138 + if (fs == FS_L1_PERM || fs == FS_L2_PERM) 139 + return true; 140 + #endif 141 + return false; 142 + } 143 + 131 144 static void die_kernel_fault(const char *msg, struct mm_struct *mm, 132 145 unsigned long addr, unsigned int fsr, 133 146 struct pt_regs *regs) ··· 175 162 */ 176 163 if (addr < PAGE_SIZE) { 177 164 msg = "NULL pointer dereference"; 165 + } else if (is_permission_fault(fsr) && fsr & FSR_LNX_PF) { 166 + msg = "execution of memory"; 178 167 } else { 179 168 if (is_translation_fault(fsr) && 180 169 kfence_handle_page_fault(addr, is_write_fault(fsr), regs)) ··· 197 182 int code, struct pt_regs *regs) 198 183 { 199 184 struct task_struct *tsk = current; 200 - 201 - if (addr > TASK_SIZE) 202 - harden_branch_predictor(); 203 185 204 186 #ifdef CONFIG_DEBUG_USER 205 187 if (((user_debug & UDBG_SEGV) && (sig == SIGSEGV)) || ··· 237 225 } 238 226 239 227 #ifdef CONFIG_MMU 240 - static inline bool is_permission_fault(unsigned int fsr) 241 - { 242 - int fs = fsr_fs(fsr); 243 - #ifdef CONFIG_ARM_LPAE 244 - if ((fs & FS_MMU_NOLL_MASK) == FS_PERM_NOLL) 245 - return true; 246 - #else 247 - if (fs == FS_L1_PERM || fs == FS_L2_PERM) 248 - return true; 249 - #endif 250 - return false; 251 - } 252 - 253 228 #ifdef CONFIG_CPU_TTBR0_PAN 254 229 static inline bool ttbr0_usermode_access_allowed(struct pt_regs *regs) 255 230 { ··· 259 260 #endif 260 261 261 262 static int __kprobes 263 + do_kernel_address_page_fault(struct mm_struct *mm, unsigned long addr, 264 + unsigned int fsr, struct pt_regs *regs) 265 + { 266 + if (user_mode(regs)) { 267 + /* 268 + * Fault from user mode for a kernel space address. User mode 269 + * should not be faulting in kernel space, which includes the 270 + * vector/khelper page. Handle the branch predictor hardening 271 + * while interrupts are still disabled, then send a SIGSEGV. 272 + */ 273 + harden_branch_predictor(); 274 + __do_user_fault(addr, fsr, SIGSEGV, SEGV_MAPERR, regs); 275 + } else { 276 + /* 277 + * Fault from kernel mode. Enable interrupts if they were 278 + * enabled in the parent context. Section (upper page table) 279 + * translation faults are handled via do_translation_fault(), 280 + * so we will only get here for a non-present kernel space 281 + * PTE or PTE permission fault. This may happen in exceptional 282 + * circumstances and need the fixup tables to be walked. 283 + */ 284 + if (interrupts_enabled(regs)) 285 + local_irq_enable(); 286 + 287 + __do_kernel_fault(mm, addr, fsr, regs); 288 + } 289 + 290 + return 0; 291 + } 292 + 293 + static int __kprobes 262 294 do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) 263 295 { 264 296 struct mm_struct *mm = current->mm; ··· 302 272 if (kprobe_page_fault(regs, fsr)) 303 273 return 0; 304 274 275 + /* 276 + * Handle kernel addresses faults separately, which avoids touching 277 + * the mmap lock from contexts that are not able to sleep. 278 + */ 279 + if (addr >= TASK_SIZE) 280 + return do_kernel_address_page_fault(mm, addr, fsr, regs); 305 281 306 282 /* Enable interrupts if they were enabled in the parent context. */ 307 283 if (interrupts_enabled(regs)) ··· 484 448 * We enter here because the first level page table doesn't contain 485 449 * a valid entry for the address. 486 450 * 487 - * If the address is in kernel space (>= TASK_SIZE), then we are 488 - * probably faulting in the vmalloc() area. 451 + * If this is a user address (addr < TASK_SIZE), we handle this as a 452 + * normal page fault. This leaves the remainder of the function to handle 453 + * kernel address translation faults. 489 454 * 490 - * If the init_task's first level page tables contains the relevant 491 - * entry, we copy the it to this task. If not, we send the process 492 - * a signal, fixup the exception, or oops the kernel. 455 + * Since user mode is not permitted to access kernel addresses, pass these 456 + * directly to do_kernel_address_page_fault() to handle. 493 457 * 494 - * NOTE! We MUST NOT take any locks for this case. We may be in an 495 - * interrupt or a critical region, and should only copy the information 496 - * from the master page table, nothing more. 458 + * Otherwise, we're probably faulting in the vmalloc() area, so try to fix 459 + * that up. Note that we must not take any locks or enable interrupts in 460 + * this case. 461 + * 462 + * If vmalloc() fixup fails, that means the non-leaf page tables did not 463 + * contain an entry for this address, so handle this via 464 + * do_kernel_address_page_fault(). 497 465 */ 498 466 #ifdef CONFIG_MMU 499 467 static int __kprobes ··· 563 523 return 0; 564 524 565 525 bad_area: 566 - do_bad_area(addr, fsr, regs); 526 + do_kernel_address_page_fault(current->mm, addr, fsr, regs); 527 + 567 528 return 0; 568 529 } 569 530 #else /* CONFIG_MMU */ ··· 584 543 static int 585 544 do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) 586 545 { 546 + /* 547 + * If this is a kernel address, but from user mode, then userspace 548 + * is trying bad stuff. Invoke the branch predictor handling. 549 + * Interrupts are disabled here. 550 + */ 551 + if (addr >= TASK_SIZE && user_mode(regs)) 552 + harden_branch_predictor(); 553 + 587 554 do_bad_area(addr, fsr, regs); 555 + 588 556 return 0; 589 557 } 590 558 #endif /* CONFIG_ARM_LPAE */