[Toybox] Upgrades to su command.

enh enh at google.com
Wed Feb 20 18:22:28 PST 2019


On Wed, Feb 20, 2019 at 10:54 AM Rob Landley <rob at landley.net> wrote:
>
> This came up recently:
>
>   https://github.com/landley/toybox/issues/117#issuecomment-465610332
>
> And it's been on my todo list forever: if you want to run a command as an
> arbitrary UID/GID, it's kinda awkward to do so with sudo or su because both
> conventionally want to look up a name out of /etc/passwd, and will error out on
> a uid with no passwd entry even for root. But these days with things like
> containers, there's lots of interesting UIDs and GIDs that aren't active in
> /etc/passwd. (And then there's the whole android thing of not having an
> /etc/passwd and using their version of the Windows Registry instead, because
> keeping system information in human readable text files is too unixy or
> something....)
>
> So anyway, I want su -u UID and su -g GID[,gid,gid...] to work, at least for
> root. And I want to be able to run an arbitrary command line without necessarily
> having to wash it through a random command shell. And _implementing this is
> fairly straightforward. No the hard part is writing the help text to explain it,
> especially if I've kept compatibility with the original su behavior.
>
> A word on the legacy su behavior: way back when setting a user's shell in
> /etc/passwd to /bin/false or /dev/null was a way of preventing anybody from
> running commands as that user. Then su grew -s to override which shell you were
> running as, so this stopped working from a security standpoint. (Besides, if you
> were running as root you could whip up a trivial C program to do it anyway, but
> the point was _su_ no longer enforced it.) And it let you specify -c to pass a
> command line to that shell so su could "run a command as a user" instead of
> being interactive, so this ability is already _there_ for most users, just
> awkward to use.
>
> Here's the new help text I've got so far. Is it intelligible?
>
>   usage: su [-lmp] [-u UID] [-g GID,...] [-s SHELL] [-c CMD] [USER [COMMAND...]]
>
>   Switch user, prompting for password of new user when not run as root.
>
>   With one argument, switch to USER and run user's shell from /etc/passwd.
>   With no arguments, USER is root. If COMMAND line provided after USER,
>   exec() it as new USER (bypasing shell). If -u or -g specified, first
>   argument (if any) isn't USER (it's COMMAND).
>
>   first argument is USER name to switch to (which must exist).
>   Non-root users are prompted for new user's password.
>
>   -s  Shell to use (default is user's shell from /etc/passwd)
>   -c  Command line to pass to -s shell (ala sh -c "CMD")
>   -l  Reset environment as if new login.
>   -u  Switch to UID instead of USER
>   -g  Switch to GID (only root allowed, can be comma separated list)
>   -p  Preserve environment

isn't the awkwardness of writing this why sudo(1) is separate from su(1)?

(ignoring the fact that they then added so much to sudo that it now
suffers from a similar problem.)

if you are doing this in toybox su, would it be simpler to just accept
that USER is a special case and not have -u? making the instructions
simpler seems worthwhile even if the historical cruft makes this
inherently unappealing aethetically.

> One other thing... I've been pondering a "contain" command for a long time that
> combines unshare, nsenter, chroot (really pivot_root because
> http://lkml.iu.edu/hypermail/linux/kernel/1310.0/02823.html), uid/gid range
> remapping, su, and possibly oneit or similar. (How you marshall
> stdin/stdout/stderr out of the container and into something the host can see is
> sort of a pty problem requiring a host daemon to monitor the container. And what
> _does_ happen to dmesg, anyway? I forget...)

yeah, that would be useful for testing toybox, if nothing else :-)

on Android su is (a) already taken (b) different yet again. you might
be interested to see our awful hack, also for historical reasons
(getopt being annoying enough that all tools start with ad hoc shit
and then it's hard to beat sense into them when they start growing
"real" options):

  $ adb shell su --help
  usage: su [UID[,GID[,GID2]...]] [COMMAND [ARG...]]

  Switch to WHO (default 'root') and run the given command (default sh).

  where WHO is a comma-separated list of user, group,
  and supplementary groups in that order.

(that would make more sense if the usage: line said WHO instead of
[UID[,GID[,GID2]...]] --- i should fix that at least...)

> It's probably still worth upgrading su anyway, but there _is_ no
> contain-equivalent pipeline that doesn't have circular dependencies in the order
> the commands need to run, and then your init binary needs to do setup _in_ the
> new namespace which with chroot means you need a binary in the new chroot that's
> really all about the host, not the chroot. Static qemu application mode that
> can't do it's own chroot had this problem too, which is why I submitted a patch
> to it many moons ago...
>
> Rob
>
> P.S. https://twitter.com/__apf__/status/1098265272782184448
> _______________________________________________
> Toybox mailing list
> Toybox at lists.landley.net
> http://lists.landley.net/listinfo.cgi/toybox-landley.net



More information about the Toybox mailing list