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