COMMAND

    sh3 (kernel)

SYSTEMS AFFECTED

    NetBSD

PROBLEM

    Following  is  based  on  a  NetBSD  Security  Advisory  2001-008.
    Missing validation  of user-supplied  arguments to  a system  call
    can allow user  applications on the  sh3 platform to  execute code
    with supervisor privileges,  bypassing normal system  protections.
    This problem is only present  on the sh3 platform, which  includes
    the dreamcast, evbsh3, hpcsh and mmeye ports.

    The Hitachi Super-H architecture  includes the Status Register,  a
    processor register which provides  status information such as  the
    true/false condition bit, and which also controls properties among
    which is the processor mode (either user mode or privileged mode).
    The only component of NetBSD  executing in privileged mode is  the
    kernel; user processes are restricted to user mode and thus cannot
    execute  privileged  processor  instructions  or  access   related
    resources.

    As a  part of  the protection  model, the  contents of  the Status
    Register can be modified only when executing in privileged mode.

    While reviewing code in NetBSD, it was discovered that the  NetBSD
    "sigreturn" system  call did  not do  validation of  user-supplied
    Status  Register  contents;  it  was  also  discovered  that   the
    "process_write_regs" kernel routine, which  is used by the  procfs
    and ptrace(2)  facilities, did  not do  appropriate validation  of
    user-supplied Status  Register contents;  in short,  it's possible
    for a  user process  to construct  and pass  an execution  context
    which makes it resume in privileged mode.

    Credits to Klaus Klein for detecting and resolving this problem.

SOLUTION

    Systems running  NetBSD/evbsh3, NetBSD/dreamcast,  NetBSD/hpcsh or
    NetBSD/mmeye are vulnerable.  Although the NetBSD Project has  not
    distributed binary releases for these ports yet, binary  snapshots
    of development versions are known to be in use.

    Systems  running  NetBSD-current  dated  from  before May 16, 2001
    should be upgraded to NetBSD-current dated May 16, 2001 or  later.
    Systems running NetBSD-release-1-5 dated from before May 27,  2001
    should be  upgraded to  NetBSD-release-1-5 dated  May 27,  2001 or
    later.

    The following patches to
    - /sys/arch/sh3/include/psl.h,
    - /sys/arch/sh3/sh3/compat_13_machdep.c and
    - /sys/arch/sh3/sh3/sh3_machdep.c
    should be applied before building a new kernel.  This patch can be
    applied (with offset differences) to NetBSD-1.5 or  NetBSD-current
    kernel sources using the patch(1) command.

    Index: include/psl.h
    ===================================================================
    RCS file: /cvsroot/syssrc/sys/arch/sh3/include/psl.h,v
    retrieving revision 1.1
    retrieving revision 1.2
    diff -u -r1.1 -r1.2
    --- include/psl.h	1999/09/13 10:31:21	1.1
    +++ include/psl.h	2001/05/16 12:42:38	1.2
    @@ -57,8 +57,8 @@
     #define	PSL_MBO		0x00000000	/* must be one bits */
     #define	PSL_MBZ		0x8ffffc0c	/* must be zero bits */
    
    -#define PSL_USERSET    0
    -#define PSL_USERSTATIC    (PSL_BL|PSL_RB|PSL_MD|PSL_IMASK)
    +#define PSL_USERSET	0
    +#define PSL_USERSTATIC	(PSL_BL|PSL_RB|PSL_MD|PSL_IMASK|PSL_MBO|PSL_MBZ)
    
     #ifdef _KERNEL
     #include <machine/intr.h>
    Index: sh3/compat_13_machdep.c
    ===================================================================
    RCS file: /cvsroot/syssrc/sys/arch/sh3/sh3/compat_13_machdep.c,v
    retrieving revision 1.2
    retrieving revision 1.3
    diff -u -r1.2 -r1.3
    --- sh3/compat_13_machdep.c	2000/12/22 22:58:55	1.2
    +++ sh3/compat_13_machdep.c	2001/05/16 12:42:38	1.3
    @@ -71,16 +71,9 @@
 	    /* Restore register context. */
 	    tf = p->p_md.md_regs;
    
    -	/*
    -	 * Check for security violations.  If we're returning to
    -	 * protected mode, the CPU will validate the segment registers
    -	 * automatically and generate a trap on violations.  We handle
    -	 * the trap, rather than doing all of the checking here.
    -	 */
    -#ifdef TODO
    +	/* Check for security violations.  */
 	    if (((context.sc_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0)
 		    return (EINVAL);
    -#endif
    
 	    tf->tf_ssr = context.sc_ssr;
    
    Index: sh3/sh3_machdep.c
    ===================================================================
    RCS file: /cvsroot/syssrc/sys/arch/sh3/sh3/sh3_machdep.c,v
    retrieving revision 1.12
    retrieving revision 1.13
    diff -u -r1.12 -r1.13
    --- sh3/sh3_machdep.c	2001/04/24 04:31:09	1.12
    +++ sh3/sh3_machdep.c	2001/05/16 12:42:38	1.13
    @@ -350,21 +350,13 @@
    
 	    /* Restore signal context. */
 	    tf = p->p_md.md_regs;
    -	{
    -		/*
    -		 * Check for security violations.  If we're returning to
    -		 * protected mode, the CPU will validate the segment registers
    -		 * automatically and generate a trap on violations.  We handle
    -		 * the trap, rather than doing all of the checking here.
    -		 */
    -#ifdef TODO
    -	  if (((context.sc_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0) {
    -	    return (EINVAL);
    -	  }
    -#endif
    
    -	  tf->tf_ssr = context.sc_ssr;
    -	}
    +	/* Check for security violations. */
    +	if (((context.sc_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0)
    +		return (EINVAL);
    +
    +	tf->tf_ssr = context.sc_ssr;
    +
 	    tf->tf_r0 = context.sc_r0;
 	    tf->tf_r1 = context.sc_r1;
 	    tf->tf_r2 = context.sc_r2;