Subject: bin/362: setuid /bin/sh scripts are insecure (and fix)
To: None <gnats-admin>
From: Mark Weaver <mhw@cs.brown.edu>
List: netbsd-bugs
Date: 07/22/1994 16:35:06
>Number:         362
>Category:       bin
>Synopsis:       setuid /bin/sh scripts are insecure (and fix)
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    gnats-admin (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   mhw
>Arrival-Date:   Fri Jul 22 16:35:03 1994
>Originator:     Mark Weaver
>Organization:
--------------------------------------------------------------------
Email: Mark_Weaver@brown.edu           | Brown University
PGP Key: finger mhw@cs.brown.edu       | Dept of Computer Science
>Release:        NetBSD 1.0-ALPHA (21-July-1994)
>Environment:

System: NetBSD cis-ts3-slip4.cis.brown.edu 1.0-ALPHA NetBSD 1.0-ALPHA (EXCELSIOR) #0: Fri Jul 22 07:27:48 EDT 1994 mhw@cis-ts3-slip4.cis.brown.edu:/usr/src/sys/arch/i386/compile/EXCELSIOR i386


>Description:
	When /bin/sh starts up, it reads in the file named in the environment
	variable "ENV".  I don't see any option that can turn this off,
	from looking at both the man page and the source.

	This seems like a gaping security hole to me.  Assuming I read the
	source correctly, can I suggest making sh ignore ENV by default if
	uid!=euid?

	I haven't extensively looked for other possible security holes,
	but as long as sh isn't a login shell, I don't think it loads any
	other files.  Of course, always make sure you set your PATH at the
	beginning of the script.

>How-To-Repeat:
	Make any setuid shell script.  Then, as an unprivileged user,
	set the environment variable "ENV" to any script you want to
	run as root.  Run the setuid shell script and it will run the
	script specified by "ENV" with root privs.

>Fix:
*** src/bin/sh/main.c.mhw1	Sun Jun 12 06:01:35 1994
--- src/bin/sh/main.c	Fri Jul 22 13:30:47 1994
***************
*** 159,166 ****
  	} 
  state2:
  	state = 3;
! 	if ((shinit = lookupvar("ENV")) != NULL &&
! 	     *shinit != '\0') {
  		state = 3;
  		read_profile(shinit);
  	}
--- 159,167 ----
  	} 
  state2:
  	state = 3;
! 	if (getuid() == geteuid() &&
! 	    (shinit = lookupvar("ENV")) != NULL &&
! 	    *shinit != '\0') {
  		state = 3;
  		read_profile(shinit);
  	}
>Audit-Trail:
>Unformatted:


------------------------------------------------------------------------------