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 *);