View Issue Details

IDProjectCategoryView StatusLast Update
0000540Kali LinuxFeature Requestspublic2018-01-29 12:24
Reporterdookie Assigned Tog0tmi1k  
PrioritynormalSeverityminorReproducibilityhave not tried
Status closedResolutionsuspended 
Product Version2.0 
Summary0000540: Implement privmode Support in dash
Description

Patch details: http://thread.gmane.org/gmane.comp.shells.dash/841

As Tavis notes:

"this is a patch to add privmode support to dash. privmode attempts to
drop privileges by default if the effective uid does not match the uid. This
can be disabled with -p, or -o nopriv.

This matches the behaviour of bash since version 2.0 (released around 1996"

Although Kali is supposed to run as root, this would still be a good idea to patch for those users who prefer to run as a low-priv user and it would be trivial to implement.

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);
  • /*
    • PS1 depends on uid
  • */
  • 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;

Relationships

related to 0000536 closedg0tmi1k Debian default shell security issue 

Activities

rhertzog

rhertzog

2014-01-16 14:18

administrator   ~0001408

I sent a mail to Tavis Ormandy, Harald van Dijk and Jilles Tjoelker to try to restart the process of getting the patch merged upstream.

g0tmi1k

g0tmi1k

2018-01-29 12:24

administrator   ~0008103

Due to the age of the OS (Kali Moto [v1], Kali Safi [v2], Kali Rolling 2016.x), these legacy versions are no longer supported.
We will be closing this ticket due to inactivity.

Please could you see if you are able to replicate this issue with the latest version of Kali Linux - https://www.kali.org/downloads/)?

If you are still facing the same problem, feel free to re-open the ticket. If you choose to do this, could you provide more information to the issue you are facing,and also give information about your setup?
For more information, please read: https://kali.training/topic/filing-a-good-bug-report/

Issue History

Date Modified Username Field Change
2013-08-23 11:46 dookie New Issue
2014-01-10 14:48 rhertzog Relationship added related to 0000536
2014-01-16 14:18 rhertzog Note Added: 0001408
2015-09-03 12:07 rhertzog Category Tool Upgrade => Feature Requests
2015-09-03 12:07 rhertzog Product Version => 2.0
2018-01-29 12:24 g0tmi1k Assigned To => g0tmi1k
2018-01-29 12:24 g0tmi1k Status new => closed
2018-01-29 12:24 g0tmi1k Resolution open => suspended
2018-01-29 12:24 g0tmi1k Note Added: 0008103