call setsid() when called with -c
Prevents command injection via TIOCSTI https://bugzilla.redhat.com/show_bug.cgi?id=173008
This commit is contained in:
parent
a6fdd3f812
commit
c6a1746b5f
|
@ -157,6 +157,9 @@ static bool simulate_login;
|
||||||
/* If true, change some environment vars to indicate the user su'd to. */
|
/* If true, change some environment vars to indicate the user su'd to. */
|
||||||
static bool change_environment;
|
static bool change_environment;
|
||||||
|
|
||||||
|
/* If true, then don't call setsid() with a command. */
|
||||||
|
int same_session = 0;
|
||||||
|
|
||||||
#ifdef USE_PAM
|
#ifdef USE_PAM
|
||||||
static bool _pam_session_opened;
|
static bool _pam_session_opened;
|
||||||
static bool _pam_cred_established;
|
static bool _pam_cred_established;
|
||||||
|
@ -165,6 +168,7 @@ static bool _pam_cred_established;
|
||||||
static struct option const longopts[] =
|
static struct option const longopts[] =
|
||||||
{
|
{
|
||||||
{"command", required_argument, NULL, 'c'},
|
{"command", required_argument, NULL, 'c'},
|
||||||
|
{"session-command", required_argument, NULL, 'C'},
|
||||||
{"fast", no_argument, NULL, 'f'},
|
{"fast", no_argument, NULL, 'f'},
|
||||||
{"login", no_argument, NULL, 'l'},
|
{"login", no_argument, NULL, 'l'},
|
||||||
{"preserve-environment", no_argument, NULL, 'p'},
|
{"preserve-environment", no_argument, NULL, 'p'},
|
||||||
|
@ -339,10 +343,23 @@ create_watching_parent (void)
|
||||||
sigemptyset (&action.sa_mask);
|
sigemptyset (&action.sa_mask);
|
||||||
action.sa_flags = 0;
|
action.sa_flags = 0;
|
||||||
sigemptyset (&ourset);
|
sigemptyset (&ourset);
|
||||||
if (sigaddset (&ourset, SIGTERM)
|
if (!same_session)
|
||||||
|| sigaddset (&ourset, SIGALRM)
|
{
|
||||||
|| sigaction (SIGTERM, &action, NULL)
|
if (sigaddset(&ourset, SIGINT) || sigaddset(&ourset, SIGQUIT))
|
||||||
|| sigprocmask (SIG_UNBLOCK, &ourset, NULL))
|
{
|
||||||
|
error (0, errno, _("cannot set signal handler"));
|
||||||
|
caught_signal = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!caught_signal && (sigaddset(&ourset, SIGTERM)
|
||||||
|
|| sigaddset(&ourset, SIGALRM)
|
||||||
|
|| sigaction(SIGTERM, &action, NULL)
|
||||||
|
|| sigprocmask(SIG_UNBLOCK, &ourset, NULL))) {
|
||||||
|
error (0, errno, _("cannot set signal handler"));
|
||||||
|
caught_signal = true;
|
||||||
|
}
|
||||||
|
if (!caught_signal && !same_session && (sigaction(SIGINT, &action, NULL)
|
||||||
|
|| sigaction(SIGQUIT, &action, NULL)))
|
||||||
{
|
{
|
||||||
error (0, errno, _("cannot set signal handler"));
|
error (0, errno, _("cannot set signal handler"));
|
||||||
caught_signal = true;
|
caught_signal = true;
|
||||||
|
@ -764,6 +781,8 @@ Change the effective user id and group id to that of USER.\n\
|
||||||
\n\
|
\n\
|
||||||
-, -l, --login make the shell a login shell\n\
|
-, -l, --login make the shell a login shell\n\
|
||||||
-c, --command=COMMAND pass a single COMMAND to the shell with -c\n\
|
-c, --command=COMMAND pass a single COMMAND to the shell with -c\n\
|
||||||
|
--session-command=COMMAND pass a single COMMAND to the shell with -c\n\
|
||||||
|
and do not create a new session\n\
|
||||||
-f, --fast pass -f to the shell (for csh or tcsh)\n\
|
-f, --fast pass -f to the shell (for csh or tcsh)\n\
|
||||||
-m, --preserve-environment do not reset environment variables\n\
|
-m, --preserve-environment do not reset environment variables\n\
|
||||||
-p same as -m\n\
|
-p same as -m\n\
|
||||||
|
@ -786,6 +805,7 @@ main (int argc, char **argv)
|
||||||
int optc;
|
int optc;
|
||||||
const char *new_user = DEFAULT_USER;
|
const char *new_user = DEFAULT_USER;
|
||||||
char *command = NULL;
|
char *command = NULL;
|
||||||
|
int request_same_session = 0;
|
||||||
char *shell = NULL;
|
char *shell = NULL;
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
struct passwd pw_copy;
|
struct passwd pw_copy;
|
||||||
|
@ -811,6 +831,11 @@ main (int argc, char **argv)
|
||||||
command = optarg;
|
command = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'C':
|
||||||
|
command = optarg;
|
||||||
|
request_same_session = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
fast_startup = true;
|
fast_startup = true;
|
||||||
break;
|
break;
|
||||||
|
@ -881,6 +906,9 @@ main (int argc, char **argv)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (request_same_session || !command || !pw->pw_uid)
|
||||||
|
same_session = 1;
|
||||||
|
|
||||||
if (!shell && !change_environment)
|
if (!shell && !change_environment)
|
||||||
shell = getenv ("SHELL");
|
shell = getenv ("SHELL");
|
||||||
if (shell && getuid () != 0 && restricted_shell (pw->pw_shell))
|
if (shell && getuid () != 0 && restricted_shell (pw->pw_shell))
|
||||||
|
@ -902,6 +930,8 @@ main (int argc, char **argv)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
change_identity (pw);
|
change_identity (pw);
|
||||||
|
if (!same_session)
|
||||||
|
setsid ();
|
||||||
|
|
||||||
/* Set environment after pam_open_session, which may put KRB5CCNAME
|
/* Set environment after pam_open_session, which may put KRB5CCNAME
|
||||||
into the pam_env, etc. */
|
into the pam_env, etc. */
|
||||||
|
|
Loading…
Reference in New Issue