What is the difference between "su --command" and "su --session-command"?
Generally, you should prefer --command
(-c) to --session-command
. You should not be using -c with interactive shells (maybe you wanted --shell /bin/bash
?), but you should be using it with background processes.
--session-command does not call setsid() to allocate a new session (which has the effect, as you found, of allowing the continued use of the controlling tty and thus bash will give you process control being an interactive shell). This means its children can be assigned to any process group of the parent session, perhaps the session foreground pg or to avoiding killpg() or other classification based on process group id. It also retains the ability to send SIGCONT to any process in the session, though I'm not sure how abuseable that is.
Related videos on Youtube
oliver
Updated on September 18, 2022Comments
-
oliver over 1 year
Running
# su - oliver --command bash
gives a shell but also prints the warningbash: no job control in this shell
, and indeed Ctrl+Z andfg
/bg
don't work in that shell.Running
# su - oliver --session-command bash
gives a shell without printing the warning, and job control indeed works.The suggestion to use
--session-command
comes from Starting a shell from scripts using su results in "no job control in this shell" which states "[a security fix for su] changed the behavior of the -c option and disables job control inside the called shell".But I still don't quite understand this. When should one use
--command
and when should one use--session-command
? Is--command
(aka-c
) more secure? Or should one always use--session-command
, and--command
is just left in for backwards compatibility?FWIW, I'm using RHEL 6.4.
-
Barmar almost 10 yearsI wonder why you're getting a non-interactive shell in the first case. The bash documentation says it starts an interactive shell when you don't give any filename arguments, don't give the
-c
option, and stdin and stderr are both connected to terminals. What are you doing that you didn't show? -
oliver almost 10 years@Barmar: I think in both cases I do get an interactive shell, at least according to tldp.org/LDP/abs/html/intandnonint.html; it's just that the first shell has no job control.
-
-
iSee almost 10 yearsScientific Linux 6.0 (EL6 compatible) has
--session-command
in the su(1) man page. It's also in this man page. -
Nathan C almost 10 yearsAh good...weird that I couldn't just find it. In any case, i'd just use
-c
in any case. It's well-supported and the command's even listed as "discouraged". -
oliver almost 10 yearsHuh - "discouraged" sounds bad. I can see that in the man7.org link, but the man page on my system looks more like the one at unixhelp.ed.ac.uk/CGI/man-cgi?su and explains
--session-command
like this: "pass a single COMMAND to the shell with -c and do not create a new session". From which I still don't understand when to use this option and when to use-c
. -
Nathan C almost 10 yearsThe no "session" means you have no shell variables or anything of the sort...you're literally just calling whatever shell the user has by default and executing the command as them. It's dangerous because the lack of environment variables may cause programs to do weird things...
-
oliver almost 10 yearsJust a side note: according to openwall.com/lists/oss-security/2011/06/15/4 there are several versions of
su
available; at least Ubuntu seems to use the one from shadow-utils, while the /bin/su on my RHEL6.4 system is provided by coreutils-8.4-19.el6.x86_64. -
iSee almost 10 yearsAnd on Fedora 20 su is part of util-linux.
-
oliver almost 10 yearsSo if I understand this correctly,
--command
will create a new session, which is more secure as the executed command no longer has access to the old session (but removes access to the terminal)? And--session-command
will execute the new command in the old session, which gives it access to the terminal, which is necessary for job control but might also open up security holes? -
oliver almost 10 yearsWell in my use case I want to have a single "command wrapper" binary which allows to run non-interactive as well as interactive commands, so
--session-command
might be a good compromise here. For a more secure system I probably should have two distinct command wrappers: one for starting interactive shells (using--shell
) and one for starting non-interactive commands (using--command
).