Page MenuHomeFreeBSD

D55861.diff
No OneTemporary

D55861.diff

diff --git a/sys/amd64/amd64/exec_machdep.c b/sys/amd64/amd64/exec_machdep.c
--- a/sys/amd64/amd64/exec_machdep.c
+++ b/sys/amd64/amd64/exec_machdep.c
@@ -94,6 +94,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.
*
@@ -262,6 +271,14 @@
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 @@
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
--- a/sys/amd64/ia32/ia32_signal.c
+++ b/sys/amd64/ia32/ia32_signal.c
@@ -88,6 +88,15 @@
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 @@
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 @@
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 @@
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 @@
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

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 2, 7:26 AM (6 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30713818
Default Alt Text
D55861.diff (3 KB)

Event Timeline