Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / share / doc / papers / jail / implementation.ms
1 .\"
2 .\" $FreeBSD: src/share/doc/papers/jail/implementation.ms,v 1.1.2.1 2000/08/20 13:16:44 mpp Exp $
3 .\" $DragonFly: src/share/doc/papers/jail/implementation.ms,v 1.2 2003/06/17 04:36:56 dillon Exp $
4 .\"
5 .NH
6 Implementation jail in the FreeBSD kernel.
7 .NH 2
8 The jail(2) system call, allocation, refcounting and deallocation of
9 \fCstruct prison\fP.
10 .PP
11 The jail(2) system call is implemented as a non-optional system call
12 in FreeBSD.  Other system calls are controlled by compile time options
13 in the kernel configuration file, but due to the minute footprint of
14 the jail implementation, it was decided to make it a standard
15 facility in FreeBSD.
16 .PP
17 The implementation of the system call is straightforward:  a data structure
18 is allocated and populated with the arguments provided.  The data structure
19 is attached to the current process' \fCstruct proc\fP, its reference count
20 set to one and a call to the
21 chroot(2) syscall implementation completes the task.
22 .PP
23 Hooks in the code implementing process creation and destruction maintains
24 the reference count on the data structure and free it when the last reference
25 is lost.
26 Any new process created by a process in a jail will inherit a reference
27 to the jail, which effectively puts the new process in the same jail.
28 .PP
29 There is no way to modify the contents of the data structure describing
30 the jail after its creation, and no way to attach a process to an existing
31 jail if it was not created from the inside that jail.
32 .NH 2
33 Fortification of the chroot(2) facility for filesystem name scoping.
34 .PP
35 A number of ways to escape the confines of a chroot(2)-created subscope
36 of the filesystem view have been identified over the years.
37 chroot(2) was never intended to be security mechanism as such, but even
38 then the ftp daemon largely depended on the security provided by
39 chroot(2) to provide the ``anonymous ftp'' access method.
40 .PP
41 Three classes of escape routes existed: recursive chroot(2) escapes,
42 ``..'' based escapes and fchdir(2) based escapes.
43 All of these exploited the fact that chroot(2) didn't try sufficiently
44 hard to enforce the new root directory.
45 .PP
46 New code were added to detect and thwart these escapes, amongst
47 other things by tracking the directory of the first level of chroot(2)
48 experienced by a process and refusing backwards traversal across
49 this directory, as well as additional code to refuse chroot(2) if
50 file-descriptors were open referencing directories.
51 .NH 2
52 Restriction of process visibility and interaction.
53 .PP
54 A macro was already in available in the kernel to determine if one process
55 could affect another process.  This macro did the rather complex checking
56 of uid and gid values.  It was felt that the complexity of the macro were
57 approaching the lower edge of IOCCC entrance criteria, and it was therefore
58 converted to a proper function named \fCp_trespass(p1, p2)\fP which does
59 all the previous checks and additionally checks the jail aspect of the access.
60 The check is implemented such that access fails if the origin process is jailed
61 but the target process is not in the same jail.
62 .PP
63 Process visibility is provided through two mechanisms in FreeBSD,
64 the \fCprocfs\fP file system and a sub-tree of the \fCsysctl\fP tree.
65 Both of these were modified to report only the processes in the same
66 jail to a jailed process.
67 .NH 2
68 Restriction to one IP number.
69 .PP
70 Restricting TCP and UDP access to just one IP number was done almost
71 entirely in the code which manages ``protocol control blocks''.
72 When a jailed process binds to a socket, the IP number provided by
73 the process will not be used, instead the pre-configured IP number of
74 the jail is used.
75 .PP
76 BSD based TCP/IP network stacks sport a special interface, the loop-back
77 interface, which has the ``magic'' IP number 127.0.0.1.
78 This is often used by processes to contact servers on the local machine,
79 and consequently special handling for jails were needed.
80 To handle this case it was necessary to also intercept and modify the
81 behaviour of connection establishment, and when the 127.0.0.1 address
82 were seen from a jailed process, substitute the jails configured IP number.
83 .PP
84 Finally the APIs through which the network configuration and connection
85 state may be queried were modified to report only information relevant
86 to the configured IP number of a jailed process.
87 .NH 2
88 Adding jail awareness to selected device drivers.
89 .PP
90 A couple of device drivers needed to be taught about jails, the ``pty''
91 driver is one of them.  The pty driver provides ``virtual terminals'' to
92 services like telnet, ssh, rlogin and X11 terminal window programs.
93 Therefore jails need access to the pty driver, and code had to be added
94 to enforce that a particular virtual terminal were not accessed from more
95 than one jail at the same time.
96 .NH 2
97 General restriction of super-users powers for jailed super-users.
98 .PP
99 This item proved to be the simplest but most tedious to implement.
100 Tedious because a manual review of all places where the kernel allowed
101 the super user special powers were called for,
102 simple because very few places were required to let a jailed root through.
103 Of the approximately 260 checks in the FreeBSD 4.0 kernel, only
104 about 35 will let a jailed root through.
105 .PP
106 Since the default is for jailed roots to not receive privilege, new
107 code or drivers in the FreeBSD kernel are automatically jail-aware: they
108 will refuse jailed roots privilege.
109 The other part of this protection comes from the fact that a jailed
110 root cannot create new device nodes with the mknod(2) systemcall, so
111 unless the machine administrator creates device nodes for a particular
112 device inside the jails filesystem tree, the driver in effect does
113 not exist in the jail.
114 .PP
115 As a side-effect of this work the suser(9) API were cleaned up and
116 extended to cater for not only the jail facility, but also to make room
117 for future partitioning facilities.
118 .NH 2
119 Implementation statistics
120 .PP
121 The change of the suser(9) API modified approx 350 source lines
122 distributed over approx. 100 source files.  The vast majority of 
123 these changes were generated automatically with a script.
124 .PP
125 The implementation of the jail facility added approx 200 lines of
126 code in total, distributed over approx. 50 files.  and about 200 lines
127 in two new kernel files.