What is the difference between "su --command" and "su --session-command"?

6,269

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.

Share:
6,269

Related videos on Youtube

oliver
Author by

oliver

Updated on September 18, 2022

Comments

  • oliver
    oliver over 1 year

    Running # su - oliver --command bash gives a shell but also prints the warning bash: no job control in this shell, and indeed Ctrl+Z and fg/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
      Barmar almost 10 years
      I 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
      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
    iSee almost 10 years
    Scientific Linux 6.0 (EL6 compatible) has --session-command in the su(1) man page. It's also in this man page.
  • Nathan C
    Nathan C almost 10 years
    Ah 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
    oliver almost 10 years
    Huh - "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
    Nathan C almost 10 years
    The 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
    oliver almost 10 years
    Just 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
    iSee almost 10 years
    And on Fedora 20 su is part of util-linux.
  • oliver
    oliver almost 10 years
    So 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
    oliver almost 10 years
    Well 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).