--- a/sys/platform/vkernel64/x86_64/tls.c 2026-10-09 10:21:21.604870044 +0000 +++ b/sys/platform/vkernel64/x86_64/tls.c 2026-10-09 10:21:31.652740788 +0000 @@ -97,6 +97,20 @@ return (EINVAL); /* + * The base is handed verbatim to the host kernel on the return to + * emulated user mode: go_user() passes &curthread->td_savevext + * (== td_tls) to the host's vmspace_ctl(VMSPACE_CTL_RUN), which + * programs it into MSR_FSBASE / MSR_KGSBASE with wrmsr. WRMSR + * raises #GP(0) in kernel mode for a non-canonical FS.base/GS.base + * value (Intel SDM Vol.3 17.17), so accepting one here lets any + * unprivileged user inside the virtual kernel panic the HOST. + * Reject non-canonical bases up front (canonical 48-bit: bits + * 63..47 all zero or all one). + */ + if (((uint64_t)(register_t)info.base + 0x0000800000000000ULL) >> 48) + return (EINVAL); + + /* * For x86_64 we can only adjust FSBASE and GSBASE */ curthread->td_tls.info[i] = info;