fix the “set ±p” issue for good

cf. http://blog.cmpxchg8b.com/2013/08/security-debianisms.html
This commit is contained in:
tg 2014-06-09 12:28:19 +00:00
parent 7734e07d12
commit 129ba5c584
3 changed files with 27 additions and 31 deletions

32
main.c
View File

@ -34,7 +34,7 @@
#include <locale.h> #include <locale.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.279 2014/01/16 13:59:12 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/main.c,v 1.280 2014/06/09 12:28:17 tg Exp $");
extern char **environ; extern char **environ;
@ -407,7 +407,7 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
setint_n((vp_pipest = global("PIPESTATUS")), 0, 10); setint_n((vp_pipest = global("PIPESTATUS")), 0, 10);
/* Set this before parsing arguments */ /* Set this before parsing arguments */
Flag(FPRIVILEGED) = kshuid != ksheuid || kshgid != kshegid; Flag(FPRIVILEGED) = (kshuid != ksheuid || kshgid != kshegid) ? 2 : 0;
/* this to note if monitor is set on command line (see below) */ /* this to note if monitor is set on command line (see below) */
#ifndef MKSH_UNEMPLOYED #ifndef MKSH_UNEMPLOYED
@ -585,22 +585,22 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
if (!current_wd[0] && Flag(FTALKING)) if (!current_wd[0] && Flag(FTALKING))
warningf(false, "can't determine current directory"); warningf(false, "can't determine current directory");
if (Flag(FLOGIN)) { if (Flag(FLOGIN))
include(MKSH_SYSTEM_PROFILE, 0, NULL, true); include(MKSH_SYSTEM_PROFILE, 0, NULL, true);
if (!Flag(FPRIVILEGED)) if (!Flag(FPRIVILEGED)) {
include(substitute("$HOME/.profile", 0), 0, if (Flag(FLOGIN))
NULL, true); include(substitute("$HOME/.profile", 0), 0, NULL, true);
} if (Flag(FTALKING)) {
if (Flag(FPRIVILEGED)) cp = substitute(substitute("${ENV:-" MKSHRC_PATH "}",
0), DOTILDE);
if (cp[0] != '\0')
include(cp, 0, NULL, true);
}
} else {
include(MKSH_SUID_PROFILE, 0, NULL, true); include(MKSH_SUID_PROFILE, 0, NULL, true);
else if (Flag(FTALKING)) { /* turn off -p if not set explicitly */
char *env_file; if (Flag(FPRIVILEGED) != 1)
change_flag(FPRIVILEGED, OF_INTERNAL, false);
/* include $ENV */
env_file = substitute(substitute("${ENV:-" MKSHRC_PATH "}", 0),
DOTILDE);
if (*env_file != '\0')
include(env_file, 0, NULL, true);
} }
if (restricted) { if (restricted) {

22
mksh.1
View File

@ -1,4 +1,4 @@
.\" $MirOS: src/bin/mksh/mksh.1,v 1.334 2014/06/09 11:22:50 tg Exp $ .\" $MirOS: src/bin/mksh/mksh.1,v 1.335 2014/06/09 12:28:17 tg Exp $
.\" $OpenBSD: ksh.1,v 1.152 2014/02/12 16:28:13 schwarze Exp $ .\" $OpenBSD: ksh.1,v 1.152 2014/02/12 16:28:13 schwarze Exp $
.\"- .\"-
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
@ -247,8 +247,7 @@ below.
Privileged shell. Privileged shell.
A shell is A shell is
.Dq privileged .Dq privileged
if this option is used if the real user ID or group ID does not match the
or if the real user ID or group ID does not match the
effective user ID or group ID (see effective user ID or group ID (see
.Xr getuid 2 .Xr getuid 2
and and
@ -257,6 +256,9 @@ Clearing the privileged option causes the shell to set
its effective user ID (group ID) to its real user ID (group ID). its effective user ID (group ID) to its real user ID (group ID).
For further implications, see For further implications, see
.Sx Startup files . .Sx Startup files .
If the shell is privileged and this flag is not explicitly set, the
.Dq privileged
option is cleared automatically after processing the startup files.
.It Fl r .It Fl r
Restricted shell. Restricted shell.
A shell is A shell is
@ -366,15 +368,9 @@ parameter after subjecting it to parameter, command, arithmetic and tilde
substitution; if unset or empty, the user mkshrc profile is processed; substitution; if unset or empty, the user mkshrc profile is processed;
otherwise, if a file whose name is the substitution result exists, otherwise, if a file whose name is the substitution result exists,
it is processed; non-existence is silently ignored. it is processed; non-existence is silently ignored.
.Pp A privileged shell then drops privileges if neither was the
The suid profile probably should run .Fl p
.Ic set +p option given on the command line nor set during execution of the startup files.
unless the shell was explicitly started with
.Fl p .
This isn't easily implemented but
.Pq just always run Ic set +p
a stopgap measure for:
.Pa http://blog.cmpxchg8b.com/2013/08/security\-debianisms.html
.Ss Command syntax .Ss Command syntax
The shell begins parsing its input by removing any backslash-newline The shell begins parsing its input by removing any backslash-newline
combinations, then breaking it into combinations, then breaking it into
@ -6457,7 +6453,7 @@ $ /bin/sleep 666 && echo fubar
.Ed .Ed
.Pp .Pp
This document attempts to describe This document attempts to describe
.Nm mksh\ R49 .Nm mksh\ R50
and up, and up,
compiled without any options impacting functionality, such as compiled without any options impacting functionality, such as
.Dv MKSH_SMALL , .Dv MKSH_SMALL ,

View File

@ -1,5 +1,5 @@
@SHFLAGS_DEFNS @SHFLAGS_DEFNS
__RCSID("$MirOS: src/bin/mksh/sh_flags.opt,v 1.1 2013/11/17 22:22:56 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh_flags.opt,v 1.2 2014/06/09 12:28:19 tg Exp $");
#define FN(sname,cname,flags,ochar) \ #define FN(sname,cname,flags,ochar) \
static const struct { \ static const struct { \
/* character flag (if any) */ \ /* character flag (if any) */ \
@ -123,7 +123,7 @@ FN("pipefail", FPIPEFAIL, OF_ANY
>| >|
FN("posix", FPOSIX, OF_ANY FN("posix", FPOSIX, OF_ANY
/* -p use suid_profile; privileged shell */ /* -p privileged shell (suid) */
>p| >p|
FN("privileged", FPRIVILEGED, OF_ANY FN("privileged", FPRIVILEGED, OF_ANY