1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-13 11:42:21 +00:00

Remove ineffective check for login shell; require -p for suid/sgid

In main.c:

158:		if(sh.ppid==1)
159:			sh.login_sh++;

If that was ever valid, it certainly is not now. As far as I know,
there is no currently existing system where PID 1 (init or systemd
or whatever) is the parent shell of the login shell, even straight
after bootup; login shells are invoked via a program like login(1).
Plus, there is no guarantee the init process actually has PID 1.

This invalidates all use of login_sh that couldn't be replaced by
checks for the login_shell option, so this commit does just that.

src/cmd/ksh93/include/shell.h:
- Remove login_sh flag.

src/cmd/ksh93/sh/init.c:
- If a login shell was detected, just set the login_shell option.
- Remove obsolete check for #! setuid scripts. This was meant to
  guard against a symlink called '-i' to a setuid script with a
  hashbang path, which used to give users a root shell. All modern
  Unixes ignore the setuid bit when they detect a hashbang path.

src/cmd/ksh93/SHOPT.sh:
- By default, let's require the -p/--privileged invocation option
  for the setuid/setgid bit on the shell binary to be respected,
  for all user IDs (>= 0). This is what bash and mksh do, and
  it seems sensible. (See init.c 1475-1483)
This commit is contained in:
Martijn Dekker 2022-07-21 03:16:15 +02:00
parent 948fab26aa
commit 8264d2089a
10 changed files with 8 additions and 24 deletions

View file

@ -127,8 +127,8 @@ The options have the following defaults and meanings:
OPTIMIZE on Optimize loop invariants for with for and while loops.
P_SUID off If set, all real UIDs, greater than or equal to this
value will require the -p flag to run SUID/SGID scripts.
P_SUID 0 If set, all real UIDs greater than or equal to this value
will require the -p option to run the shell setuid/setgid.
RAWONLY on Turn on if the vi line mode doesn't work right unless
you do a set -o viraw.

View file

@ -30,7 +30,7 @@ SHOPT NAMESPACE=1 # allow namespaces
SHOPT NOECHOE=0 # turn off 'echo -e' when SHOPT_ECHOPRINT is disabled
SHOPT OLDTERMIO= # support both TCGETA and TCGETS
SHOPT OPTIMIZE=1 # optimize loop invariants
SHOPT P_SUID= # real UIDs that require -p for set[ug]id (do not set to 0 to turn off)
SHOPT P_SUID=0 # real UIDs >= this value require -p for set[ug]id (to turn off, use empty, not 0)
SHOPT RAWONLY=1 # make viraw the only vi mode
SHOPT REGRESS= # enable __regress__ builtin and instrumented intercepts for testing
SHOPT REMOTE= # enable --rc if running as a remote shell

View file

@ -191,7 +191,6 @@ const char e_suidprofile[] = "/etc/suid_profile";
#if SHOPT_SYSRC
const char e_sysrc[] = "/etc/ksh.kshrc";
#endif
const char e_prohibited[] = "login setuid/setgid shells prohibited";
#ifdef BUILD_DTKSH
const char e_suidexec[] = SUIDEXECPATH;
#else

View file

@ -194,8 +194,7 @@ static void hist_touch(void *handle)
/*
* open the history file
* if HISTNAME is not given and userid==0 then no history file.
* if login_sh and HISTFILE is longer than HIST_MAX bytes then it is
* cleaned up.
* if HISTFILE is longer than HIST_MAX bytes then it is cleaned up.
* hist_open() returns 1, if history file is open
*/
int sh_histinit(void)

View file

@ -308,7 +308,6 @@ struct Shell_s
int savesig;
unsigned char *sigflag; /* pointer to signal states */
char intrap;
char login_sh;
char forked;
char binscript;
char funload;

View file

@ -675,7 +675,7 @@ noreturn void sh_done(register int sig)
tty_cooked(-1);
#endif /* SHOPT_VSH || SHOPT_ESH */
#ifdef JOBS
if((sh_isoption(SH_INTERACTIVE) && sh.login_sh) || (!sh_isoption(SH_INTERACTIVE) && (sig==SIGHUP)))
if((sh_isoption(SH_INTERACTIVE) && sh_isoption(SH_LOGIN_SHELL)) || (!sh_isoption(SH_INTERACTIVE) && (sig==SIGHUP)))
job_walk(sfstderr, job_hup, SIGHUP, NIL(char**));
#endif /* JOBS */
job_close();

View file

@ -477,7 +477,7 @@ static void init_radixpoint(void)
#endif
if(!r && val)
{
if(!sh_isstate(SH_INIT) || sh.login_sh==0)
if(!sh_isstate(SH_INIT) || !sh_isoption(SH_LOGIN_SHELL))
errormsg(SH_DICT,0,e_badlocale,val);
return;
}
@ -1353,7 +1353,7 @@ Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit)
{
type = sh_type(*argv);
if(type&SH_TYPE_LOGIN)
sh.login_sh = 2;
sh_onoption(SH_LOGIN_SHELL);
if(type&SH_TYPE_POSIX)
{
sh_onoption(SH_POSIX);
@ -1482,14 +1482,6 @@ Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit)
else
#endif /* SHOPT_P_SUID */
sh_onoption(SH_PRIVILEGED);
#ifdef SHELLMAGIC
/* careful of #! setuid scripts with name beginning with - */
if(sh.login_sh && argv[1] && strcmp(argv[0],argv[1])==0)
{
errormsg(SH_DICT,ERROR_exit(1),e_prohibited);
UNREACHABLE();
}
#endif /*SHELLMAGIC*/
}
else
sh_offoption(SH_PRIVILEGED);

View file

@ -705,7 +705,7 @@ int job_close(void)
errormsg(SH_DICT,0,e_terminate);
return(-1);
}
else if(running && sh.login_sh)
else if(running && sh_isoption(SH_LOGIN_SHELL))
{
errormsg(SH_DICT,0,e_jobsrunning);
return(-1);

View file

@ -155,10 +155,6 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
beenhere++;
sh_onstate(SH_PROFILE);
sh.sigflag[SIGTSTP] |= SH_SIGIGNORE;
if(sh.ppid==1)
sh.login_sh++;
if(sh.login_sh >= 2)
sh_onoption(SH_LOGIN_SHELL);
/* decide whether shell is interactive */
if(!sh_isoption(SH_INTERACTIVE) && !sh_isoption(SH_TFLAG) && !sh_isoption(SH_CFLAG) &&
sh_isoption(SH_SFLAG) && tty_check(0) && tty_check(ERRIO))

View file

@ -2930,7 +2930,6 @@ pid_t _sh_fork(register pid_t parent,int flags,int *jobid)
job.jobcontrol = 0;
#endif /* JOBS */
job.toclear = 1;
sh.login_sh = 0;
sh_offoption(SH_LOGIN_SHELL);
sh_onstate(SH_FORKED);
#if SHOPT_ACCT