logoalt Hacker News

Joker_vDtoday at 8:43 AM1 replyview on HN

> The root cause is not thinking: Why is root chrooting into a directory they do not control?

Because you can't call chroot(2) unless you're root. And "control a directory" is weasel words; root technically controls everything in one sense of the word. It can also gain full control (in a slightly different sense of the word) over a directory: kill every single process that's owned by the owner of that directory, then don't setuid into that user in this process and in any other process that the root currently executes, or will execute, until you're done with this directory. But that's just not useful for actual use, isn't it?

Secure things should be simple to do, and potentially unsafe things should be possible.


Replies

geocartoday at 10:22 AM

> And "control a directory" is weasel words;

I did not choose the term to confuse you, that's from the definition document linked to the CVE:

https://cwe.mitre.org/data/definitions/426.html

The CVE itself uses the language "If the NEWROOT is writable by an attacker" which could refer to a shared library (as indicated in the report), or even a passwd file as would have been true since the origin of chroot()

> root technically controls everything in one sense of the word.

But not the sense we're talking about.

> Because you can't call chroot(2) unless you're root

Well you can[1], but this is /usr/sbin/chroot aka chroot(8) when used with a non-numeric --userspec, and the point is to drop root to a user that root controls with setuid(2). Something needs to map user names to the numeric userids that setuid(2) uses, and that something is typically the NSS database.

Now: Which database should be used to map a username to a userid?

- The one from before the chroot(2)?

- Or the one that you're chroot(2)ing into

If you're the author of the code in-question, you chose the latter, and that is totally obvious to anyone who can read because that's the order the code appears in, but it's also obvious that only the first one* is under control of root, and so only the first one could be correct.

[1]: if you're curious: unshare(CLONE_USERNS|CLONE_FS) can be used. this is part of how rootless containers work.

show 1 reply