== The somewhat surprising history of _chroot()_ The _chroot()_ system call is one of those that I think of as being really old. Up until [[a while back https://twitter.com/thatcks/status/623873713298124800]], if you'd pressed me I'd have guessed that it originated in V7. Then I dug into it and in that tweet claimed it was from 4.2 BSD. This is what you'd kind of expect and what it sort of looks like, but it turns out to be wrong and the history of _chroot()_ seems to be much more interesting than I expected. The classic use of _chroot()_ is for safely confining network daemons, and indeed this is what _ftpd_ uses it for in 4.2 BSD. But there's another use of it in the 4.2 BSD tree lurking in a file called [[/usr/src/games/compat/runcompat.c http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.2BSD/usr/src/games/compat/runcompat.c]]. As [[a manpage http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.2BSD/usr/src/games/compat/v6run.1]] and [[a Readme http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.2BSD/usr/src/games/compat/Readme]] there make clear, this is a system to let you run PDP-11 V6 and V7 programs on your VAX. It uses _chroot()_ to optionally put those programs inside a familiar V6 or V7 directory hierarchy. This appears to go more or less all the way back to [[32V https://en.wikipedia.org/wiki/UNIX/32V]], the first Unix version to run on a VAX and thus the first one where this desire would come up. But it's not where _chroot(2)_ was added. Much to my surprise, it turns out that _chroot(2)_ is in V7 after all. It's not obvious because there's no separate manpage for it; instead it's part of the [[_chdir(2)_ manpage http://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/man/man2/chdir.2]]. I don't know why it's there, apart from 'someone thought it was an obvious feature'; tuhs.org has more or less complete V7 source, and there's no programs in the source tree that use it that I can find. Apparently it was added first and then people found various uses for it later. What we now think of as its most prominent uses (for things like confining anonymous ftp) are relatively latecomers to the game, since they started years after _chroot()_ itself came into existence. (I don't believe that the V7 _chroot()_ was a security measure.) === Sidebar: why chroot is in the chdir manpage V7 implements _chdir(2)_ and _chroot(2)_ with basically the same code; you can see it in [[/usr/sys/sys/sys4.c http://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/sys/sys/sys4.c]]. It's pretty clever: .pn prewrap on chdir() { chdirec(&u.u_cdir); } chroot() { if (suser()) chdirec(&u.u_rdir); } chdirec(ipp) register struct inode **ipp; { [...] In other words, the only real difference between chdir and chroot is what field in the _u_ user structure they act on. chdir acts on the 'current directory' field, chroot acts on the 'root directory' field. The actual implementation of chroot requires a bit more kernel code than this, because of course the ((u_rdir)) field didn't exist before chroot was added. But there turn out to be remarkably few places that deal with ((u_rdir)) in the V7 kernel. By the way, reading this code makes me suspect that a V7 chroot was remarkably permeable; I don't see any reason why you can't just '_cd .._' your way right out of one (although I may be missing something subtle in the code). That obviously changed later. (Note that the V7 manpage doesn't claim that chroot() confines processes; it simply says that it changes what '_/_' means to them. Which is literally what the kernel code does.)