Additional Information | Initial patch proposed by Tavis Ormandy:
src/dash.1 | 16 ++++++++++------
src/main.c | 17 +++++++++++++++++
src/options.c | 2 ++
src/options.h | 7 ++++---
src/var.c | 29 +++++++++++++++++++++++------
src/var.h | 1 +
6 files changed, 57 insertions(+), 15 deletions(-)
diff --git a/src/dash.1 b/src/dash.1
index a9cb491..94fc642 100644
--- a/src/dash.1
+++ b/src/dash.1
<at> <at> -41,8 +41,8 <at> <at>
.Sh SYNOPSIS
.Nm
.Bk -words
-.Op Fl aCefnuvxIimqVEb
-.Op Cm +aCefnuvxIimqVEb
+.Op Fl aCefnuvxIimqVEbp
+.Op Cm +aCefnuvxIimqVEbp
.Ek
.Bk -words
.Op Fl o Ar option_name
<at> <at> -54,8 +54,8 <at> <at>
.Nm
.Fl c
.Bk -words
-.Op Fl aCefnuvxIimqVEb
-.Op Cm +aCefnuvxIimqVEb
+.Op Fl aCefnuvxIimqVEbp
+.Op Cm +aCefnuvxIimqVEbp
.Ek
.Bk -words
.Op Fl o Ar option_name
<at> <at> -68,8 +68,8 <at> <at>
.Nm
.Fl s
.Bk -words
-.Op Fl aCefnuvxIimqVEb
-.Op Cm +aCefnuvxIimqVEb
+.Op Fl aCefnuvxIimqVEbp
+.Op Cm +aCefnuvxIimqVEbp
.Ek
.Bk -words
.Op Fl o Ar option_name
<at> <at> -257,6 +257,10 <at> <at> if it has been set).
.It Fl b Em notify
Enable asynchronous notification of background job completion.
(UNIMPLEMENTED for 4.4alpha)
+.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 system(3) or
+popen(3).
.El
.Ss Lexical Structure
The shell reads input in terms of lines from a file and breaks it up into
diff --git a/src/main.c b/src/main.c
index f79ad7d..7ca247d 100644
--- a/src/main.c
+++ b/src/main.c
<at> <at> -97,11 +97,16 <at> <at> main(int argc, char **argv)
struct jmploc jmploc;
struct stackmark smark;
int login;
-
uid_t uid;
-
gid_t gid;
#ifdef GLIBC
dash_errno = __errno_location();
#endif
-
uid = getuid();
-
gid = getgid();
-
#if PROFILE
monitor(4, etext, profile_buf, sizeof profile_buf, 50);
#endif
<at> <at> -148,6 +153,18 <at> <at> main(int argc, char **argv)
init();
setstackmark(&smark);
login = procargs(argc, argv);
-
-
/*
-
- To limit bogus system(3) or popen(3) calls in setuid binaries, require
-
- -p flag to work in this situation.
-
*/
-
if (!pflag && (uid != geteuid() || gid != getegid())) {
-
setuid(uid);
-
setgid(gid);
-
/ PS1 might need to be changed accordingly. /
-
choose_ps1();
-
}
-
if (login) {
state = 1;
read_profile("/etc/profile");
diff --git a/src/options.c b/src/options.c
index 6f381e6..99ac55b 100644
--- a/src/options.c
+++ b/src/options.c
<at> <at> -79,6 +79,7 <at> <at> static const char *const optnames[NOPTS] = {
"allexport",
"notify",
"nounset",
-
"nopriv",
"nolog",
"debug",
};
<at> <at> -99,6 +100,7 <at> <at> const char optletters[NOPTS] = {
'a',
'b',
'u',
-
'p',
0,
0,
};
diff --git a/src/options.h b/src/options.h
index 975fe33..9e90947 100644
--- a/src/options.h
+++ b/src/options.h
<at> <at> -59,10 +59,11 <at> <at> struct shparam {
#define aflag optlist[12]
#define bflag optlist[13]
#define uflag optlist[14]
-#define nolog optlist[15]
-#define debug optlist[16]
+#define pflag optlist[15]
+#define nolog optlist[16]
+#define debug optlist[17]
-#define NOPTS 17
+#define NOPTS 18
extern const char optletters[NOPTS];
extern char optlist[NOPTS];
diff --git a/src/var.c b/src/var.c
index dc90249..d04c4d9 100644
--- a/src/var.c
+++ b/src/var.c
<at> <at> -81,6 +81,9 <at> <at> const char defifsvar[] = "IFS= \t\n";
const char defifs[] = " \t\n";
#endif
+const char defps1[] = "PS1=$ ";
+const char rootps1[] = "PS1=# ";
+
int lineno;
char linenovar[sizeof("LINENO=")+sizeof(int)*CHAR_BIT/3+1] = "LINENO=";
<at> <at> -97,7 +100,7 <at> <at> struct var varinit[] = {
{ 0, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL\0", changemail },
{ 0, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH\0", changemail },
{ 0, VSTRFIXED|VTEXTFIXED, defpathvar, changepath },
- { 0, VSTRFIXED|VTEXTFIXED, "PS1=$ ", 0 },
- { 0, VSTRFIXED|VTEXTFIXED, defps1, 0 },
{ 0, VSTRFIXED|VTEXTFIXED, "PS2=> ", 0 },
{ 0, VSTRFIXED|VTEXTFIXED, "PS4=+ ", 0 },
{ 0, VSTRFIXED|VTEXTFIXED, "OPTIND=1", getoptsreset },
<at> <at> -178,11 +181,25 <at> <at> initvar(void)
vp->next = vpp;
vpp = vp;
} while (++vp < end);
- /*
-
- */
- if (!geteuid())
- vps1.text = "PS1=# ";
-
- choose_ps1();
+}
-
+/*
-
- Modify PS1 to reflect uid, unless an exported var exists.
- */
-
+void
+choose_ps1(void)
+{
- if (vps1.flags & VEXPORT)
- return;
-
- if (!geteuid()) {
- vps1.text = rootps1;
- } else {
- vps1.text = defps1;
-
}
}
/*
diff --git a/src/var.h b/src/var.h
index 79ee71a..bb2175b 100644
--- a/src/var.h
+++ b/src/var.h
<at> <at> -139,6 +139,7 <at> <at> extern char linenovar[];
#define mpathset() ((vmpath.flags & VUNSET) == 0)
void initvar(void);
+void choose_ps1(void);
struct var setvar(const char name, const char val, int flags);
intmax_t setvarint(const char , intmax_t, int);
struct var setvareq(char s, int flags);
Amended patch from Harald van Dijk to change nopriv to priv:
diff --git a/src/Makefile.am b/src/Makefile.am
index 2a37381..82d00fb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -21,14 +21,14 @@ bin_PROGRAMS = dash
dash_CFILES = \
alias.c arith_yacc.c arith_yylex.c cd.c error.c eval.c exec.c expand.c \
histedit.c input.c jobs.c mail.c main.c memalloc.c miscbltin.c \
- mystring.c options.c parser.c redir.c show.c trap.c output.c \
- mystring.c options.c parser.c priv.c redir.c show.c trap.c output.c \
bltin/printf.c system.c bltin/test.c bltin/times.c var.c
dash_SOURCES = \
$(dash_CFILES) \
alias.h arith_yacc.h bltin/bltin.h cd.h error.h eval.h exec.h \
expand.h hetio.h \
init.h input.h jobs.h machdep.h mail.h main.h memalloc.h miscbltin.h \
- myhistedit.h mystring.h options.h output.h parser.h redir.h shell.h \
- myhistedit.h mystring.h options.h output.h parser.h priv.h redir.h shell.h \
show.h system.h trap.h var.h
dash_LDADD = builtins.o init.o nodes.o signames.o syntax.o
diff --git a/src/dash.1 b/src/dash.1
index 94fc642..0f35748 100644
--- a/src/dash.1
+++ b/src/dash.1
@@ -257,7 +257,7 @@ if it has been set).
.It Fl b Em notify
Enable asynchronous notification of background job completion.
(UNIMPLEMENTED for 4.4alpha)
-.It Fl p Em nopriv
+.It Fl p Em priv
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 system(3) or
popen(3).
diff --git a/src/main.c b/src/main.c
index e106848..69e5e07 100644
--- a/src/main.c
+++ b/src/main.c
@@ -50,6 +50,7 @@
#include "eval.h"
#include "jobs.h"
#include "input.h"
+#include "priv.h"
#include "trap.h"
#include "var.h"
#include "show.h"
@@ -97,8 +98,6 @@ main(int argc, char **argv)
struct jmploc jmploc;
struct stackmark smark;
int login;
-
uid_t uid;
-
gid_t gid;
#ifdef GLIBC
dash_errno = __errno_location();
@@ -154,17 +153,6 @@ main(int argc, char **argv)
setstackmark(&smark);
login = procargs(argc, argv);
-
/*
-
- To limit bogus system(3) or popen(3) calls in setuid binaries, require
-
- -p flag to work in this situation.
-
*/
-
if (!pflag && (uid != geteuid() || gid != getegid())) {
-
setuid(uid);
-
setgid(gid);
-
/ PS1 might need to be changed accordingly. /
-
choose_ps1();
-
}
-
if (login) {
state = 1;
read_profile("/etc/profile");
diff --git a/src/options.c b/src/options.c
index 99ac55b..c640a41 100644
--- a/src/options.c
+++ b/src/options.c
@@ -45,6 +45,7 @@
#include "jobs.h"
#include "input.h"
#include "output.h"
+#include "priv.h"
#include "trap.h"
#include "var.h"
#include "memalloc.h"
@@ -79,7 +80,7 @@ static const char *const optnames[NOPTS] = {
"allexport",
"notify",
"nounset",
-
"nopriv",
-
"priv",
"nolog",
"debug",
};
@@ -184,6 +185,7 @@ optschanged(void)
#ifdef DEBUG
opentrace();
#endif
-
setprivileged(pflag);
setinteractive(iflag);
#ifndef SMALL
histedit();
diff --git a/src/priv.c b/src/priv.c
new file mode 100644
index 0000000..26346c0
--- /dev/null
+++ b/src/priv.c
@@ -0,0 +1,27 @@
+#include <unistd.h>
-
+#include "priv.h"
+#include "var.h"
-
+uid_t uid;
+gid_t gid;
-
+void setprivileged(int on)
+{
-
static int is_privileged = 1;
-
if (is_privileged == on)
-
return;
-
-
is_privileged = on;
-
-
/*
-
- To limit bogus system(3) or popen(3) calls in setuid binaries, require
-
- -p flag to work in this situation.
-
*/
-
if (!on && (uid != geteuid() || gid != getegid())) {
-
setuid(uid);
-
setgid(gid);
-
/ PS1 might need to be changed accordingly. /
-
choose_ps1();
-
}
+}
diff --git a/src/priv.h b/src/priv.h
new file mode 100644
index 0000000..31b380b
--- /dev/null
+++ b/src/priv.h
@@ -0,0 +1,6 @@
+#include <unistd.h>
-
+extern uid_t uid;
+extern gid_t gid;
-
+void setprivileged(int on);
diff --git a/src/var.c b/src/var.c
index cafe407..277777f 100644
--- a/src/var.c
+++ b/src/var.c
@@ -192,13 +192,12 @@ initvar(void)
void
choose_ps1(void)
{
-
if (vps1.flags & VEXPORT)
-
return;
|
---|