View | Details | Raw Unified | Return to bug 108676
Collapse All | Expand All

(-)chapter.sgml (-189 / +237 lines)
Lines 1-7 Link Here
1
<!--
1
<!--
2
     The FreeBSD Documentation Project
2
     The FreeBSD Documentation Project
3
3
4
     $FreeBSD: doc/en_US.ISO8859-1/books/arch-handbook/jail/chapter.sgml,v 1.19 2007/01/31 14:22:22 delphij Exp $
4
     $FreeBSD: /repoman/r/dcvs/doc/en_US.ISO8859-1/books/arch-handbook/jail/chapter.sgml,v 1.19 2007/01/31 14:22:22 delphij Exp $
5
-->
5
-->
6
6
7
<chapter id="jail">
7
<chapter id="jail">
Lines 55-61 Link Here
55
    <para>
55
    <para>
56
      <application>Jail</application> consists of two realms: the
56
      <application>Jail</application> consists of two realms: the
57
      user-space program, jail, and the code implemented within the
57
      user-space program, jail, and the code implemented within the
58
      kernel: the <literal>jail()</literal> system call and associated
58
      kernel: the <literal>jail</literal> system call and associated
59
      restrictions. I will be discussing the user-space program and
59
      restrictions. I will be discussing the user-space program and
60
      then how jail is implemented within the kernel.</para>
60
      then how jail is implemented within the kernel.</para>
61
61
Lines 94-103 Link Here
94
          arguments passed to the jail program, and indeed, they are
94
          arguments passed to the jail program, and indeed, they are
95
          set during its execution.</para>
95
          set during its execution.</para>
96
96
97
        <programlisting><filename>/usr/src/usr.sbin/jail.c</filename>
97
        <programlisting><filename>/usr/src/usr.sbin/jail/jail.c</filename>
98
j.version = 0; 
98
char path[PATH_MAX];
99
j.path = argv[1];
99
...
100
j.hostname = argv[2];</programlisting>
100
if (realpath(argv[0], path) == NULL)
101
    err(1, "realpath: %s", argv[0]);
102
if (chdir(path) != 0)
103
    err(1, "chdir: %s", path);
104
memset(&amp;j, 0, sizeof(j));
105
j.version = 0;
106
j.path = path;
107
j.hostname = argv[1];</programlisting>
101
108
102
      </sect3>
109
      </sect3>
103
110
Lines 106-128 Link Here
106
113
107
        <para>One of the arguments passed to the Jail program is an IP
114
        <para>One of the arguments passed to the Jail program is an IP
108
          address with which the jail can be accessed over the
115
          address with which the jail can be accessed over the
109
          network. Jail translates the ip address given into network
116
          network. Jail translates the ip address given into host
110
          byte order and then stores it in j (the jail structure).</para>
117
          byte order and then stores it in j (the jail structure).</para>
111
118
112
        <programlisting><filename>/usr/src/usr.sbin/jail/jail.c</filename>:
119
        <programlisting><filename>/usr/src/usr.sbin/jail/jail.c</filename>:
113
struct in.addr in; 
120
struct in_addr in; 
114
... 
115
i = inet_aton(argv[3], <![CDATA[&in]]>); 
116
... 
121
... 
117
j.ip_number = ntohl(in.s.addr);</programlisting>
122
if (inet_aton(argv[2], &amp;in) == 0)
123
    errx(1, "Could not make sense of ip-number: %s", argv[2]);
124
j.ip_number = ntohl(in.s_addr);</programlisting>
118
125
119
        <para>The
126
        <para>The
120
          <citerefentry><refentrytitle>inet_aton</refentrytitle><manvolnum>3</manvolnum></citerefentry>
127
          <citerefentry><refentrytitle>inet_aton</refentrytitle>
128
          <manvolnum>3</manvolnum></citerefentry>
121
          function "interprets the specified character string as an
129
          function "interprets the specified character string as an
122
          Internet address, placing the address into the structure
130
          Internet address, placing the address into the structure
123
          provided." The ip number node in the jail structure is set
131
          provided." The ip number node in the jail structure is set
124
          only when the ip address placed onto the in structure by
132
          only when the ip address placed onto the in structure by
125
          inet aton is translated into network byte order by
133
          inet_aton is translated into host byte order by
126
          <function>ntohl()</function>.</para>
134
          <function>ntohl()</function>.</para>
127
135
128
      </sect3>
136
      </sect3>
Lines 132-144 Link Here
132
140
133
        <para>Finally, the userland program jails the process, and
141
        <para>Finally, the userland program jails the process, and
134
          executes the command specified. Jail now becomes an
142
          executes the command specified. Jail now becomes an
135
          imprisoned process itself and forks a child process which
143
          imprisoned process itself and then executes the command
136
          then executes the command given using &man.execv.3;</para>
144
          given using &man.execv.3;</para>
137
145
138
        <programlisting><filename>/usr/src/sys/usr.sbin/jail/jail.c</filename>
146
        <programlisting><filename>/usr/src/sys/usr.sbin/jail/jail.c</filename>
139
i = jail(<![CDATA[&j]]>); 
147
i = jail(&amp;j); 
140
... 
148
... 
141
i = execv(argv[4], argv + 4);</programlisting>
149
if (execv(argv[3], argv + 3) != 0)
150
    err(1, "execv: %s", argv[3]);</programlisting>
142
151
143
        <para>As you can see, the jail function is being called, and
152
        <para>As you can see, the jail function is being called, and
144
          its argument is the jail structure which has been filled
153
          its argument is the jail structure which has been filled
Lines 171-203 Link Here
171
180
172
int     jail_set_hostname_allowed = 1;
181
int     jail_set_hostname_allowed = 1;
173
SYSCTL_INT(_security_jail, OID_AUTO, set_hostname_allowed, CTLFLAG_RW,
182
SYSCTL_INT(_security_jail, OID_AUTO, set_hostname_allowed, CTLFLAG_RW,
174
    <![CDATA[&jail]]>_set_hostname_allowed, 0,
183
    &amp;jail_set_hostname_allowed, 0,
175
    "Processes in jail can set their hostnames");
184
    "Processes in jail can set their hostnames");
176
185
177
int     jail_socket_unixiproute_only = 1;
186
int     jail_socket_unixiproute_only = 1;
178
SYSCTL_INT(_security_jail, OID_AUTO, socket_unixiproute_only, CTLFLAG_RW,
187
SYSCTL_INT(_security_jail, OID_AUTO, socket_unixiproute_only, CTLFLAG_RW,
179
    <![CDATA[&jail]]>_socket_unixiproute_only, 0,
188
    &amp;jail_socket_unixiproute_only, 0,
180
    "Processes in jail are limited to creating &unix;/IPv4/route sockets only
189
    "Processes in jail are limited to creating &unix;/IPv4/route sockets only");
181
");
182
190
183
int     jail_sysvipc_allowed = 0;
191
int     jail_sysvipc_allowed = 0;
184
SYSCTL_INT(_security_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW,
192
SYSCTL_INT(_security_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW,
185
    <![CDATA[&jail]]>_sysvipc_allowed, 0,
193
    &amp;jail_sysvipc_allowed, 0,
186
    "Processes in jail can use System V IPC primitives");
194
    "Processes in jail can use System V IPC primitives");
187
195
188
static int jail_enforce_statfs = 2;
196
static int jail_enforce_statfs = 2;
189
SYSCTL_INT(_security_jail, OID_AUTO, enforce_statfs, CTLFLAG_RW,
197
SYSCTL_INT(_security_jail, OID_AUTO, enforce_statfs, CTLFLAG_RW,
190
    <![CDATA[&jail]]>_enforce_statfs, 0,
198
    &amp;jail_enforce_statfs, 0,
191
    "Processes in jail cannot see all mounted file systems");
199
    "Processes in jail cannot see all mounted file systems");
192
200
193
int    jail_allow_raw_sockets = 0;
201
int    jail_allow_raw_sockets = 0;
194
SYSCTL_INT(_security_jail, OID_AUTO, allow_raw_sockets, CTLFLAG_RW,
202
SYSCTL_INT(_security_jail, OID_AUTO, allow_raw_sockets, CTLFLAG_RW,
195
    <![CDATA[&jail]]>_allow_raw_sockets, 0,
203
    &amp;jail_allow_raw_sockets, 0,
196
    "Prison root can create raw sockets");
204
    "Prison root can create raw sockets");
197
205
198
int    jail_chflags_allowed = 0;
206
int    jail_chflags_allowed = 0;
199
SYSCTL_INT(_security_jail, OID_AUTO, chflags_allowed, CTLFLAG_RW,
207
SYSCTL_INT(_security_jail, OID_AUTO, chflags_allowed, CTLFLAG_RW,
200
    <![CDATA[&jail]]>_chflags_allowed, 0,
208
    &amp;jail_chflags_allowed, 0,
201
    "Processes in jail can alter system file flags");</programlisting>
209
    "Processes in jail can alter system file flags");</programlisting>
202
210
203
        <para>Each of these sysctls can be accessed by the user
211
        <para>Each of these sysctls can be accessed by the user
Lines 211-233 Link Here
211
        <title>&man.jail.2; system call</title>
219
        <title>&man.jail.2; system call</title>
212
220
213
        <para>Like all system calls, the &man.jail.2; system call takes
221
        <para>Like all system calls, the &man.jail.2; system call takes
214
          two arguments, <literal>struct proc *p</literal> and
222
          two arguments, <literal>struct thread *td</literal> and
215
          <literal>struct jail_args
223
          <literal>struct jail_args *uap</literal>.
216
          *uap</literal>. <literal>p</literal> is a pointer to a proc
224
          <literal>td</literal> is a pointer to the thread
217
          structure which describes the calling process. In this
225
          structure which describes the calling thread. In this
218
          context, uap is a pointer to a structure which specifies the
226
          context, uap is a pointer to the structure which specifies the
219
          arguments given to &man.jail.2; from the userland program
227
          arguments given to &man.jail.2; from the userland program
220
          <filename>jail.c</filename>. When I described the userland
228
          <filename>jail.c</filename>. When I described the userland
221
          program before, you saw that the &man.jail.2; system call was
229
          program before, you saw that the &man.jail.2; system call was
222
          given a jail structure as its own argument.</para>
230
          given a jail structure as its own argument.</para>
223
231
224
        <programlisting><filename>/usr/src/sys/kern/kern_jail.c:</filename>
232
        <programlisting><filename>/usr/src/sys/kern/kern_jail.c:</filename>
225
int
233
/*
226
jail(p, uap)
234
 * MPSAFE
227
        struct proc *p;
235
 *  
228
        struct jail_args /* {
236
 * struct jail_args {
229
                syscallarg(struct jail *) jail;
237
 *  struct jail *jail;
230
        } */ *uap;</programlisting>
238
 * };
239
 */ 
240
int 
241
jail(struct thread *td, struct jail_args *uap)</programlisting>
231
242
232
        <para>Therefore, <literal>uap-&gt;jail</literal> would access the
243
        <para>Therefore, <literal>uap-&gt;jail</literal> would access the
233
          jail structure which was passed to the system call. Next,
244
          jail structure which was passed to the system call. Next,
Lines 242-248 Link Here
242
          <literal>j</literal>.</para>
253
          <literal>j</literal>.</para>
243
254
244
        <programlisting><filename>/usr/src/sys/kern/kern_jail.c: </filename>
255
        <programlisting><filename>/usr/src/sys/kern/kern_jail.c: </filename>
245
error = copyin(uap-&gt;jail, <![CDATA[&j]]>, sizeof j);</programlisting>
256
error = copyin(uap-&gt;jail, &amp;j, sizeof(j));</programlisting>
246
257
247
        <para>There is another important structure defined in
258
        <para>There is another important structure defined in
248
          jail.h. It is the prison structure
259
          jail.h. It is the prison structure
Lines 253-262 Link Here
253
264
254
        <programlisting><filename>/usr/include/sys/jail.h</filename>:
265
        <programlisting><filename>/usr/include/sys/jail.h</filename>:
255
struct prison {
266
struct prison {
256
        int             pr_ref;
267
    LIST_ENTRY(prison) pr_list;         /* (a) all prisons */
257
        char            pr_host[MAXHOSTNAMELEN];
268
    int      pr_id;             /* (c) prison id */
258
        u_int32_t       pr_ip;
269
    int      pr_ref;            /* (p) refcount */
259
        void            *pr_linux;
270
    char         pr_path[MAXPATHLEN];       /* (c) chroot path */
271
    struct vnode    *pr_root;           /* (c) vnode to rdir */
272
    char         pr_host[MAXHOSTNAMELEN];   /* (p) jail hostname */
273
    u_int32_t    pr_ip;             /* (c) ip addr host */
274
    void        *pr_linux;          /* (p) linux abi */
275
    int      pr_securelevel;        /* (p) securelevel */
276
    struct task  pr_task;           /* (d) destroy task */
277
    struct mtx   pr_mtx;
260
};</programlisting>
278
};</programlisting>
261
279
262
        <para>The jail() system call then allocates memory for a
280
        <para>The jail() system call then allocates memory for a
Lines 264-346 Link Here
264
        structures.</para>
282
        structures.</para>
265
283
266
        <programlisting><filename>/usr/src/sys/kern/kern_jail.c</filename>:
284
        <programlisting><filename>/usr/src/sys/kern/kern_jail.c</filename>:
267
 MALLOC(pr, struct prison *, sizeof *pr , M_PRISON, M_WAITOK);
285
MALLOC(pr, struct prison *, sizeof(*pr), M_PRISON, M_WAITOK | M_ZERO);
268
 bzero((caddr_t)pr, sizeof *pr);
286
...
269
 error = copyinstr(j.hostname, <![CDATA[&pr-&gt;pr_host]]>, sizeof pr-&gt;pr_host, 0);
287
error = copyinstr(j.path, &amp;pr-&gt;pr_path, sizeof(pr-&gt;pr_path), 0);
270
 if (error) 
288
if (error)
271
         goto bail;</programlisting>
289
    goto e_killmtx;
272
290
...
273
      <indexterm><primary>chroot</primary></indexterm>
291
error = copyinstr(j.hostname, &amp;pr-&gt;pr_host, sizeof(pr-&gt;pr_host), 0);
274
292
 if (error)
275
        <para>Finally, the jail system call chroots the path
293
     goto e_dropvnref;</programlisting>
276
          specified. The chroot function is given two arguments. The
277
          first is p, which represents the calling process, the second
278
          is a pointer to the structure chroot args. The structure
279
          chroot args contains the path which is to be chrooted. As
280
          you can see, the path specified in the jail structure is
281
          copied to the chroot args structure and used.</para>
282
283
        <programlisting><filename>/usr/src/sys/kern/kern_jail.c</filename>:
284
ca.path = j.path; 
285
error = chroot(p, <![CDATA[&ca]]>);</programlisting>
286
287
        <para>These next three lines in the source are very important,
294
        <para>These next three lines in the source are very important,
288
          as they specify how the kernel recognizes a process as
295
          as they specify how the kernel recognizes a process as
289
          jailed. Each process on a &unix; system is described by its
296
          jailed. Each process on a &unix; system is described by its
290
          own proc structure. You can see the whole proc structure in
297
          own proc structure. You can see the whole proc structure in
291
          <filename>/usr/include/sys/proc.h</filename>. For example,
298
          <filename>/usr/include/sys/proc.h</filename>. For example,
292
          the p argument in any system call is actually a pointer to
299
          the td argument in any system call is actually a pointer to
293
          that process' proc structure, as stated before. The proc
300
          that calling thread's thread structure, as stated before. The
294
          structure contains nodes which can describe the owner's
301
          td-&gt;td_proc is a pointer to the calling process' process
295
          identity (<literal>p_cred</literal>), the process resource
302
          structure.  The proc structure contains nodes which can describe
296
          limits (<literal>p_limit</literal>), and so on. In the
303
          the owner's identity (<literal>p_ucred</literal>), the process
297
          definition of the process structure, there is a pointer to a
304
          resource limits (<literal>p_limit</literal>), and so on. In the
298
          prison structure. (<literal>p_prison</literal>).</para>
305
          definition of the ucred structure, there is a pointer to a
306
          prison structure. (<literal>cr_prison</literal>).</para>
299
307
300
        <programlisting><filename>/usr/include/sys/proc.h: </filename>
308
        <programlisting><filename>/usr/include/sys/proc.h: </filename>
301
struct proc { 
309
struct proc { 
302
...
310
...
303
struct prison *p_prison; 
311
struct ucred *p_ucred; 
312
...
313
};
314
<filename>/usr/include/sys/ucred.h</filename>
315
struct ucred {
316
...
317
struct prison *cr_prison;
304
...
318
...
305
};</programlisting>
319
};</programlisting>
306
320
307
        <para>In <filename>kern_jail.c</filename>, the function then
321
        <para>In <filename>kern_jail.c</filename>, the function then
308
          copies the pr structure, which is filled with all the
322
          calls function jail_attach with a given jid. And the jail_attach
309
          information from the original jail structure, over to the
323
          calls function change_root to change the root directory of the
310
          <literal>p-&gt;p_prison</literal> structure. It then does a
324
          calling process.  The jail_attach function then creates a new ucred
311
          bitwise OR of <literal>p-&gt;p_flag</literal> with the constant
325
          structure, and attaches the newly created ucred structure to the
312
          <literal>P_JAILED</literal>, meaning that the calling
326
          calling process after it has successfully attaches the prison on the
313
          process is now recognized as jailed. The parent process of
327
          cred structure. From then on, the calling process is recognized as
314
          each process, forked within the jail, is the program jail
328
          jailed. When calls function jailed with the newly created ucred
315
          itself, as it calls the &man.jail.2; system call. When the
329
          structure as the argument, it returns 1 to tell that the credential
316
          program is executed through execve, it inherits the
330
          is in a jail. The parent process of each process, forked within 
317
          properties of its parents proc structure, therefore it has
331
          the jail, is the program jail itself, as it calls the &man.jail.2;
318
          the <literal>p-&gt;p_flag</literal> set, and the
332
          system call.  When the program is executed through execve, it
319
          <literal>p-&gt;p_prison</literal> structure is filled.</para>
333
          inherits the properties of its parent's ucred structure, therefore it
334
          has the jailed ucred structure.</para>
320
335
321
        <programlisting><filename>/usr/src/sys/kern/kern_jail.c</filename>
336
        <programlisting><filename>/usr/src/sys/kern/kern_jail.c</filename>
322
p-&gt;p.prison = pr; 
337
int
323
p-&gt;p.flag |= P.JAILED;</programlisting>
338
jail(struct thread *td, struct jail_args *uap)
339
{
340
...
341
    struct jail_attach_args jaa;
342
...
343
    error = jail_attach(td, &amp;jaa);
344
    if (error)
345
        goto e_dropprref;
346
...
347
}
324
348
349
int
350
jail_attach(struct thread *td, struct jail_attach_args *uap)
351
{
352
    struct proc *p;
353
    struct ucred *newcred, *oldcred;
354
    struct prison *pr;
355
...
356
    p = td-&gt;td_proc;
357
...
358
    pr = prison_find(uap-&gt;jid);
359
...
360
    change_root(pr-&gt;pr_root, td);
361
...
362
    newcred-&gt;cr_prison = pr;
363
    p-&gt;p_ucred = newcred;
364
...
365
}</programlisting>
325
        <para>When a process is forked from a parent process, the
366
        <para>When a process is forked from a parent process, the
326
          &man.fork.2; system call deals differently with imprisoned
367
          &man.fork.2; system call uses crhold to maintain the credential
327
          processes. In the fork system call, there are two pointers
368
          for the newly forked process. It inherently keep the newly forked
328
          to a <literal>proc</literal> structure <literal>p1</literal>
369
          child's credential consistent with its parent, so the child process
329
          and <literal>p2</literal>. <literal>p1</literal> points to
370
          is also jailed.</para>
330
          the parent's <literal>proc</literal> structure and p2 points
331
          to the child's unfilled <literal>proc</literal>
332
          structure. After copying all relevant data between the
333
          structures, &man.fork.2; checks if the structure
334
          <literal>p-&gt;p_prison</literal> is filled on
335
          <literal>p2</literal>. If it is, it increments the
336
          <literal>pr.ref</literal> by one, and sets the
337
          <literal>p_flag</literal> to one on the child process.</para>
338
371
339
        <programlisting><filename>/usr/src/sys/kern/kern_fork.c</filename>:
372
        <programlisting><filename>/usr/src/sys/kern/kern_fork.c</filename>:
340
if (p2-&gt;p_prison) {
373
p2-&gt;p_ucred = crhold(td-&gt;td_ucred);
341
        p2-&gt;p_prison-&gt;pr_ref++;
374
td2-&gt;td_ucred = crhold(p2-&gt;p_ucred);</programlisting>
342
	p2-&gt;p_flag |= P_JAILED;
343
}</programlisting>
344
375
345
      </sect3>
376
      </sect3>
346
    </sect2>
377
    </sect2>
Lines 354-361 Link Here
354
      the process is jailed, and if so, returns an error. For
385
      the process is jailed, and if so, returns an error. For
355
      example:</para>
386
      example:</para>
356
387
357
    <programlisting>if (p-&gt;p_prison) 
388
    <programlisting>if (jailed(td-&gt;td_ucred))
358
        return EPERM;</programlisting>
389
        return (EPERM);</programlisting>
359
390
360
    <sect2>
391
    <sect2>
361
      <title>SysV IPC</title>
392
      <title>SysV IPC</title>
Lines 369-377 Link Here
369
        <literal>msgsend</literal> and <literal>msgrcv</literal>.
400
        <literal>msgsend</literal> and <literal>msgrcv</literal>.
370
        Earlier, I mentioned that there were certain sysctls you could
401
        Earlier, I mentioned that there were certain sysctls you could
371
        turn on or off in order to affect the behavior of Jail. One of
402
        turn on or off in order to affect the behavior of Jail. One of
372
        these sysctls was <literal>jail_sysvipc_allowed</literal>. On
403
        these sysctls was <literal>security.jail.sysvipc_allowed</literal>.
373
        most systems, this sysctl is set to 0. If it were set to 1, it
404
        On most systems, this sysctl is set to 0. If it were set to 1,
374
        would defeat the whole purpose of having a jail; privileged
405
        it would defeat the whole purpose of having a jail; privileged
375
        users from within the jail would be able to affect processes
406
        users from within the jail would be able to affect processes
376
        outside of the environment. The difference between a message
407
        outside of the environment. The difference between a message
377
        and a signal is that the message only consists of the signal
408
        and a signal is that the message only consists of the signal
Lines 399-407 Link Here
399
      <para>In each of these system calls, there is this
430
      <para>In each of these system calls, there is this
400
        conditional:</para>
431
        conditional:</para>
401
432
402
      <programlisting><filename>/usr/src/sys/kern/sysv msg.c</filename>:
433
      <programlisting><filename>/usr/src/sys/kern/sysv_msg.c</filename>:
403
if (!jail.sysvipc.allowed &amp;&amp; p-&gt;p_prison != NULL)
434
if (!jail_sysvipc_allowed &amp;&amp; jailed(td-&gt;td_ucred)
404
        return (ENOSYS);</programlisting>
435
    return (ENOSYS);</programlisting>
405
436
406
      <indexterm><primary>semaphores</primary></indexterm>
437
      <indexterm><primary>semaphores</primary></indexterm>
407
      <para>Semaphore system calls allow processes to synchronize
438
      <para>Semaphore system calls allow processes to synchronize
Lines 430-436 Link Here
430
          <para><literal>Key and flag take on the same meaning as they
461
          <para><literal>Key and flag take on the same meaning as they
431
          do in msgget.</literal></para></listitem>
462
          do in msgget.</literal></para></listitem>
432
463
433
        <listitem><para>&man.semop.2;<literal>(id, ops, num)</literal>:
464
        <listitem><para>&man.semop.2;<literal>(semid, sops, nsops)</literal>:
434
          Semop does the set of semaphore operations in the array of
465
          Semop does the set of semaphore operations in the array of
435
          structures ops, to the set of semaphores identified by
466
          structures ops, to the set of semaphores identified by
436
          id.</para></listitem>
467
          id.</para></listitem>
Lines 445-466 Link Here
445
        shmat, oshmctl, shmctl, shmget</literal>, and
476
        shmat, oshmctl, shmctl, shmget</literal>, and
446
        <literal>shmsys</literal>.</para>
477
        <literal>shmsys</literal>.</para>
447
478
448
      <para><filename>/usr/src/sys/kern/sysv shm.c</filename>:</para>
479
      <para><filename>/usr/src/sys/kern/sysv_shm.c</filename>:</para>
449
480
450
      <itemizedlist>
481
      <itemizedlist>
451
        <listitem><para>&man.shmctl.2;<literal>(id, cmd, buf)</literal>:
482
        <listitem><para>&man.shmctl.2;<literal>(shmid, cmd, buf)</literal>:
452
        shmctl does various control operations on the shared memory
483
        shmctl does various control operations on the shared memory
453
        region identified by id.</para></listitem>
484
        region identified by id.</para></listitem>
454
485
455
        <listitem><para>&man.shmget.2;<literal>(key, size,
486
        <listitem><para>&man.shmget.2;<literal>(key, size,
456
        flag)</literal>: shmget accesses or creates a shared memory
487
        shmflg)</literal>: shmget accesses or creates a shared memory
457
        region of size bytes.</para></listitem>
488
        region of size bytes.</para></listitem>
458
489
459
        <listitem><para>&man.shmat.2;<literal>(id, addr, flag)</literal>:
490
        <listitem><para>&man.shmat.2;<literal>(shmid, shmaddr, shmflg)</literal>:
460
        shmat attaches a shared memory region identified by id to the
491
        shmat attaches a shared memory region identified by id to the
461
        address space of a process.</para></listitem>
492
        address space of a process.</para></listitem>
462
493
463
        <listitem><para>&man.shmdt.2;<literal>(addr)</literal>: shmdt
494
        <listitem><para>&man.shmdt.2;<literal>(shmaddr)</literal>: shmdt
464
        detaches the shared memory region previously attached at
495
        detaches the shared memory region previously attached at
465
        addr.</para></listitem>
496
        addr.</para></listitem>
466
497
Lines 475-481 Link Here
475
        lower-level socket functions in a special manner. In order to
506
        lower-level socket functions in a special manner. In order to
476
        determine whether a certain socket is allowed to be created,
507
        determine whether a certain socket is allowed to be created,
477
        it first checks to see if the sysctl
508
        it first checks to see if the sysctl
478
        <literal>jail.socket.unixiproute.only</literal> is set. If
509
        <literal>security.jail.socket_unixiproute_only</literal> is set. If
479
        set, sockets are only allowed to be created if the family
510
        set, sockets are only allowed to be created if the family
480
        specified is either <literal>PF_LOCAL</literal>,
511
        specified is either <literal>PF_LOCAL</literal>,
481
        <literal>PF_INET</literal> or
512
        <literal>PF_INET</literal> or
Lines 483-497 Link Here
483
        error.</para>
514
        error.</para>
484
515
485
      <programlisting><filename>/usr/src/sys/kern/uipc_socket.c</filename>:
516
      <programlisting><filename>/usr/src/sys/kern/uipc_socket.c</filename>:
486
int socreate(dom, aso, type, proto, p) 
517
int
487
... 
518
socreate(dom, aso, type, proto, cred, td)
488
register struct protosw *prp; 
519
...
489
... 
490
{
520
{
491
        if (p-&gt;p_prison &amp;&amp; jail_socket_unixiproute_only &amp;&amp;
521
    struct protosw *prp;
492
            prp-&gt;pr_domain-&gt;dom_family != PR_LOCAL &amp;&amp; prp-&gt;pr_domain-&gt;dom_family != PF_INET 
522
...
493
            &amp;&amp; prp-&gt;pr_domain-&gt;dom_family != PF_ROUTE)
523
    if (jailed(cred) &amp;&amp; jail_socket_unixiproute_only &amp;&amp;
494
                return (EPROTONOSUPPORT); 
524
        prp-&gt;pr_domain-&gt;dom_family != PF_LOCAL &amp;&amp;
525
        prp-&gt;pr_domain-&gt;dom_family != PF_INET &amp;&amp;
526
        prp-&gt;pr_domain-&gt;dom_family != PF_ROUTE) {
527
        return (EPROTONOSUPPORT);
528
    }
495
...
529
...
496
}</programlisting>
530
}</programlisting>
497
531
Lines 506-522 Link Here
506
      <para>The Berkeley Packet Filter provides a raw interface to
540
      <para>The Berkeley Packet Filter provides a raw interface to
507
        data link layers in a protocol independent fashion. The
541
        data link layers in a protocol independent fashion. The
508
        function <literal>bpfopen()</literal> opens an Ethernet
542
        function <literal>bpfopen()</literal> opens an Ethernet
509
        device. There is a conditional which disallows any jailed
543
        device. It's now controlled by the devfs whether can be used
510
        processes from accessing this function.</para>
544
        in the jail.
511
512
      <programlisting><filename>/usr/src/sys/net/bpf.c</filename>: 
513
static int bpfopen(dev, flags, fmt, p) 
514
... 
515
{
516
        if (p-&gt;p_prison) 
517
                return (EPERM);
518
...
519
}</programlisting>
520
545
521
    </sect2>
546
    </sect2>
522
547
Lines 534-611 Link Here
534
        which describes the address on which to bind the service. A
559
        which describes the address on which to bind the service. A
535
        more exact definition is that sockaddr "may be used as a
560
        more exact definition is that sockaddr "may be used as a
536
        template for referring to the identifying tag and length of
561
        template for referring to the identifying tag and length of
537
        each address"[2]. In the function in
562
        each address"[2]. In the function
538
        <literal>pcbbind</literal>, <literal>sin</literal> is a
563
        <literal>in_pcbbind_setup</literal>, <literal>sin</literal> is a
539
        pointer to a sockaddr.in structure, which contains the port,
564
        pointer to a sockaddr_in structure, which contains the port,
540
        address, length and domain family of the socket which is to be
565
        address, length and domain family of the socket which is to be
541
        bound. Basically, this disallows any processes from jail to be
566
        bound. Basically, this disallows any processes from jail to be
542
        able to specify the domain family.</para>
567
        able to specify the domain family.</para>
543
568
544
      <programlisting><filename>/usr/src/sys/kern/netinet/in_pcb.c</filename>: 
569
      <programlisting><filename>/usr/src/sys/netinet/in_pcb.c</filename>: 
545
int in.pcbbind(int, nam, p) 
570
int
546
...
571
in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
547
        struct sockaddr *nam; 
572
    u_short *lportp, struct ucred *cred)
548
        struct proc *p; 
549
{
573
{
550
        ... 
574
    ...
551
        struct sockaddr.in *sin; 
575
    struct sockaddr_in *sin;
552
        ... 
576
    ...
553
        if (nam) {
577
    if (nam) {
554
                sin = (struct sockaddr.in *)nam; 
578
        sin = (struct sockaddr_in *)nam;
555
                ... 
579
        ...
556
                if (sin-&gt;sin_addr.s_addr != INADDR_ANY) 
580
#ifdef notdef
557
                       if (prison.ip(p, 0, <![CDATA[&sin]]>-&gt;sin.addr.s_addr)) 
581
        /*
558
                              return (EINVAL); 
582
         * We should check the family, but old programs
559
                ....
583
         * incorrectly fail to initialize it.
560
        }
584
         */
585
        if (sin->sin_family != AF_INET)
586
            return (EAFNOSUPPORT);
587
#endif
588
        if (sin-&gt;sin_addr.s_addr != INADDR_ANY)
589
            if (prison_ip(cred, 0, &amp;sin-&gt;sin_addr.s_addr))
590
                return(EINVAL);
591
        ...
592
    }
561
...
593
...
562
}</programlisting>
594
}</programlisting>
563
595
564
      <para>You might be wondering what function
596
      <para>You might be wondering what function
565
        <literal>prison_ip()</literal> does. prison.ip is given three
597
        <literal>prison_ip()</literal> does. prison_ip is given three
566
        arguments, the current process (represented by
598
        arguments, a pointer to the credential(represented by
567
        <literal>p</literal>), any flags, and an ip address. It
599
        <literal>cred</literal>), any flags, and an ip address. It
568
        returns 1 if the ip address belongs to a jail or 0 if it does
600
        returns 1 if the ip address does NOT belong to the jail or
569
        not. As you can see from the code, if it is indeed an ip
601
        0 otherwise.  As you can see from the code, if it is indeed
570
        address belonging to a jail, the protcol is not allowed to
602
        an ip address not belonging to the jail, the protcol is
571
        bind to a certain port.</para>
603
        not allowed to bind to a certain port.</para>
572
604
573
      <programlisting><filename>/usr/src/sys/kern/kern_jail.c:</filename>
605
      <programlisting><filename>/usr/src/sys/kern/kern_jail.c:</filename>
574
int prison_ip(struct proc *p, int flag, u_int32_t *ip) {
606
int
575
        u_int32_t tmp;
607
prison_ip(struct ucred *cred, int flag, u_int32_t *ip)
576
608
{
577
       if (!p-&gt;p_prison) 
609
    u_int32_t tmp;
578
              return (0); 
579
       if (flag) 
580
              tmp = *ip; 
581
       else tmp = ntohl (*ip); 
582
583
       if (tmp == INADDR_ANY) {
584
              if (flag) 
585
                     *ip = p-&gt;p_prison-&gt;pr_ip; 
586
              else *ip = htonl(p-&gt;p_prison-&gt;pr_ip); 
587
              return (0); 
588
       }
589
610
590
       if (p-&gt;p_prison-&gt;pr_ip != tmp) 
611
    if (!jailed(cred))
591
              return (1); 
612
        return (0);
592
       return (0); 
613
    if (flag)
614
        tmp = *ip;
615
    else
616
        tmp = ntohl(*ip);
617
    if (tmp == INADDR_ANY) {
618
        if (flag)
619
            *ip = cred-&gt;cr_prison-&gt;pr_ip;
620
        else
621
            *ip = htonl(cred-&gt;cr_prison-&gt;pr_ip);
622
        return (0);
623
    }
624
    if (tmp == INADDR_LOOPBACK) {
625
        if (flag)
626
            *ip = cred-&gt;cr_prison-&gt;pr_ip;
627
        else
628
            *ip = htonl(cred-&gt;cr_prison-&gt;pr_ip);
629
        return (0);
630
    }
631
    if (cred-&gt;cr_prison-&gt;pr_ip != tmp)
632
        return (1);
633
    return (0);
593
}</programlisting>
634
}</programlisting>
594
635
595
      <para>Jailed users are not allowed to bind services to an ip
636
      <para>Jailed users are not allowed to bind services to an ip
596
        which does not belong to the jail. The restriction is also
637
        which does not belong to the jail. The restriction is also
597
        written within the function <literal>in_pcbbind</literal>:</para>
638
        written within the function <literal>in_pcbbind_setup</literal>:</para>
598
639
599
      <programlisting><filename>/usr/src/sys/net inet/in_pcb.c</filename>
640
      <programlisting><filename>/usr/src/sys/netinet/in_pcb.c</filename>
600
        if (nam) {
641
        if (nam) {
601
               ... 
642
               ... 
602
               lport = sin-&gt;sin.port; 
643
               lport = sin-&gt;sin.port; 
603
               ... if (lport) { 
644
               ... if (lport) { 
604
                          ... 
645
                         ... 
605
                         if (p &amp;&amp; p-&gt;p_prison)
646
                         if (jailed(cred))
606
                                prison = 1; 
647
                                prison = 1; 
648
                         ...
607
                         if (prison &amp;&amp;
649
                         if (prison &amp;&amp;
608
                             prison_ip(p, 0, <![CDATA[&sin]]>-&gt;sin_addr.s_addr))
650
                             prison_ip(cred, 0, &amp;sin-&gt;sin_addr.s_addr))
609
			            return (EADDRNOTAVAIL);</programlisting>
651
			            return (EADDRNOTAVAIL);</programlisting>
610
652
611
    </sect2>
653
    </sect2>
Lines 619-632 Link Here
619
        the securelevel is greater than 0.</para>
661
        the securelevel is greater than 0.</para>
620
662
621
      <programlisting>/usr/src/sys/ufs/ufs/ufs_vnops.c:
663
      <programlisting>/usr/src/sys/ufs/ufs/ufs_vnops.c:
622
int ufs.setattr(ap) 
664
static int
623
        ... 
665
ufs_setattr(ap)
666
    ...
624
{
667
{
625
        if ((cred-&gt;cr.uid == 0) &amp;&amp; (p-&gt;prison == NULL)) {
668
    ...
626
	        if ((ip-&gt;i_flags 
669
        if (!suser_cred(cred,
627
                     &amp; (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) &amp;&amp; 
670
            jail_chflags_allowed ? SUSER_ALLOWJAIL : 0)) {
628
                     securelevel &gt; 0)
671
            if (ip-&gt;i_flags
629
		       return (EPERM);
672
                &amp; (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) {
673
                error = securelevel_gt(cred, 0);
674
                if (error)
675
                    return (error);
676
            }
677
            ...
630
}</programlisting>
678
}</programlisting>
631
679
632
    </sect2>
680
    </sect2>

Return to bug 108676