2014-06-10
An irritating and interesting su
change from Ubuntu 12.04 to 14.04
In Ubuntu 12.04, the su
manpage describes the -c
option with this
minimal description:
- -c, --command COMMAND
- Specify a command that will be invoked by the shell using its -c [option].
In Ubuntu 14.04, the following note was added as well:
The executed command will have no controlling terminal. This option cannot be used to execute interactive programs which need a controlling TTY.
This change broke part of my customary environment. For years I
have been su'ing to root but running an alternate shell once I got there by actually
doing '/bin/su -c "exec $myshell"'
(generally this incantation
is hiding behind other scripts). On the
traditional su
, as found on 12.04 and previous LTS releases as
well as on, eg, Fedora, this works fine. On 14.04 my shell started
spitting out errors about 'tcsetgrp: Inappropriate ioctl for device
'
(probably because my shell has readline support these days) and bash complained:
bash: cannot set terminal process group (14684): Inappropriate ioctl for device bash: no job control in this shell
Contrary to what the manpage says, interactive programs do not actually fail. Pretty much everything runs fine, except of course there's no job control and my shell whined incessantly; the former doesn't bother me since I don't use it anyway, but the latter was rather annoying.
That's the irritating part. The interesting part is why this change
was made, because it turns out not to be an arbitrary one; instead
it's actually sort of a security fix. In Ubuntu, su
comes from
the shadow
package, which in May of 2012 was updated to a new
upstream version that included the following change (from the
Ubuntu changelog):
- su: Fix possible tty hijacking by dropping the controlling terminal when executing a command (CVE-2005-4890). Closes: #628843
A longer description of the problem CVE-2005-4890 is about is here,
with links to various discussions of the issue. This writeup notes
that a number of people don't think that this is a bug and are not
fixing it. This includes some Linux distributions and also some
upstream authors of versions of su
.
(That's right, Linux has multiple versions of su
. Fedora 20 uses the
util-linux version, for example, and neither Fedora nor the upstream
has changed su
to fix this CVE's issue.)
On the one hand I can't exactly blame the upstream 'shadow' maintainers
for fixing this; it is a possible security issue. On the other hand
it is a change to long-standing behavior in order to fix what is
very likely to be an extremely rare vulnerability and it doesn't
even apply in this situation (since I am su
'ing to root, not away
from it). So on the whole I selfishly wish that they hadn't changed
the behavior of 'su -c
', at least for people su'ing to root.
Fortunately the fix is easy. I just need to use '/bin/su -s
$myshell
' instead of my old incantation. Unfortunately this is
slightly less portable as the -s
option is not present on things
like Solaris (well, OmniOS) while -c
goes back to the mists of
time.
(I only discovered that this was a CVE fix when I started writing this entry and decided to dig into the exact versions involved, read the changelogs, and so on so that I could write an informed entry. Once again blogging has proved educational.)