Module Name:    src
Committed By:   christos
Date:           Tue May 26 21:35:15 UTC 2015

Modified Files:
        src/bin/sh: main.c options.h sh.1 var.c var.h

Log Message:
Drop privileges when executed set{u,g}id unless -p is specified like other
shells do to avoid system() and popen() abuse.


To generate a diff of this commit:
cvs rdiff -u -r1.58 -r1.59 src/bin/sh/main.c
cvs rdiff -u -r1.21 -r1.22 src/bin/sh/options.h
cvs rdiff -u -r1.114 -r1.115 src/bin/sh/sh.1
cvs rdiff -u -r1.43 -r1.44 src/bin/sh/var.c
cvs rdiff -u -r1.25 -r1.26 src/bin/sh/var.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/bin/sh/main.c
diff -u src/bin/sh/main.c:1.58 src/bin/sh/main.c:1.59
--- src/bin/sh/main.c:1.58	Sat May 31 10:42:18 2014
+++ src/bin/sh/main.c	Tue May 26 17:35:15 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: main.c,v 1.58 2014/05/31 14:42:18 christos Exp $	*/
+/*	$NetBSD: main.c,v 1.59 2015/05/26 21:35:15 christos Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1991, 19
 #if 0
 static char sccsid[] = "@(#)main.c	8.7 (Berkeley) 7/19/95";
 #else
-__RCSID("$NetBSD: main.c,v 1.58 2014/05/31 14:42:18 christos Exp $");
+__RCSID("$NetBSD: main.c,v 1.59 2015/05/26 21:35:15 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -106,6 +106,11 @@ main(int argc, char **argv)
 	struct stackmark smark;
 	volatile int state;
 	char *shinit;
+	uid_t uid;
+	gid_t gid;
+
+	uid = getuid();
+	gid = getgid();
 
 	setlocale(LC_ALL, "");
 
@@ -178,6 +183,18 @@ main(int argc, char **argv)
 	initpwd();
 	setstackmark(&smark);
 	procargs(argc, argv);
+
+	/*
+	 * Limit bogus system(3) or popen(3) calls in setuid binaries,
+	 * by requiring the -p flag
+	 */
+	if (!pflag && (uid != geteuid() || gid != getegid())) {
+		setuid(uid);
+		setgid(gid);
+		/* PS1 might need to be changed accordingly. */
+		choose_ps1();
+	}
+
 	if (argv[0] && argv[0][0] == '-') {
 		state = 1;
 		read_profile("/etc/profile");

Index: src/bin/sh/options.h
diff -u src/bin/sh/options.h:1.21 src/bin/sh/options.h:1.22
--- src/bin/sh/options.h:1.21	Fri Jan  2 14:56:20 2015
+++ src/bin/sh/options.h	Tue May 26 17:35:15 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: options.h,v 1.21 2015/01/02 19:56:20 christos Exp $	*/
+/*	$NetBSD: options.h,v 1.22 2015/05/26 21:35:15 christos Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -101,9 +101,11 @@ DEF_OPT( "tabcomplete",	0 )	/* <tab> cau
 #define	tabcomplete optlist[18].val
 DEF_OPT( "fork",	'F' )	/* use fork(2) instead of vfork(2) */
 #define	usefork optlist[19].val
+DEF_OPT( "nopriv",	'p' )	/* preserve privs even if set{u,g}id */
+#define pflag optlist[20].val
 #ifdef DEBUG
 DEF_OPT( "debug",	0 )	/* enable debug prints */
-#define	debug optlist[20].val
+#define	debug optlist[21].val
 #endif
 
 #ifdef DEFINE_OPTIONS

Index: src/bin/sh/sh.1
diff -u src/bin/sh/sh.1:1.114 src/bin/sh/sh.1:1.115
--- src/bin/sh/sh.1:1.114	Sun Jun  1 13:46:06 2014
+++ src/bin/sh/sh.1	Tue May 26 17:35:15 2015
@@ -1,4 +1,4 @@
-.\"	$NetBSD: sh.1,v 1.114 2014/06/01 17:46:06 christos Exp $
+.\"	$NetBSD: sh.1,v 1.115 2015/05/26 21:35:15 christos Exp $
 .\" Copyright (c) 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
 .\"
@@ -31,7 +31,7 @@
 .\"
 .\"	@(#)sh.1	8.6 (Berkeley) 5/4/95
 .\"
-.Dd June 1, 2014
+.Dd May 26, 2015
 .Dt SH 1
 .Os
 .Sh NAME
@@ -53,8 +53,8 @@
 .Nm
 .Fl c
 .Bk -words
-.Op Fl aCefnuvxIimqVEb
-.Op Cm +aCefnuvxIimqVEb
+.Op Fl abCEefnuvxIimpqV
+.Op Cm +abCEefnuvxIimpqV
 .Ek
 .Bk -words
 .Op Fl o Ar option_name
@@ -67,8 +67,8 @@
 .Nm
 .Fl s
 .Bk -words
-.Op Fl aCefnuvxIimqVEb
-.Op Cm +aCefnuvxIimqVEb
+.Op Fl abCEefnuvxIimpqV
+.Op Cm +abCEefnuvxIimpqV
 .Ek
 .Bk -words
 .Op Fl o Ar option_name
@@ -299,6 +299,13 @@ section below.)
 .It Fl b Em notify
 Enable asynchronous notification of background job completion.
 (Not implemented.)
+.It Fl p Em nopriv
+Do not attempt to reset effective uid if it does not match uid.
+This is not set by default to help avoid incorrect usage by setuid
+root programs via
+.Xr system 3
+or
+.Xr popen 3 .
 .It "\ \ " Em cdprint
 Make an interactive shell always print the new directory name when
 changed by the

Index: src/bin/sh/var.c
diff -u src/bin/sh/var.c:1.43 src/bin/sh/var.c:1.44
--- src/bin/sh/var.c:1.43	Fri Nov  1 12:49:02 2013
+++ src/bin/sh/var.c	Tue May 26 17:35:15 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: var.c,v 1.43 2013/11/01 16:49:02 christos Exp $	*/
+/*	$NetBSD: var.c,v 1.44 2015/05/26 21:35:15 christos Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)var.c	8.3 (Berkeley) 5/4/95";
 #else
-__RCSID("$NetBSD: var.c,v 1.43 2013/11/01 16:49:02 christos Exp $");
+__RCSID("$NetBSD: var.c,v 1.44 2015/05/26 21:35:15 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -190,11 +190,19 @@ initvar(void)
 	if (find_var("PS1", &vpp, &vps1.name_len) == NULL) {
 		vps1.next = *vpp;
 		*vpp = &vps1;
-		vps1.text = strdup(geteuid() ? "PS1=$ " : "PS1=# ");
 		vps1.flags = VSTRFIXED|VTEXTFIXED;
+		vps1.text = NULL;
+		choose_ps1();
 	}
 }
 
+void
+choose_ps1(void)
+{
+	free(vps1.text);
+	vps1.text = strdup(geteuid() ? "PS1=$ " : "PS1=# ");
+}
+
 /*
  * Safe version of setvar, returns 1 on success 0 on failure.
  */
@@ -575,11 +583,11 @@ exportcmd(int argc, char **argv)
 	char *name;
 	const char *p;
 	int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT;
-	int pflag;
+	int pflg;
 
-	pflag = nextopt("p") == 'p' ? 3 : 0;
-	if (argc <= 1 || pflag) {
-		showvars( pflag ? argv[0] : 0, flag, pflag );
+	pflg = nextopt("p") == 'p' ? 3 : 0;
+	if (argc <= 1 || pflg) {
+		showvars( pflg ? argv[0] : 0, flag, pflg );
 		return 0;
 	}
 

Index: src/bin/sh/var.h
diff -u src/bin/sh/var.h:1.25 src/bin/sh/var.h:1.26
--- src/bin/sh/var.h:1.25	Sat Jun 18 17:18:46 2011
+++ src/bin/sh/var.h	Tue May 26 17:35:15 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: var.h,v 1.25 2011/06/18 21:18:46 christos Exp $	*/
+/*	$NetBSD: var.h,v 1.26 2015/05/26 21:35:15 christos Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -125,5 +125,6 @@ void mklocal(const char *, int);
 void listmklocal(struct strlist *, int);
 void poplocalvars(void);
 int unsetvar(const char *, int);
+void choose_ps1(void);
 int setvarsafe(const char *, const char *, int);
 void print_quoted(const char *);

Reply via email to