diff options
| author | Konstantin Belousov <kib@FreeBSD.org> | 2026-03-15 07:17:24 +0000 |
|---|---|---|
| committer | Konstantin Belousov <kib@FreeBSD.org> | 2026-03-20 21:05:15 +0000 |
| commit | 8892176c86db18bd175cc00a2d52dff080babec1 (patch) | |
| tree | d286b7107327a3c1969268643ec352b6dd13bc44 /sys | |
| parent | e18449fbe2731399862e82e61fffaadd6739642c (diff) | |
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/amd64/amd64/exec_machdep.c | 19 | ||||
| -rw-r--r-- | sys/amd64/ia32/ia32_signal.c | 28 |
2 files changed, 47 insertions, 0 deletions
diff --git a/sys/amd64/amd64/exec_machdep.c b/sys/amd64/amd64/exec_machdep.c index b5eda6f83d46..7d567c561c52 100644 --- a/sys/amd64/amd64/exec_machdep.c +++ b/sys/amd64/amd64/exec_machdep.c @@ -95,6 +95,15 @@ _Static_assert(sizeof(ucontext_t) == 880, "ucontext_t size incorrect"); _Static_assert(sizeof(siginfo_t) == 80, "siginfo_t size incorrect"); /* + * Check that the value r is 16bit, i.e. fits into a segment register. + */ +static bool +is_seg_val(register_t r) +{ + return ((uint64_t)r <= 0xffff); +} + +/* * Send an interrupt to process. * * Stack is set up to allow sigcode stored at top to call routine, @@ -262,6 +271,14 @@ sys_sigreturn(struct thread *td, struct sigreturn_args *uap) return (EINVAL); } + if (!is_seg_val(ucp->uc_mcontext.mc_ss) || + !is_seg_val(ucp->uc_mcontext.mc_cs)) { + uprintf("pid %d (%s): sigreturn cs = %#lx ss = %#lx\n", + p->p_pid, td->td_name, ucp->uc_mcontext.mc_cs, + ucp->uc_mcontext.mc_ss); + return (EINVAL); + } + /* * Don't allow users to load a valid privileged %cs. Let the * hardware check for invalid selectors, excess privilege in @@ -659,6 +676,8 @@ set_mcontext(struct thread *td, mcontext_t *mcp) if (mcp->mc_len != sizeof(*mcp) || (mcp->mc_flags & ~_MC_FLAG_MASK) != 0) return (EINVAL); + if (!is_seg_val(mcp->mc_ss) || !is_seg_val(mcp->mc_cs)) + return (EINVAL); rflags = (mcp->mc_rflags & PSL_USERCHANGE) | (tp->tf_rflags & ~PSL_USERCHANGE); if (mcp->mc_flags & _MC_HASFPXSTATE) { diff --git a/sys/amd64/ia32/ia32_signal.c b/sys/amd64/ia32/ia32_signal.c index 54e170450dba..3b26244932b4 100644 --- a/sys/amd64/ia32/ia32_signal.c +++ b/sys/amd64/ia32/ia32_signal.c @@ -88,6 +88,15 @@ extern char _binary_elf_vdso32_so_1_size; static void freebsd4_ia32_sendsig(sig_t, ksiginfo_t *, sigset_t *); #endif +/* + * Check that the value r is 16bit, i.e. fits into a segment register. + */ +static bool +is_seg_val(uint32_t r) +{ + return (r <= 0xffff); +} + static void ia32_get_fpcontext(struct thread *td, struct ia32_mcontext *mcp, char **xfpusave, size_t *xfpusave_len) @@ -205,6 +214,8 @@ ia32_set_mcontext(struct thread *td, struct ia32_mcontext *mcp) tp = td->td_frame; if (mcp->mc_len != sizeof(*mcp)) return (EINVAL); + if (!is_seg_val(mcp->mc_ss) || !is_seg_val(mcp->mc_cs)) + return (EINVAL); rflags = (mcp->mc_eflags & PSL_USERCHANGE) | (tp->tf_rflags & ~PSL_USERCHANGE); if (mcp->mc_flags & _MC_IA32_HASFPXSTATE) { @@ -707,6 +718,8 @@ ofreebsd32_sigreturn(struct thread *td, struct ofreebsd32_sigreturn_args *uap) if (!EFL_SECURE(eflags, regs->tf_rflags)) { return (EINVAL); } + if (!is_seg_val(scp->sc_ss) || !is_seg_val(scp->sc_cs)) + return (EINVAL); if (!CS_SECURE(scp->sc_cs)) { ksiginfo_init_trap(&ksi); ksi.ksi_signo = SIGBUS; @@ -772,6 +785,13 @@ freebsd4_freebsd32_sigreturn(struct thread *td, return (EINVAL); } + if (!is_seg_val(ucp->uc_mcontext.mc_ss) || + !is_seg_val(ucp->uc_mcontext.mc_cs)) { + uprintf("pid %d (%s): sigreturn cs = %#x ss = %#x\n", + td->td_proc->p_pid, td->td_name, ucp->uc_mcontext.mc_cs, + ucp->uc_mcontext.mc_ss); + return (EINVAL); + } /* * Don't allow users to load a valid privileged %cs. Let the * hardware check for invalid selectors, excess privilege in @@ -841,6 +861,14 @@ freebsd32_sigreturn(struct thread *td, struct freebsd32_sigreturn_args *uap) return (EINVAL); } + if (!is_seg_val(ucp->uc_mcontext.mc_ss) || + !is_seg_val(ucp->uc_mcontext.mc_cs)) { + uprintf("pid %d (%s): sigreturn cs = %#x ss = %#x\n", + td->td_proc->p_pid, td->td_name, ucp->uc_mcontext.mc_cs, + ucp->uc_mcontext.mc_ss); + return (EINVAL); + } + /* * Don't allow users to load a valid privileged %cs. Let the * hardware check for invalid selectors, excess privilege in |
