|
| 1 | +x86/mm/vsyscall: Consider vsyscall page part of user address space |
| 2 | + |
| 3 | +jira LE-1907 |
| 4 | +cve CVE-2024-26906 |
| 5 | +Rebuild_History Non-Buildable kernel-4.18.0-553.8.1.el8_10 |
| 6 | +commit-author Dave Hansen < [email protected]> |
| 7 | +commit 3ae0ad92f53e0f05cf6ab781230b7902b88f73cd |
| 8 | +Empty-Commit: Cherry-Pick Conflicts during history rebuild. |
| 9 | +Will be included in final tarball splat. Ref for failed cherry-pick at: |
| 10 | +ciq/ciq_backports/kernel-4.18.0-553.8.1.el8_10/3ae0ad92.failed |
| 11 | + |
| 12 | +The vsyscall page is weird. It is in what is traditionally part of |
| 13 | +the kernel address space. But, it has user permissions and we handle |
| 14 | +faults on it like we would on a user page: interrupts on. |
| 15 | + |
| 16 | +Right now, we handle vsyscall emulation in the "bad_area" code, which |
| 17 | +is used for both user-address-space and kernel-address-space faults. |
| 18 | +Move the handling to the user-address-space code *only* and ensure we |
| 19 | +get there by "excluding" the vsyscall page from the kernel address |
| 20 | +space via a check in fault_in_kernel_space(). |
| 21 | + |
| 22 | +Since the fault_in_kernel_space() check is used on 32-bit, also add a |
| 23 | +64-bit check to make it clear we only use this path on 64-bit. Also |
| 24 | +move the unlikely() to be in is_vsyscall_vaddr() itself. |
| 25 | + |
| 26 | +This helps clean up the kernel fault handling path by removing a case |
| 27 | +that can happen in normal[1] operation. (Yeah, yeah, we can argue |
| 28 | +about the vsyscall page being "normal" or not.) This also makes |
| 29 | +sanity checks easier, like the "we never take pkey faults in the |
| 30 | +kernel address space" check in the next patch. |
| 31 | + |
| 32 | + |
| 33 | + |
| 34 | + Cc: Sean Christopherson < [email protected]> |
| 35 | + Cc: Thomas Gleixner < [email protected]> |
| 36 | + Cc: Andy Lutomirski < [email protected]> |
| 37 | + Signed-off-by: Dave Hansen < [email protected]> |
| 38 | + Signed-off-by: Peter Zijlstra (Intel) < [email protected]> |
| 39 | +Link: http://lkml.kernel.org/r/ [email protected] |
| 40 | +(cherry picked from commit 3ae0ad92f53e0f05cf6ab781230b7902b88f73cd) |
| 41 | + Signed-off-by: Jonathan Maple < [email protected]> |
| 42 | + |
| 43 | +# Conflicts: |
| 44 | +# arch/x86/mm/fault.c |
| 45 | +diff --cc arch/x86/mm/fault.c |
| 46 | +index 929bfb03e31a,7e0fa7e24168..000000000000 |
| 47 | +--- a/arch/x86/mm/fault.c |
| 48 | ++++ b/arch/x86/mm/fault.c |
| 49 | +@@@ -855,22 -872,13 +855,32 @@@ __bad_area_nosemaphore(struct pt_regs * |
| 50 | + if (is_errata100(regs, address)) |
| 51 | + return; |
| 52 | + |
| 53 | +++<<<<<<< HEAD |
| 54 | + +#ifdef CONFIG_X86_64 |
| 55 | + + /* |
| 56 | + + * Instruction fetch faults in the vsyscall page might need |
| 57 | + + * emulation. |
| 58 | + + */ |
| 59 | + + if (unlikely((error_code & X86_PF_INSTR) && |
| 60 | + + is_vsyscall_vaddr(address))) { |
| 61 | + + if (emulate_vsyscall(regs, address)) |
| 62 | + + return; |
| 63 | + + } |
| 64 | + +#endif |
| 65 | + + |
| 66 | + + sanitize_error_code(address, &error_code); |
| 67 | + + |
| 68 | + + if (fixup_vdso_exception(regs, X86_TRAP_PF, error_code, address)) |
| 69 | + + return; |
| 70 | +++======= |
| 71 | ++ /* |
| 72 | ++ * To avoid leaking information about the kernel page table |
| 73 | ++ * layout, pretend that user-mode accesses to kernel addresses |
| 74 | ++ * are always protection faults. |
| 75 | ++ */ |
| 76 | ++ if (address >= TASK_SIZE_MAX) |
| 77 | ++ error_code |= X86_PF_PROT; |
| 78 | +++>>>>>>> 3ae0ad92f53e (x86/mm/vsyscall: Consider vsyscall page part of user address space) |
| 79 | + |
| 80 | + if (likely(show_unhandled_signals)) |
| 81 | + show_signal_msg(regs, error_code, address, tsk); |
| 82 | +@@@ -1208,8 -1178,16 +1218,16 @@@ access_error(unsigned long error_code, |
| 83 | + return 0; |
| 84 | + } |
| 85 | + |
| 86 | + -static int fault_in_kernel_space(unsigned long address) |
| 87 | + +bool fault_in_kernel_space(unsigned long address) |
| 88 | + { |
| 89 | ++ /* |
| 90 | ++ * On 64-bit systems, the vsyscall page is at an address above |
| 91 | ++ * TASK_SIZE_MAX, but is not considered part of the kernel |
| 92 | ++ * address space. |
| 93 | ++ */ |
| 94 | ++ if (IS_ENABLED(CONFIG_X86_64) && is_vsyscall_vaddr(address)) |
| 95 | ++ return false; |
| 96 | ++ |
| 97 | + return address >= TASK_SIZE_MAX; |
| 98 | + } |
| 99 | + |
| 100 | +* Unmerged path arch/x86/mm/fault.c |
0 commit comments