On Sat, Mar 11, 2017 at 05:02:14AM +0000, Kristaps Dzonsons wrote:
> In running risky non-root applications, it'd be great to chroot(2)
> without needing to be root.  But the manpage says no.  So I added a
> system call, uchroot(2), that does the following:
>  (1) performs the change-root w/o checking for root
>  (2) disables setuid (flag is inherited)
> The (2) plugs the hole wherein a non-root normal chroot could allow for
> privilege escalation by a cooked master.passwd and setuid.
> Enclosed is a patch.  (Without the bits generated from make syscalls: I
> don't know whether that's preferred.  Also doesn't include the libc
> parts.)  It can't be this easy, can it?  What did I miss?

fd tables can be shared between processes (see FORK_SHAREFILES). So in
particular if one process uchroots and another one performs execve, the
execve is done against the chroot while "ignore suid" is not set.

While this bit is easily fixable I think this is too hairy in general
and the feature is unnecessary for the intended purpose.

> My initial motivation is CGI scripts, which can and do pledge, yes, but
> I'd like to limit *path-pledged processes to a directory so scripts
> can't read everything else in /var/www.  For example, within /var/www,
> to (say) /vhosts/foo.com.

I think the way to go is "will only use lookups against a file
descriptor" pledge. Nice added value is that programs can now use
different places in the tree with directory granulalrity as opposed to
having to chroot to the common parent.

This poses a problem with confining ".." lookups.  There is a hack in
FreeBSD to explicitly track them, but perhaps you will be fine enough
with disallowing ".."s in the first place.

Mateusz Guzik <mjguzik gmail.com>

Reply via email to