5 ms·
Chw00t: Breaking Unix chroot Solutions (2015) [video]
- clarry 10y agochroot is a very simple facility that can provide meaningful security. So yes, it can be used as a security feature. People just need to understand its limitations. No, it won't prevent kernel exploits. Yes, root can escape it (1996 called? http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/sys/chroot.2.diff?r1=1.2&r2=1.3 http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/sys/ch... ) It's not going to protect you from a malicious or vulnerable process running as root; you're already rooted. So once you leave out the exploits that require root, you're mostly left with the issue of ptrace, unless you also have another malicious process running on your system. Even if it ptrace couldn't help a process out of a chroot, it is still a big risk, so use good privsep hygiene (no shared UIDs outside the chroot), or disable it entirely, if it's not needed. Worth noting, OpenBSD defaults to disallowing global ptrace, i.e. you can only trace child processes, such as those started by gdb.
- shshhdhs 10y agoI appreciate the depth of the commentary here (one of the reasons why I keep coming back to HN). Where would you encourage me to read more about best practices like you've just described?
- nine_k 10y agoWhat is the next, light-weight but more hardened solution after chroot? On *BSD, it's probably `jail`. On Linux, it's probably runC?
- wahern 10y agoOnly FreeBSD has jails, but it's not quite the same thing. Jails are more like containers. The evolution of the chroot concept on OpenBSD is pledge. On Linux it's seccomp. runC creates Linux containers. Containers and VMs are not security solutions, rather system administration and provisioning solutions. chroot() was originally implemented as a type of container. It allowed you to run programs (especially before the adoption of dynamic linking) from a private directory tree when building, installing, and testing software, without risking overwriting the real system. Basically, it's purpose was just like Docker. But the use of chroot() as a security solution is different. You don't usually mount /dev or /proc in a chroot jail as that would defeat the purpose. The purpose is reducing the code surface of kernel and other privileged code available to software that might be abused to tickle bugs and elevate privileges. Containers don't reduce code surface area at all, not to the kernel, nor usually to stock SUID and SGID binaries. All the same devices files _and_ system calls are still available, as well as typical SUID account and system management binaries. It might have security related benefits in the sense that you can, e.g., remove application-specific SUID binaries from some containers but not others. But that's no different than chroot, and so it's not really an improvement over chroot in that sense. More importantly, the code implementing Linux containers is complex and has opened up far more kernel bugs than it's closed. There are good reasons why most kernel developers, including even Linus for long time, resisted attempts to expand the chroot namespace model. In terms of security you'd be better off recompiling your Linux kernel without all the container namespace code. VMs seem better security-wise until you realize a VM's interface to the host kernel is through device drivers. And the device driver model of monolithic Unix kernels is a security nightmare. Ironically, it wasn't until VMs came out that hackers had such easy and broad access to manipulating device driver code on the host. Unix's "everything is a file" approach always limited that ability. Where that approach broke down, like with ioctl, was always a hotbed of exploits. Blackhats haven't had much trouble taking control of host kernels from guest VMs, although because that path is less well-trodden it's not something script kiddies are typically capable of. As VMs get simpler and move away from hardware and driver emulation, the security benefit of VMs will improve. But their utility as sandboxes for code you don't control will also be diminished. In many circumstances seccomp and pledge will remain the better option, especially from a developer's standpoint. Note that SELinux doesn't limit access to system calls, and only indirectly limits code surface by making it easier to restrict access to logical resource objects. SELinux wouldn't have prevented or hindered in any way the recent recvmmsg() remote root exploit Linux. It's function is quite different than pledge and seccomp. SELinux can be used in tandem with seccomp. But given the real-world threat model out there, if you were to only rely on one, then seccomp is far more valuable, IMO.
- cyphar 10y ago> Only FreeBSD has jails, but it's not quite the same thing. Jails are more like containers. The evolution of the chroot concept on OpenBSD is pledge. On Linux it's seccomp. > runC creates Linux containers. Containers and VMs are not security solutions, rather system administration and provisioning solutions. As someone who maintains runC, I disagree with you quite vehemently. Containers are a security system. Yes, they've had their fair share of problems but that doesn't mean that > chroot() was originally implemented as a type of container. It allowed you to run programs (especially before the adoption of dynamic linking) from a private directory tree when building, installing, and testing software, without risking overwriting the real system. Basically, it's purpose was just like Docker. That is a very narrow view of what the purpose of containers is. > But the use of chroot() as a security solution is different. You don't usually mount /dev or /proc in a chroot jail as that would defeat the purpose. That's not correct. Many programs require /proc, /dev or /sys to function. Most of the uses I've seen of chroot do mount stuff like that in the rootfs. If you're an unprivileged user you haven't really increased the attack surface. And even if you don't mount those filesystems, chroot doesn't namespace networking or process trees -- so those avenues of attack still exist. That _alone_ makes containers more secure than chroot. > Containers don't reduce code surface area at all, not to the kernel, nor usually to stock SUID and SGID binaries. All the same devices files _and_ system calls are still available, as well as typical SUID account and system management binaries. This is not necessarily true, given the existence of no_new_privs, seccomp and user namespaces in Linux. Not to mention that all of the runtimes I know of do not just mount /dev (instead it's a tmpfs with bindmounts for the devices needed by containers). And not to mention that chroot is just a weaker version of mount namespaces (which is a far more powerful primitive for isolating processes). > But that's no different than chroot, and so it's not really an improvement over chroot in that sense. More importantly, the code implementing Linux containers is complex and has opened up far more kernel bugs than it's closed. That's just FUD. Yes, the way Linux went about creating namespaces wasn't the best way, but modern Linux containers are more secure than chroot. Chroot doesn't even protect against messing around with other processes on your host system! It doesn't protect against accessing things outside of your current root (pivot_root actually fixes that problem -- but you can't use it without using mount namespaces).