Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 17 Jan 2020 19:13:49 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r356840 - head/sys/riscv/riscv
Message-ID:  <202001171913.00HJDnp3034663@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Fri Jan 17 19:13:49 2020
New Revision: 356840
URL: https://svnweb.freebsd.org/changeset/base/356840

Log:
  Check for invalid sstatus values in set_mcontext().
  
  Previously, this check was only in sys_sigreturn() which meant that
  user applications could write invalid values to the register via
  setcontext() or swapcontext().
  
  Reviewed by:	mhorne
  Sponsored by:	DARPA
  Differential Revision:	https://reviews.freebsd.org/D23219

Modified:
  head/sys/riscv/riscv/machdep.c

Modified: head/sys/riscv/riscv/machdep.c
==============================================================================
--- head/sys/riscv/riscv/machdep.c	Fri Jan 17 19:01:59 2020	(r356839)
+++ head/sys/riscv/riscv/machdep.c	Fri Jan 17 19:13:49 2020	(r356840)
@@ -367,6 +367,14 @@ set_mcontext(struct thread *td, mcontext_t *mcp)
 
 	tf = td->td_frame;
 
+	/*
+	 * Make sure the processor mode has not been tampered with and
+	 * interrupts have not been disabled.
+	 * Supervisor interrupts in user mode are always enabled.
+	 */
+	if ((mcp->mc_gpregs.gp_sstatus & SSTATUS_SPP) != 0)
+		return (EINVAL);
+
 	memcpy(tf->tf_t, mcp->mc_gpregs.gp_t, sizeof(tf->tf_t));
 	memcpy(tf->tf_s, mcp->mc_gpregs.gp_s, sizeof(tf->tf_s));
 	memcpy(tf->tf_a, mcp->mc_gpregs.gp_a, sizeof(tf->tf_a));
@@ -523,21 +531,11 @@ struct sigreturn_args {
 int
 sys_sigreturn(struct thread *td, struct sigreturn_args *uap)
 {
-	uint64_t sstatus;
 	ucontext_t uc;
 	int error;
 
 	if (copyin(uap->sigcntxp, &uc, sizeof(uc)))
 		return (EFAULT);
-
-	/*
-	 * Make sure the processor mode has not been tampered with and
-	 * interrupts have not been disabled.
-	 * Supervisor interrupts in user mode are always enabled.
-	 */
-	sstatus = uc.uc_mcontext.mc_gpregs.gp_sstatus;
-	if ((sstatus & SSTATUS_SPP) != 0)
-		return (EINVAL);
 
 	error = set_mcontext(td, &uc.uc_mcontext);
 	if (error != 0)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202001171913.00HJDnp3034663>