From owner-svn-src-stable@freebsd.org Tue Nov 28 11:06:19 2017 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 7A6E1E5265C; Tue, 28 Nov 2017 11:06:19 +0000 (UTC) (envelope-from andrew@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 35DFE806A9; Tue, 28 Nov 2017 11:06:19 +0000 (UTC) (envelope-from andrew@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id vASB6I1t025049; Tue, 28 Nov 2017 11:06:18 GMT (envelope-from andrew@FreeBSD.org) Received: (from andrew@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id vASB6I5F025046; Tue, 28 Nov 2017 11:06:18 GMT (envelope-from andrew@FreeBSD.org) Message-Id: <201711281106.vASB6I5F025046@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: andrew set sender to andrew@FreeBSD.org using -f From: Andrew Turner Date: Tue, 28 Nov 2017 11:06:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r326313 - in stable/11/sys: arm/arm arm64/arm64 arm64/include X-SVN-Group: stable-11 X-SVN-Commit-Author: andrew X-SVN-Commit-Paths: in stable/11/sys: arm/arm arm64/arm64 arm64/include X-SVN-Commit-Revision: 326313 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 28 Nov 2017 11:06:19 -0000 Author: andrew Date: Tue Nov 28 11:06:17 2017 New Revision: 326313 URL: https://svnweb.freebsd.org/changeset/base/326313 Log: MFC r326137: Ensure we check the program state set in the trap frame on arm and arm64. This value may be set by userspace so we need to check it before using it. If this is not done correctly on exception return the kernel may continue in kernel mode with all registers set to a userspace controlled value. Fix this by moving the check into set_mcontext, and also add the missing sanitisation from the arm64 set_regs. Discussed with: security-officer@ Sponsored by: DARPA, AFRL Modified: stable/11/sys/arm/arm/machdep.c stable/11/sys/arm64/arm64/machdep.c stable/11/sys/arm64/include/armreg.h Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/arm/arm/machdep.c ============================================================================== --- stable/11/sys/arm/arm/machdep.c Tue Nov 28 11:04:47 2017 (r326312) +++ stable/11/sys/arm/arm/machdep.c Tue Nov 28 11:06:17 2017 (r326313) @@ -507,7 +507,17 @@ set_mcontext(struct thread *td, mcontext_t *mcp) mcontext_vfp_t mc_vfp, *vfp; struct trapframe *tf = td->td_frame; const __greg_t *gr = mcp->__gregs; + int spsr; + /* + * Make sure the processor mode has not been tampered with and + * interrupts have not been disabled. + */ + spsr = gr[_REG_CPSR]; + if ((spsr & PSR_MODE) != PSR_USR32_MODE || + (spsr & (PSR_I | PSR_F)) != 0) + return (EINVAL); + #ifdef WITNESS if (mcp->mc_vfp_size != 0 && mcp->mc_vfp_size != sizeof(mc_vfp)) { printf("%s: %s: Malformed mc_vfp_size: %d (0x%08X)\n", @@ -666,22 +676,16 @@ sys_sigreturn(td, uap) } */ *uap; { ucontext_t uc; - int spsr; + int error; if (uap == NULL) return (EFAULT); 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. - */ - spsr = uc.uc_mcontext.__gregs[_REG_CPSR]; - if ((spsr & PSR_MODE) != PSR_USR32_MODE || - (spsr & (PSR_I | PSR_F)) != 0) - return (EINVAL); /* Restore register context. */ - set_mcontext(td, &uc.uc_mcontext); + error = set_mcontext(td, &uc.uc_mcontext); + if (error != 0) + return (error); /* Restore signal mask. */ kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0); Modified: stable/11/sys/arm64/arm64/machdep.c ============================================================================== --- stable/11/sys/arm64/arm64/machdep.c Tue Nov 28 11:04:47 2017 (r326312) +++ stable/11/sys/arm64/arm64/machdep.c Tue Nov 28 11:06:17 2017 (r326313) @@ -194,7 +194,8 @@ set_regs(struct thread *td, struct reg *regs) frame->tf_sp = regs->sp; frame->tf_lr = regs->lr; frame->tf_elr = regs->elr; - frame->tf_spsr = regs->spsr; + frame->tf_spsr &= ~PSR_FLAGS; + frame->tf_spsr |= regs->spsr & PSR_FLAGS; memcpy(frame->tf_x, regs->x, sizeof(frame->tf_x)); @@ -332,7 +333,13 @@ int set_mcontext(struct thread *td, mcontext_t *mcp) { struct trapframe *tf = td->td_frame; + uint32_t spsr; + spsr = mcp->mc_gpregs.gp_spsr; + if ((spsr & PSR_M_MASK) != PSR_M_EL0t || + (spsr & (PSR_F | PSR_I | PSR_A | PSR_D)) != 0) + return (EINVAL); + memcpy(tf->tf_x, mcp->mc_gpregs.gp_x, sizeof(tf->tf_x)); tf->tf_sp = mcp->mc_gpregs.gp_sp; @@ -502,19 +509,16 @@ int sys_sigreturn(struct thread *td, struct sigreturn_args *uap) { ucontext_t uc; - uint32_t spsr; + int error; if (uap == NULL) return (EFAULT); if (copyin(uap->sigcntxp, &uc, sizeof(uc))) return (EFAULT); - spsr = uc.uc_mcontext.mc_gpregs.gp_spsr; - if ((spsr & PSR_M_MASK) != PSR_M_EL0t || - (spsr & (PSR_F | PSR_I | PSR_A | PSR_D)) != 0) - return (EINVAL); - - set_mcontext(td, &uc.uc_mcontext); + error = set_mcontext(td, &uc.uc_mcontext); + if (error != 0) + return (error); set_fpcontext(td, &uc.uc_mcontext); /* Restore signal mask. */ Modified: stable/11/sys/arm64/include/armreg.h ============================================================================== --- stable/11/sys/arm64/include/armreg.h Tue Nov 28 11:04:47 2017 (r326312) +++ stable/11/sys/arm64/include/armreg.h Tue Nov 28 11:06:17 2017 (r326313) @@ -439,6 +439,7 @@ #define PSR_C 0x20000000 #define PSR_Z 0x40000000 #define PSR_N 0x80000000 +#define PSR_FLAGS 0xf0000000 /* TCR_EL1 - Translation Control Register */ #define TCR_ASID_16 (1 << 36)