summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2025-10-04 10:25:22 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2025-10-04 10:25:22 -0700
commit7c738cb4ca678e70c4583ab35587f30bfae823e5 (patch)
tree38b76c0526f586ce22f2758ccb22bce374367943
parentbe786eba12c87dc04ad8eac408dc17369c04ad47 (diff)
parent3da01ffe1aeaa0d427ab5235ba735226670a80d9 (diff)
Merge tag 'x86_entry_for_6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 entry updates from Dave Hansen: "A pair of x86/entry updates. The FRED one adjusts the kernel to the latest spec. The spec change prevents attackers from abusing kernel entry points. The second one came about because of the LASS work[1]. It moves the vsyscall emulation code away from depending on X86_PF_INSTR which is not available on some CPUs. Those CPUs are pretty obscure these days, but this still seems like the right thing to do. It also makes this code consistent with some things that the LASS code is going to do. - Use RIP instead of X86_PF_INSTR for vsyscall emulation - Remove ENDBR64 from FRED entry points" Link: https://lore.kernel.org/lkml/20250620135325.3300848-1-kirill.shutemov@linux.intel.com/ [1] * tag 'x86_entry_for_6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/fred: Remove ENDBR64 from FRED entry points x86/vsyscall: Do not require X86_PF_INSTR to emulate vsyscall
-rw-r--r--arch/x86/entry/entry_64_fred.S2
-rw-r--r--arch/x86/entry/vsyscall/vsyscall_64.c17
2 files changed, 15 insertions, 4 deletions
diff --git a/arch/x86/entry/entry_64_fred.S b/arch/x86/entry/entry_64_fred.S
index 29c5c32c16c3..907bd233c6c1 100644
--- a/arch/x86/entry/entry_64_fred.S
+++ b/arch/x86/entry/entry_64_fred.S
@@ -16,7 +16,7 @@
.macro FRED_ENTER
UNWIND_HINT_END_OF_STACK
- ENDBR
+ ANNOTATE_NOENDBR
PUSH_AND_CLEAR_REGS
movq %rsp, %rdi /* %rdi -> pt_regs */
.endm
diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c
index c9103a6fa06e..6e6c0a740837 100644
--- a/arch/x86/entry/vsyscall/vsyscall_64.c
+++ b/arch/x86/entry/vsyscall/vsyscall_64.c
@@ -124,7 +124,12 @@ bool emulate_vsyscall(unsigned long error_code,
if ((error_code & (X86_PF_WRITE | X86_PF_USER)) != X86_PF_USER)
return false;
- if (!(error_code & X86_PF_INSTR)) {
+ /*
+ * Assume that faults at regs->ip are because of an
+ * instruction fetch. Return early and avoid
+ * emulation for faults during data accesses:
+ */
+ if (address != regs->ip) {
/* Failed vsyscall read */
if (vsyscall_mode == EMULATE)
return false;
@@ -137,12 +142,18 @@ bool emulate_vsyscall(unsigned long error_code,
}
/*
+ * X86_PF_INSTR is only set when NX is supported. When
+ * available, use it to double-check that the emulation code
+ * is only being used for instruction fetches:
+ */
+ if (cpu_feature_enabled(X86_FEATURE_NX))
+ WARN_ON_ONCE(!(error_code & X86_PF_INSTR));
+
+ /*
* No point in checking CS -- the only way to get here is a user mode
* trap to a high address, which means that we're in 64-bit user code.
*/
- WARN_ON_ONCE(address != regs->ip);
-
if (vsyscall_mode == NONE) {
warn_bad_vsyscall(KERN_INFO, regs,
"vsyscall attempted with vsyscall=none");