aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2026-04-25 09:49:08 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2026-04-27 03:23:19 +0000
commitbd8edba0792b71be3f8ed5dea9c22287e95c986a (patch)
treedd0c4e40bf4da138adadccce7f03142f89688e6c
parent912f9dfca451e359dda7cdf45539b7c19764f54d (diff)
amd64 ia32_syscall(): only allow for ILP32 processes
64bit processes can issue INT $0x80 instruction, and get the syscall dispatched through ia32_syscall(). This works because syscall argument fetch and result return are selected from the process sysent. But, ia32_syscall() does not verify some conditions and does not perform some actions which are considered unnecessary because the caller is supposed to only access lower 4G. The INT syscall path breaks this assumption. We never supported such hack, so disable it. Send the offending thread SIGBUS as if #GP was issued by hardware due to IDT vector 0x80 having not numerically high enough DPL value. Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D56630
-rw-r--r--sys/amd64/ia32/ia32_syscall.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/sys/amd64/ia32/ia32_syscall.c b/sys/amd64/ia32/ia32_syscall.c
index 85e3d8f8e920..edafb753faa0 100644
--- a/sys/amd64/ia32/ia32_syscall.c
+++ b/sys/amd64/ia32/ia32_syscall.c
@@ -218,6 +218,15 @@ ia32_syscall(struct trapframe *frame)
orig_tf_rflags = frame->tf_rflags;
td = curthread;
td->td_frame = frame;
+ if (__predict_false(SV_PROC_FLAG(td->td_proc, SV_ILP32) == 0)) {
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_addr = (void *)frame->tf_rip;
+ trapsignal(td, &ksi);
+ userret(td, td->td_frame);
+ return;
+ }
syscallenter(td);