|
|
Subscribe / Log in / New account

Unprivileged chroot()

Unprivileged chroot()

Posted Mar 16, 2021 0:50 UTC (Tue) by geofft (subscriber, #59789)
Parent article: Unprivileged chroot()

Unprivileged chroot, I think, was one of the original motivations for PR_SET_NO_NEW_PRIVS back in the day.

Anyway, there's one advantage of direct unprivileged chroot over making an unprivileged user + mount namespace and calling chroot inside there: you retain a full UID map of the outside system. If you use "unshare -cm --keep-caps," you get to map a single UID, your own, and so things like "ls -l /bin" don't display the results you'd expect. Since unprivileged chroot wouldn't create a user namespace, things would still look normal.

Maybe this could be worked around by saying something like, if you're inside a user namespace, you have no capabilities, and you map to the same UID outside the namespace, and you call PR_SET_NO_NEW_PRIVS, you get the ability to write an identity map to uid_map and gid_map, even if they've already been written to. After all, in no new privs mode, you can't switch users or gain any capabilities, so it doesn't matter what UID mapping you see. But it seems extremely tricky to get the detail of that right and you'd probably introduce exploitable bugs the first few times you try.

(I don't believe CAP_SYS_CHROOT is a meaningful alternative here. How would you grant it? Would you give filesystem capabilities to the chroot command? It won't be enforcing the NO_NEW_PRIVS requirement, then, and will turn into an immediate local root escalation. It _can't_ enforce that requirement, in fact: if you run a setcap program under NO_NEW_PRIVS, those capabilities are ignored, specifically because you asked for no new privs! So it wouldn't work if run from a no-new-privs parent process. If you somehow could avoid that constraint and run a setcap chroot, you could call it twice, the second time with a modified /lib thanks to being able to modify your chroot, and you could use that to escape the first chroot and hold onto chrooting privileges. It is technically true that CAP_SYS_CHROOT is the best example of how the capability mechanism is supposed to work - it's a fantastic demonstration of how useless that mechanism is.)


to post comments

Unprivileged chroot()

Posted Mar 18, 2021 9:14 UTC (Thu) by matthias (subscriber, #94967) [Link] (3 responses)

Would it be possible to create a chroot command that has CAP_SYS_CHROOT filesystem capabilities, does the chroot, drops CAP_SYS_CHROOT and sets NO_NEW_PRIVS before calling the supplied command?

Unprivileged chroot()

Posted Mar 18, 2021 12:26 UTC (Thu) by winstonx86 (subscriber, #138536) [Link]

Yes but I suppose you couldn’t perform a second chroot because of the NO_NEW_PRIVS

Unprivileged chroot()

Posted Mar 18, 2021 16:54 UTC (Thu) by floppus (guest, #137245) [Link] (1 responses)

It's dangerous to allow that if the process is already chrooted, since it lets you escape from the outer chroot.

For that reason (I think), unprivileged processes can't create user namespaces when they're already chrooted, and the proposed unprivileged chroot would likewise be forbidden.

Unprivileged chroot()

Posted Mar 18, 2021 17:05 UTC (Thu) by matthias (subscriber, #94967) [Link]

Yes, my suggestion was to use the modified chroot command as an alternative to unprivileged chroot() syscall. And it was not meant to be used repeatedly. Obviously, it cannot be used repeatedly as after one execution NO_NEW_PRIVS is set and the CAP_CHROOT filesystem capability will have no effect.

And of course, if someone chroots a process without NO_NEW_PRIVS in a classic way, there should be no enchanted chroot command that gets capabilities from the filesystem laying around inside the new root.


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds