"Cannot set terminal process group" during su to another user as login shell

35,364

Solution 1

  • su - username is interpreted by your su to mean "run username's shell as an interactive login shell"
  • su username - is interpreted by your su to mean "run the following non-interactive command (-) as username"
  • the latter only worked at all because:
    • your su passes trailing arguments to sh for parsing
    • sh takes - to mean "run as a login shell (read /etc/profile, ...)"

But what you're really interested in is: why non-interactive? Sharing the controlling terminal between the privileged parent and the unprivileged child leaves you vulnerable to "TTY pushback privilege escalation", aka the TIOCSTI bug, so unless you really need it su detaches from it. When you used the su username - form, su inferred that you didn't need a controlling terminal.

Only processes with a controlling terminal can have session leaders which manipulate process groups (do job control); the trace you gave is bash detecting that it can't be a session leader.

You mention:

Where it gets stranger is that both forms work fine on Ubuntu and CentOS 6, however on vanilla Debian, only the first form works without error.

Ignoring variants like sux and sudo, there are at least three[1] versions of su on Linux: coreutils, util-linux and shadow-utils from which Debian's comes. The latter's manpage points out:

This version of su has many compilation options, only some of which may be in use at any particular site.

and Debian's comes with the flag old_debian_behavior; other versions may have similar compile-time/runtime options. Another reason for variability might be that there was some debate[2] as to whether su should ever be used to drop privilege this way and whether the TIOCSTI bug is therefore a bug at all (Redhat originally closed it "WONTFIX").

[1]: Edit: add SimplePAMApps and hardened-shadow to that.

[2]: Solar Designer has some (old) opinions there which I think are worth a read.

Solution 2

I would check the ownership and permissions on /dev/pts* or for a new configuration for udev related to /dev/pts devices, that was not replaced during the upgrade process.

You can also try to find out what syscal is generating the error by running as root:

strace -f su - username 2>stderr.log
Share:
35,364

Related videos on Youtube

Mikey T.K.
Author by

Mikey T.K.

I'm a systems admin by day, and a coder and gamer by night. I tend to float between small project to small project, wherever my ADD-addled mind takes me. Especially if it's ruby-based. So basically, I'm the stereotype of almost every full-time-employed-yet-not-at-a-startup hacker out there :)

Updated on September 18, 2022

Comments

  • Mikey T.K.
    Mikey T.K. over 1 year

    Note: Please read the updated information starting with "EDIT" near the halfway point of this post - the environment and background of this problem has changed

    I've got a bog standard Debian 6.0 install here that I decided to sidegrade to the Debian Testing repositories. I did this by swapping out the references to the Squeeze repos in my sources.list to use the Testing repos instead.

    After the package install and a reboot, I get the following error when attempting to su - to another user:

    root@skaia:~# su joebloggs -
    bash: cannot set terminal process group (-1): Inappropriate ioctl for device
    bash: no job control in this shell
    

    If I omit the -, this does not occur.

    Note that users can become root correctly, this only seems to happen when switching from root to somebody else and using the - to get that user's environment.

    Google is mostly useless here. The only things I can find are references from 2011 in regards to the sux package, which appear to have been fixed in the mean time.

    This looks and smells very much like an upgrade error, fixable by tweaking the right package in the right manner. I just have no idea where to start - aside from this, my system works completely normally and as expected.

    EDIT

    This is now happening to me on a Debian stable machine as described above. No upgrade or anything this time, just straight up stable.

    Yup, a year later. Still no idea what the heck the problem is.

    Here's what it looks like now (not much has changed):

    bash: cannot set terminal process group (-1): Inappropriate ioctl for device
    bash: no job control in this shell
    terraria@skaianet:~$ tty
    /dev/pts/0
    terraria@skaianet:~$ ls -l /dev/pts/0
    crw--w---- 1 root root 136, 0 Oct 10 19:21 /dev/pts/0
    terraria@skaianet:~$ ls -l /dev/pts/
    crw--w---- 1 root root 136, 0 Oct 10 19:21 0
    crw--w---- 1 root root 136, 2 Sep 22 17:47 2
    crw--w---- 1 root root 136, 3 Sep 26 19:30 3
    c--------- 1 root root   5, 2 Sep  7 10:50 ptmx
    

    An strace generated like this:

    root@skaianet:~$ strace -f -o tracelog su terraria -
    

    ..also turns up some confusing behavior. These messages are rather confusing. Some chosen lines:

    readlink("/proc/self/fd/0", "/dev/pts/0", 4095) = 10
    #Error code 10? 
    15503 open("/dev/tty", O_RDWR|O_NONBLOCK) = -1 ENXIO (No such device or address)
    #Yes there is, and I can interact with it normally
    15503 ioctl(255, TIOCGPGRP, [32561])    = -1 ENOTTY (Inappropriate ioctl for device)
    

    I've linked the full output of this strace session - all I did was run the su command, then immediately ctrl+d out of the terminal.

    • Mircea Vutcovici
      Mircea Vutcovici almost 12 years
      Hi Mike. Have you found the problem?
  • Alan Curry
    Alan Curry almost 12 years
    Better add -f to that strace, in case su decides to run the shell as a subprocess, which seems to be common now. The syscall for setting a terminal's foreground process group is ioctl(..., TIOCSPGRP, ...) and we already know it failed with ENOTTY (Inappropriate ioctl for device) so that part of the strace won't help much. But an strace of both versions of the command (with and without -) could be compared to find out why the TIOCSPGRP fails.
  • Mikey T.K.
    Mikey T.K. almost 12 years
    That looks like a promising lead. Looking in my /dev/pts folder, there are precisely two items, namely 0, permissions set as 600 owned by the user I logged in as, and a ptmx owned by root, with zero permissions.
  • Alan Curry
    Alan Curry almost 12 years
    When you get the shell prompt after the No job control message, run the command tty and it will tell you which tty you're on. Then ls -l it.
  • Mikey T.K.
    Mikey T.K. over 10 years
    @AlanCurry - it came back. I've updated the original question with the information Mircea suggested.
  • Mircea Vutcovici
    Mircea Vutcovici over 10 years
    I think it is a bug in su. See this bug report: bugs.debian.org/cgi-bin/bugreport.cgi?bug=663200
  • Mircea Vutcovici
    Mircea Vutcovici over 10 years
    Try the same command with sudo as a workaround.
  • Mikey T.K.
    Mikey T.K. almost 10 years
    That is an excellent answer and best of all it exactly explains why. I wish you'd been here a year ago :)