git: dcc5adb27e3b - main - amd64: strictly enforce the caller's mode for FRED 64bit syscall handler in C

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Wed, 28 Oct 2026 13:46:57 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=dcc5adb27e3b00f003c2256a9e9aa2fcc20c4d32

commit dcc5adb27e3b00f003c2256a9e9aa2fcc20c4d32
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-10-28 00:45:33 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-10-28 13:46:36 +0000

    amd64: strictly enforce the caller's mode for FRED 64bit syscall handler in C
    
    For FRED SYSCALL calls, check that the LM bit is set.
    
    Note that this handler is redundant for 64bit mode since syscalls
    are handled by the asm fast path. Intel CPUs raise #UD for SYSCALL
    in the compatibility mode, and for AMD we set up the MSR_CSTAR to
    fast_syscall32 for IDT case, which is nop. So practically it should only
    matter if AMD CPUs with FRED enabled allow SYSCALL from compatibility
    mode.
    
    Reported and reviewed by:       markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
---
 sys/amd64/amd64/trap.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 62d8d3b06c90..08485c852cac 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -1674,7 +1674,8 @@ trap_fred_u(struct trapframe_fred *frame)
 	case TF_FRED_EVINFO2_TYPE_SYSCALL:
 		/* Excessive */
 		enable_intr();
-		if (vec == TF_FRED_EVINFO2_VEC_SYSCALL) {
+		if (vec == TF_FRED_EVINFO2_VEC_SYSCALL &&
+		    (frame->tf_idt.tf_fred_evinfo2 & TF_FRED_EVINFO2_LM) != 0) {
 			frame->tf_idt.tf_err = fred_inst_len(frame);
 			td->td_frame = &frame->tf_idt;
 			amd64_syscall(td, (frame->tf_idt.tf_rflags & PSL_T) !=