Date: Sun, 26 Aug 2018 15:56:45 +0000 (UTC) From: Benedict Reuschling <bcr@FreeBSD.org> To: doc-committers@freebsd.org, svn-doc-all@freebsd.org, svn-doc-head@freebsd.org Subject: svn commit: r52176 - head/en_US.ISO8859-1/books/arch-handbook/jail Message-ID: <201808261556.w7QFujta027786@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: bcr Date: Sun Aug 26 15:56:45 2018 New Revision: 52176 URL: https://svnweb.freebsd.org/changeset/doc/52176 Log: Clean up some errors that were reported by textproc/igor: - Bad tag indents - Wrap long lines - Two spaces at sentence start Modified: head/en_US.ISO8859-1/books/arch-handbook/jail/chapter.xml Modified: head/en_US.ISO8859-1/books/arch-handbook/jail/chapter.xml ============================================================================== --- head/en_US.ISO8859-1/books/arch-handbook/jail/chapter.xml Sun Aug 26 14:08:19 2018 (r52175) +++ head/en_US.ISO8859-1/books/arch-handbook/jail/chapter.xml Sun Aug 26 15:56:45 2018 (r52176) @@ -4,53 +4,68 @@ $FreeBSD$ --> -<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="jail"> - <info><title>The Jail Subsystem</title> - <author><personname><firstname>Evan</firstname><surname>Sarmiento</surname></personname><affiliation> - <address><email>evms@cs.bu.edu</email></address> - </affiliation></author> +<chapter xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" + xml:id="jail"> + <info> + <title>The Jail Subsystem</title> + + <author> + <personname> + <firstname>Evan</firstname> + <surname>Sarmiento</surname> + </personname> + <affiliation> + <address> + <email>evms@cs.bu.edu</email> + </address> + </affiliation> + </author> <copyright> <year>2001</year> <holder role="mailto:evms@cs.bu.edu">Evan Sarmiento</holder> </copyright> </info> - <indexterm><primary>security</primary></indexterm> <indexterm><primary>Jail</primary></indexterm> <indexterm><primary>root</primary></indexterm> - <para>On most &unix; systems, <literal>root</literal> has omnipotent power. - This promotes insecurity. If an attacker gained <literal>root</literal> - on a system, he would have every function at his fingertips. In FreeBSD - there are sysctls which dilute the power of <literal>root</literal>, in - order to minimize the damage caused by an attacker. Specifically, one of - these functions is called <literal>secure levels</literal>. Similarly, - another function which is present from FreeBSD 4.0 and onward, is a utility - called &man.jail.8;. <application>Jail</application> chroots an environment - and sets certain restrictions on processes which are forked within - the <application>jail</application>. For example, a jailed process - cannot affect processes outside the <application>jail</application>, - utilize certain system calls, or inflict any damage on the host - environment.</para> + <para>On most &unix; systems, <literal>root</literal> has omnipotent + power. This promotes insecurity. If an attacker gained + <literal>root</literal> on a system, he would have every function + at his fingertips. In FreeBSD there are sysctls which dilute the + power of <literal>root</literal>, in order to minimize the damage + caused by an attacker. Specifically, one of these functions is + called <literal>secure levels</literal>. Similarly, another + function which is present from FreeBSD 4.0 and onward, is a + utility called &man.jail.8;. <application>Jail</application> + chroots an environment and sets certain restrictions on processes + which are forked within the <application>jail</application>. For + example, a jailed process cannot affect processes outside the + <application>jail</application>, utilize certain system calls, or + inflict any damage on the host environment.</para> <para><application>Jail</application> is becoming the new security - model. People are running potentially vulnerable servers such as - <application>Apache</application>, <application>BIND</application>, and - <application>sendmail</application> within jails, so that if an attacker - gains <literal>root</literal> within the <application>jail</application>, - it is only an annoyance, and not a devastation. This article mainly - focuses on the internals (source code) of <application>jail</application>. - For information on how to set up a jail see the <link xlink:href="&url.books.handbook;/jails.html">handbook entry on jails</link>.</para> + model. People are running potentially vulnerable servers such as + <application>Apache</application>, + <application>BIND</application>, and + <application>sendmail</application> within jails, so that if an + attacker gains <literal>root</literal> within the + <application>jail</application>, it is only an annoyance, and not + a devastation. This article mainly focuses on the internals + (source code) of <application>jail</application>. For information + on how to set up a jail see the <link + xlink:href="&url.books.handbook;/jails.html">handbook entry on + jails</link>.</para> <sect1 xml:id="jail-arch"> <title>Architecture</title> - <para> - <application>Jail</application> consists of two realms: the + <para><application>Jail</application> consists of two realms: the userland program, &man.jail.8;, and the code implemented within the kernel: the &man.jail.2; system call and associated - restrictions. I will be discussing the userland program and + restrictions. I will be discussing the userland program and then how <application>jail</application> is implemented within the kernel.</para> @@ -60,24 +75,25 @@ <indexterm><primary>Jail</primary> <secondary>Userland Program</secondary></indexterm> - <para>The source for the userland <application>jail</application> - is located in <filename>/usr/src/usr.sbin/jail</filename>, - consisting of one file, <filename>jail.c</filename>. The program - takes these arguments: the path of the <application>jail</application>, - hostname, IP address, and the command to be executed.</para> + <para>The source for the userland + <application>jail</application> is located in + <filename>/usr/src/usr.sbin/jail</filename>, consisting of one + file, <filename>jail.c</filename>. The program takes these + arguments: the path of the <application>jail</application>, + hostname, IP address, and the command to be executed.</para> <sect3> - <title>Data Structures</title> + <title>Data Structures</title> - <para>In <filename>jail.c</filename>, the first thing I would - note is the declaration of an important structure - <literal>struct jail j;</literal> which was included from - <filename>/usr/include/sys/jail.h</filename>.</para> + <para>In <filename>jail.c</filename>, the first thing I would + note is the declaration of an important structure + <literal>struct jail j;</literal> which was included from + <filename>/usr/include/sys/jail.h</filename>.</para> - <para>The definition of the <literal>jail</literal> structure is: -</para> + <para>The definition of the <literal>jail</literal> structure + is:</para> -<programlisting><filename>/usr/include/sys/jail.h</filename>: + <programlisting><filename>/usr/include/sys/jail.h</filename>: struct jail { u_int32_t version; @@ -86,11 +102,11 @@ struct jail { u_int32_t ip_number; };</programlisting> - <para>As you can see, there is an entry for each of the - arguments passed to the &man.jail.8; program, and indeed, - they are set during its execution.</para> + <para>As you can see, there is an entry for each of the + arguments passed to the &man.jail.8; program, and indeed, + they are set during its execution.</para> - <programlisting><filename>/usr/src/usr.sbin/jail/jail.c</filename> + <programlisting><filename>/usr/src/usr.sbin/jail/jail.c</filename> char path[PATH_MAX]; ... if (realpath(argv[0], path) == NULL) @@ -101,54 +117,55 @@ memset(&j, 0, sizeof(j)); j.version = 0; j.path = path; j.hostname = argv[1];</programlisting> - </sect3> <sect3> - <title>Networking</title> + <title>Networking</title> - <para>One of the arguments passed to the &man.jail.8; program is - an IP address with which the <application>jail</application> - can be accessed over the network. &man.jail.8; translates the - IP address given into host byte order and then stores it in - <literal>j</literal> (the <literal>jail</literal> structure).</para> + <para>One of the arguments passed to the &man.jail.8; program + is an IP address with which the + <application>jail</application> can be accessed over the + network. &man.jail.8; translates the IP address given into + host byte order and then stores it in <literal>j</literal> + (the <literal>jail</literal> structure).</para> - <programlisting><filename>/usr/src/usr.sbin/jail/jail.c</filename>: + <programlisting><filename>/usr/src/usr.sbin/jail/jail.c</filename>: struct in_addr in; ... if (inet_aton(argv[2], &in) == 0) errx(1, "Could not make sense of ip-number: %s", argv[2]); j.ip_number = ntohl(in.s_addr);</programlisting> - <para>The &man.inet.aton.3; function "interprets the specified - character string as an Internet address, placing the address - into the structure provided." The <literal>ip_number</literal> - member in the <literal>jail</literal> structure is set only - when the IP address placed onto the <literal>in</literal> - structure by &man.inet.aton.3; is translated into host byte - order by &man.ntohl.3;.</para> - + <para>The &man.inet.aton.3; function "interprets the specified + character string as an Internet address, placing the address + into the structure provided." The + <literal>ip_number</literal> member in the + <literal>jail</literal> structure is set only when the IP + address placed onto the <literal>in</literal> structure by + &man.inet.aton.3; is translated into host byte order by + &man.ntohl.3;.</para> </sect3> <sect3> - <title>Jailing the Process</title> + <title>Jailing the Process</title> - <para>Finally, the userland program jails the process. - <application>Jail</application> now becomes an imprisoned - process itself and then executes the command given using - &man.execv.3;.</para> - <programlisting><filename>/usr/src/usr.sbin/jail/jail.c</filename> + <para>Finally, the userland program jails the process. + <application>Jail</application> now becomes an imprisoned + process itself and then executes the command given using + &man.execv.3;.</para> + + <programlisting><filename>/usr/src/usr.sbin/jail/jail.c</filename> i = jail(&j); ... if (execv(argv[3], argv + 3) != 0) err(1, "execv: %s", argv[3]);</programlisting> - <para>As you can see, the <literal>jail()</literal> function is - called, and its argument is the <literal>jail</literal> structure - which has been filled with the arguments given to the program. - Finally, the program you specify is executed. I will now discuss - how <application>jail</application> is implemented within the - kernel.</para> + <para>As you can see, the <literal>jail()</literal> function + is called, and its argument is the <literal>jail</literal> + structure which has been filled with the arguments given to + the program. Finally, the program you specify is executed. + I will now discuss how <application>jail</application> is + implemented within the kernel.</para> </sect3> </sect2> @@ -159,20 +176,19 @@ if (execv(argv[3], argv + 3) != 0) <secondary>Kernel Architecture</secondary></indexterm> <para>We will now be looking at the file - <filename>/usr/src/sys/kern/kern_jail.c</filename>. This is - the file where the &man.jail.2; system call, appropriate sysctls, - and networking functions are defined.</para> + <filename>/usr/src/sys/kern/kern_jail.c</filename>. This is + the file where the &man.jail.2; system call, appropriate + sysctls, and networking functions are defined.</para> <sect3> - <title>sysctls</title> + <title>Sysctls</title> - <indexterm><primary>sysctl</primary></indexterm> + <indexterm><primary>sysctl</primary></indexterm> - <para>In <filename>kern_jail.c</filename>, the following - sysctls are defined:</para> + <para>In <filename>kern_jail.c</filename>, the following + sysctls are defined:</para> - <programlisting><filename>/usr/src/sys/kern/kern_jail.c:</filename> - + <programlisting><filename>/usr/src/sys/kern/kern_jail.c:</filename> int jail_set_hostname_allowed = 1; SYSCTL_INT(_security_jail, OID_AUTO, set_hostname_allowed, CTLFLAG_RW, &jail_set_hostname_allowed, 0, @@ -208,29 +224,30 @@ SYSCTL_INT(_security_jail, OID_AUTO, mount_allowed, CT &jail_mount_allowed, 0, "Processes in jail can mount/unmount jail-friendly file systems");</programlisting> - <para>Each of these sysctls can be accessed by the user - through the &man.sysctl.8; program. Throughout the kernel, these - specific sysctls are recognized by their name. For example, - the name of the first sysctl is - <literal>security.jail.set_hostname_allowed</literal>.</para> + <para>Each of these sysctls can be accessed by the user + through the &man.sysctl.8; program. Throughout the kernel, + these specific sysctls are recognized by their name. For + example, the name of the first sysctl is + <literal>security.jail.set_hostname_allowed</literal>.</para> </sect3> <sect3> - <title>&man.jail.2; System Call</title> + <title>&man.jail.2; System Call</title> - <para>Like all system calls, the &man.jail.2; system call takes - two arguments, <literal>struct thread *td</literal> and - <literal>struct jail_args *uap</literal>. - <literal>td</literal> is a pointer to the <literal>thread</literal> - structure which describes the calling thread. In this - context, <literal>uap</literal> is a pointer to the structure - in which a pointer to the <literal>jail</literal> structure - passed by the userland <filename>jail.c</filename> is contained. - When I described the userland program before, you saw that the - &man.jail.2; system call was given a <literal>jail</literal> - structure as its own argument.</para> + <para>Like all system calls, the &man.jail.2; system call + takes two arguments, <literal>struct thread *td</literal> + and <literal>struct jail_args *uap</literal>. + <literal>td</literal> is a pointer to the + <literal>thread</literal> structure which describes the + calling thread. In this context, <literal>uap</literal> is + a pointer to the structure in which a pointer to the + <literal>jail</literal> structure passed by the userland + <filename>jail.c</filename> is contained. When I described + the userland program before, you saw that the &man.jail.2; + system call was given a <literal>jail</literal> structure as + its own argument.</para> - <programlisting><filename>/usr/src/sys/kern/kern_jail.c:</filename> + <programlisting><filename>/usr/src/sys/kern/kern_jail.c:</filename> /* * struct jail_args { * struct jail *jail; @@ -239,29 +256,30 @@ SYSCTL_INT(_security_jail, OID_AUTO, mount_allowed, CT int jail(struct thread *td, struct jail_args *uap)</programlisting> - <para>Therefore, <literal>uap->jail</literal> can be used to - access the <literal>jail</literal> structure which was passed - to the system call. Next, the system call copies the - <literal>jail</literal> structure into kernel space using - the &man.copyin.9; function. &man.copyin.9; takes three arguments: - the address of the data which is to be copied into kernel space, - <literal>uap->jail</literal>, where to store it, - <literal>j</literal> and the size of the storage. The - <literal>jail</literal> structure pointed by - <literal>uap->jail</literal> is copied into kernel space and - is stored in another <literal>jail</literal> structure, - <literal>j</literal>.</para> + <para>Therefore, <literal>uap->jail</literal> can be used + to access the <literal>jail</literal> structure which was + passed to the system call. Next, the system call copies the + <literal>jail</literal> structure into kernel space using + the &man.copyin.9; function. &man.copyin.9; takes three + arguments: the address of the data which is to be copied + into kernel space, <literal>uap->jail</literal>, where to + store it, <literal>j</literal> and the size of the storage. + The <literal>jail</literal> structure pointed by + <literal>uap->jail</literal> is copied into kernel space + and is stored in another <literal>jail</literal> structure, + <literal>j</literal>.</para> - <programlisting><filename>/usr/src/sys/kern/kern_jail.c: </filename> + <programlisting><filename>/usr/src/sys/kern/kern_jail.c:</filename> error = copyin(uap->jail, &j, sizeof(j));</programlisting> - <para>There is another important structure defined in - <filename>jail.h</filename>. It is the <literal>prison</literal> - structure. The <literal>prison</literal> structure is used - exclusively within kernel space. Here is the definition of the - <literal>prison</literal> structure.</para> + <para>There is another important structure defined in + <filename>jail.h</filename>. It is the + <literal>prison</literal> structure. The + <literal>prison</literal> structure is used exclusively + within kernel space. Here is the definition of the + <literal>prison</literal> structure.</para> - <programlisting><filename>/usr/include/sys/jail.h</filename>: + <programlisting><filename>/usr/include/sys/jail.h</filename>: struct prison { LIST_ENTRY(prison) pr_list; /* (a) all prisons */ int pr_id; /* (c) prison id */ @@ -277,12 +295,12 @@ struct prison { void **pr_slots; /* (p) additional data */ };</programlisting> - <para>The &man.jail.2; system call then allocates memory for - a <literal>prison</literal> structure and copies data between - the <literal>jail</literal> and <literal>prison</literal> - structure.</para> + <para>The &man.jail.2; system call then allocates memory for a + <literal>prison</literal> structure and copies data between + the <literal>jail</literal> and <literal>prison</literal> + structure.</para> - <programlisting><filename>/usr/src/sys/kern/kern_jail.c</filename>: + <programlisting><filename>/usr/src/sys/kern/kern_jail.c</filename>: MALLOC(pr, struct prison *, sizeof(*pr), M_PRISON, M_WAITOK | M_ZERO); ... error = copyinstr(j.path, &pr->pr_path, sizeof(pr->pr_path), 0); @@ -293,10 +311,12 @@ error = copyinstr(j.hostname, &pr->pr_host, siz if (error) goto e_dropvnref; pr->pr_ip = j.ip_number;</programlisting> - <para>Next, we will discuss another important system call - &man.jail.attach.2;, which implements the function to put - a process into the <application>jail</application>.</para> - <programlisting><filename>/usr/src/sys/kern/kern_jail.c</filename>: + + <para>Next, we will discuss another important system call + &man.jail.attach.2;, which implements the function to put a + process into the <application>jail</application>.</para> + + <programlisting><filename>/usr/src/sys/kern/kern_jail.c</filename>: /* * struct jail_attach_args { * int jid; @@ -304,34 +324,37 @@ pr->pr_ip = j.ip_number;</programlisting> */ int jail_attach(struct thread *td, struct jail_attach_args *uap)</programlisting> - <para>This system call makes the changes that can distinguish - a jailed process from those unjailed ones. - To understand what &man.jail.attach.2; does for us, certain - background information is needed.</para> - <para> - On FreeBSD, each kernel visible thread is identified by its - <literal>thread</literal> structure, while the processes are - described by their <literal>proc</literal> structures. You can - find the definitions of the <literal>thread</literal> and - <literal>proc</literal> structure in - <filename>/usr/include/sys/proc.h</filename>. - For example, the <literal>td</literal> argument in any system - call is actually a pointer to the calling thread's - <literal>thread</literal> structure, as stated before. - The <literal>td_proc</literal> member in the - <literal>thread</literal> structure pointed by <literal>td</literal> - is a pointer to the <literal>proc</literal> structure which - represents the process that contains the thread represented by - <literal>td</literal>. The <literal>proc</literal> structure - contains members which can describe the owner's - identity(<literal>p_ucred</literal>), the process resource - limits(<literal>p_limit</literal>), and so on. In the - <literal>ucred</literal> structure pointed by - <literal>p_ucred</literal> member in the <literal>proc</literal> - structure, there is a pointer to the <literal>prison</literal> - structure(<literal>cr_prison</literal>).</para> - <programlisting><filename>/usr/include/sys/proc.h: </filename> + <para>This system call makes the changes that can distinguish + a jailed process from those unjailed ones. To understand + what &man.jail.attach.2; does for us, certain background + information is needed.</para> + + <para>On FreeBSD, each kernel visible thread is identified by + its <literal>thread</literal> structure, while the processes + are described by their <literal>proc</literal> structures. + You can find the definitions of the + <literal>thread</literal> and <literal>proc</literal> + structure in <filename>/usr/include/sys/proc.h</filename>. + For example, the <literal>td</literal> argument in any + system call is actually a pointer to the calling thread's + <literal>thread</literal> structure, as stated before. The + <literal>td_proc</literal> member in the + <literal>thread</literal> structure pointed by + <literal>td</literal> is a pointer to the + <literal>proc</literal> structure which represents the + process that contains the thread represented by + <literal>td</literal>. The <literal>proc</literal> + structure contains members which can describe the owner's + identity(<literal>p_ucred</literal>), the process resource + limits(<literal>p_limit</literal>), and so on. In the + <literal>ucred</literal> structure pointed by + <literal>p_ucred</literal> member in the + <literal>proc</literal> structure, there is a pointer to the + <literal>prison</literal> + structure(<literal>cr_prison</literal>).</para> + + <programlisting><filename>/usr/include/sys/proc.h:</filename> struct thread { ... struct proc *td_proc; @@ -349,29 +372,33 @@ struct ucred { ... };</programlisting> - <para>In <filename>kern_jail.c</filename>, the function - <literal>jail()</literal> then calls function - <literal>jail_attach()</literal> with a given <literal>jid</literal>. - And <literal>jail_attach()</literal> calls function - <literal>change_root()</literal> to change the root directory of the - calling process. The <literal>jail_attach()</literal> then creates - a new <literal>ucred</literal> structure, and attaches the newly - created <literal>ucred</literal> structure to the calling process - after it has successfully attached the <literal>prison</literal> - structure to the <literal>ucred</literal> structure. From then on, - the calling process is recognized as jailed. When the kernel routine - <literal>jailed()</literal> is called in the kernel with the newly - created <literal>ucred</literal> structure as its argument, it - returns 1 to tell that the credential is connected - with a <application>jail</application>. The public ancestor process - of all the process forked within the <application>jail</application>, - is the process which runs &man.jail.8;, as it calls the - &man.jail.2; system call. When a program is executed through - &man.execve.2;, it inherits the jailed property of its parent's - <literal>ucred</literal> structure, therefore it has a jailed - <literal>ucred</literal> structure.</para> + <para>In <filename>kern_jail.c</filename>, the function + <literal>jail()</literal> then calls function + <literal>jail_attach()</literal> with a given + <literal>jid</literal>. And + <literal>jail_attach()</literal> calls function + <literal>change_root()</literal> to change the root + directory of the calling process. The + <literal>jail_attach()</literal> then creates a new + <literal>ucred</literal> structure, and attaches the newly + created <literal>ucred</literal> structure to the calling + process after it has successfully attached the + <literal>prison</literal> structure to the + <literal>ucred</literal> structure. From then on, the + calling process is recognized as jailed. When the kernel + routine <literal>jailed()</literal> is called in the kernel + with the newly created <literal>ucred</literal> structure as + its argument, it returns 1 to tell that the credential is + connected with a <application>jail</application>. The + public ancestor process of all the process forked within the + <application>jail</application>, is the process which runs + &man.jail.8;, as it calls the &man.jail.2; system call. + When a program is executed through &man.execve.2;, it + inherits the jailed property of its parent's + <literal>ucred</literal> structure, therefore it has a + jailed <literal>ucred</literal> structure.</para> - <programlisting><filename>/usr/src/sys/kern/kern_jail.c</filename> + <programlisting><filename>/usr/src/sys/kern/kern_jail.c</filename> int jail(struct thread *td, struct jail_args *uap) { @@ -401,17 +428,18 @@ jail_attach(struct thread *td, struct jail_attach_args p->p_ucred = newcred; ... }</programlisting> - <para>When a process is forked from its parent process, the - &man.fork.2; system call uses <literal>crhold()</literal> to - maintain the credential for the newly forked process. It inherently - keep the newly forked child's credential consistent with its parent, - so the child process is also jailed.</para> - <programlisting><filename>/usr/src/sys/kern/kern_fork.c</filename>: + <para>When a process is forked from its parent process, the + &man.fork.2; system call uses <literal>crhold()</literal> to + maintain the credential for the newly forked process. It + inherently keep the newly forked child's credential + consistent with its parent, so the child process is also + jailed.</para> + + <programlisting><filename>/usr/src/sys/kern/kern_fork.c</filename>: p2->p_ucred = crhold(td->td_ucred); ... td2->td_ucred = crhold(p2->p_ucred);</programlisting> - </sect3> </sect2> </sect1> @@ -420,12 +448,11 @@ td2->td_ucred = crhold(p2->p_ucred);</programlis <title>Restrictions</title> <para>Throughout the kernel there are access restrictions relating - to jailed processes. Usually, these restrictions only check whether - the process is jailed, and if so, returns an error. For + to jailed processes. Usually, these restrictions only check + whether the process is jailed, and if so, returns an error. For example:</para> - <programlisting> -if (jailed(td->td_ucred)) + <programlisting>if (jailed(td->td_ucred)) return (EPERM);</programlisting> <sect2> @@ -433,112 +460,128 @@ if (jailed(td->td_ucred)) <indexterm><primary>System V IPC</primary></indexterm> - <para>System V IPC is based on messages. Processes can send each - other these messages which tell them how to act. The functions - which deal with messages are: - &man.msgctl.3;, &man.msgget.3;, &man.msgsnd.3; and &man.msgrcv.3;. - Earlier, I mentioned that there were certain sysctls you could - turn on or off in order to affect the behavior of - <application>jail</application>. One of these sysctls was - <literal>security.jail.sysvipc_allowed</literal>. By default, - this sysctl is set to 0. If it were set to 1, it would defeat the - whole purpose of having a <application>jail</application>; privileged - users from the <application>jail</application> would be able to - affect processes outside the jailed environment. The difference - between a message and a signal is that the message only consists - of the signal number.</para> + <para>System V IPC is based on messages. Processes can send + each other these messages which tell them how to act. The + functions which deal with messages are: &man.msgctl.3;, + &man.msgget.3;, &man.msgsnd.3; and &man.msgrcv.3;. Earlier, I + mentioned that there were certain sysctls you could turn on or + off in order to affect the behavior of + <application>jail</application>. One of these sysctls was + <literal>security.jail.sysvipc_allowed</literal>. By default, + this sysctl is set to 0. If it were set to 1, it would defeat + the whole purpose of having a <application>jail</application>; + privileged users from the <application>jail</application> + would be able to affect processes outside the jailed + environment. The difference between a message and a signal is + that the message only consists of the signal number.</para> <para><filename>/usr/src/sys/kern/sysv_msg.c</filename>:</para> <itemizedlist> - <listitem> <para><literal>msgget(key, msgflg)</literal>: - <literal>msgget</literal> returns (and possibly creates) a message - descriptor that designates a message queue for use in other - functions.</para></listitem> + <listitem> + <para><literal>msgget(key, msgflg)</literal>: + <literal>msgget</literal> returns (and possibly creates) a + message descriptor that designates a message queue for use + in other functions.</para> + </listitem> - <listitem> <para><literal>msgctl(msgid, cmd, buf)</literal>: - Using this function, a process can query the status of a message - descriptor.</para></listitem> + <listitem> + <para><literal>msgctl(msgid, cmd, buf)</literal>: Using this + function, a process can query the status of a message + descriptor.</para> + </listitem> - <listitem> <para><literal>msgsnd(msgid, msgp, msgsz, msgflg)</literal>: - <literal>msgsnd</literal> sends a message to a - process.</para></listitem> + <listitem> + <para><literal>msgsnd(msgid, msgp, msgsz, msgflg)</literal>: + <literal>msgsnd</literal> sends a message to a + process.</para> + </listitem> - <listitem> <para><literal>msgrcv(msgid, msgp, msgsz, msgtyp, - msgflg)</literal>: a process receives messages using - this function</para></listitem> - + <listitem> + <para><literal>msgrcv(msgid, msgp, msgsz, msgtyp, + msgflg)</literal>: a process receives messages using + this function</para> + </listitem> </itemizedlist> - <para>In each of the system calls corresponding to these functions, - there is this conditional:</para> + <para>In each of the system calls corresponding to these + functions, there is this conditional:</para> <programlisting><filename>/usr/src/sys/kern/sysv_msg.c</filename>: if (!jail_sysvipc_allowed && jailed(td->td_ucred)) return (ENOSYS);</programlisting> <indexterm><primary>semaphores</primary></indexterm> + <para>Semaphore system calls allow processes to synchronize - execution by doing a set of operations atomically on a set of - semaphores. Basically semaphores provide another way for - processes lock resources. However, process waiting on a - semaphore, that is being used, will sleep until the resources - are relinquished. The following semaphore system calls are - blocked inside a <application>jail</application>: &man.semget.2;, - &man.semctl.2; and &man.semop.2;.</para> + execution by doing a set of operations atomically on a set of + semaphores. Basically semaphores provide another way for + processes lock resources. However, process waiting on a + semaphore, that is being used, will sleep until the resources + are relinquished. The following semaphore system calls are + blocked inside a <application>jail</application>: + &man.semget.2;, &man.semctl.2; and &man.semop.2;.</para> <para><filename>/usr/src/sys/kern/sysv_sem.c</filename>:</para> <itemizedlist> - <listitem> - <para><literal>semctl(semid, semnum, cmd, ...)</literal>: - <literal>semctl</literal> does the specified <literal>cmd</literal> - on the semaphore queue indicated by - <literal>semid</literal>.</para></listitem> + <listitem> + <para><literal>semctl(semid, semnum, cmd, ...)</literal>: + <literal>semctl</literal> does the specified + <literal>cmd</literal> on the semaphore queue indicated by + <literal>semid</literal>.</para></listitem> - <listitem> - <para><literal>semget(key, nsems, flag)</literal>: - <literal>semget</literal> creates an array of semaphores, - corresponding to <literal>key</literal>.</para> + <listitem> + <para><literal>semget(key, nsems, flag)</literal>: + <literal>semget</literal> creates an array of semaphores, + corresponding to <literal>key</literal>.</para> - <para><literal>key and flag take on the same meaning as they - do in msgget.</literal></para></listitem> + <para><literal>key and flag take on the same meaning as they + do in msgget.</literal></para> + </listitem> - <listitem><para><literal>semop(semid, array, nops)</literal>: - <literal>semop</literal> performs a group of operations indicated - by <literal>array</literal>, to the set of semaphores identified by - <literal>semid</literal>.</para></listitem> + <listitem><para><literal>semop(semid, array, nops)</literal>: + <literal>semop</literal> performs a group of operations + indicated by <literal>array</literal>, to the set of + semaphores identified by + <literal>semid</literal>.</para></listitem> </itemizedlist> <indexterm><primary>shared memory</primary></indexterm> - <para>System V IPC allows for processes to share - memory. Processes can communicate directly with each other by - sharing parts of their virtual address space and then reading - and writing data stored in the shared memory. These system - calls are blocked within a jailed environment: &man.shmdt.2;, - &man.shmat.2;, &man.shmctl.2; and &man.shmget.2;.</para> + <para>System V IPC allows for processes to share memory. + Processes can communicate directly with each other by sharing + parts of their virtual address space and then reading and + writing data stored in the shared memory. These system calls + are blocked within a jailed environment: &man.shmdt.2;, + &man.shmat.2;, &man.shmctl.2; and &man.shmget.2;.</para> + <para><filename>/usr/src/sys/kern/sysv_shm.c</filename>:</para> <itemizedlist> - <listitem><para><literal>shmctl(shmid, cmd, buf)</literal>: - <literal>shmctl</literal> does various control operations on the - shared memory region identified by - <literal>shmid</literal>.</para></listitem> + <listitem><para><literal>shmctl(shmid, cmd, buf)</literal>: + <literal>shmctl</literal> does various control operations + on the shared memory region identified by + <literal>shmid</literal>.</para> + </listitem> - <listitem><para><literal>shmget(key, size, flag)</literal>: - <literal>shmget</literal> accesses or creates a shared memory - region of <literal>size</literal> bytes.</para></listitem> + <listitem><para><literal>shmget(key, size, flag)</literal>: + <literal>shmget</literal> accesses or creates a shared + memory region of <literal>size</literal> + bytes.</para> + </listitem> - <listitem><para><literal>shmat(shmid, addr, flag)</literal>: - <literal>shmat</literal> attaches a shared memory region identified - by <literal>shmid</literal> to the address space of a - process.</para></listitem> + <listitem><para><literal>shmat(shmid, addr, flag)</literal>: + <literal>shmat</literal> attaches a shared memory region + identified by <literal>shmid</literal> to the address + space of a process.</para> + </listitem> - <listitem><para><literal>shmdt(addr)</literal>: - <literal>shmdt</literal> detaches the shared memory region - previously attached at <literal>addr</literal>.</para></listitem> - + <listitem><para><literal>shmdt(addr)</literal>: + <literal>shmdt</literal> detaches the shared memory region + previously attached at + <literal>addr</literal>.</para> + </listitem> </itemizedlist> </sect2> @@ -546,17 +589,18 @@ if (!jail_sysvipc_allowed && jailed(td->td_ <title>Sockets</title> <indexterm><primary>sockets</primary></indexterm> - <para><application>Jail</application> treats the &man.socket.2; system - call and related lower-level socket functions in a special manner. - In order to determine whether a certain socket is allowed to be - created, it first checks to see if the sysctl - <literal>security.jail.socket_unixiproute_only</literal> is set. If - set, sockets are only allowed to be created if the family - specified is either <literal>PF_LOCAL</literal>, - <literal>PF_INET</literal> or - <literal>PF_ROUTE</literal>. Otherwise, it returns an - error.</para> + <para><application>Jail</application> treats the &man.socket.2; + system call and related lower-level socket functions in a + special manner. In order to determine whether a certain + socket is allowed to be created, it first checks to see if the + sysctl + <literal>security.jail.socket_unixiproute_only</literal> is + set. If set, sockets are only allowed to be created if the + family specified is either <literal>PF_LOCAL</literal>, + <literal>PF_INET</literal> or <literal>PF_ROUTE</literal>. + Otherwise, it returns an error.</para> + <programlisting><filename>/usr/src/sys/kern/uipc_socket.c</filename>: int socreate(int dom, struct socket **aso, int type, int proto, @@ -572,7 +616,6 @@ socreate(int dom, struct socket **aso, int type, int p } ... }</programlisting> - </sect2> <sect2> @@ -581,10 +624,11 @@ socreate(int dom, struct socket **aso, int type, int p <indexterm><primary>Berkeley Packet Filter</primary></indexterm> <indexterm><primary>data link layer</primary></indexterm> - <para>The <application>Berkeley Packet Filter</application> provides - a raw interface to data link layers in a protocol independent - fashion. <application>BPF</application> is now controlled by the - &man.devfs.8; whether it can be used in a jailed environment.</para> + <para>The <application>Berkeley Packet Filter</application> + provides a raw interface to data link layers in a protocol + independent fashion. <application>BPF</application> is now + controlled by the &man.devfs.8; whether it can be used in a + jailed environment.</para> </sect2> @@ -594,23 +638,25 @@ socreate(int dom, struct socket **aso, int type, int p <indexterm><primary>protocols</primary></indexterm> <para>There are certain protocols which are very common, such as - TCP, UDP, IP and ICMP. IP and ICMP are on the same level: the - network layer 2. There are certain precautions which are - taken in order to prevent a jailed process from binding a - protocol to a certain address only if the <literal>nam</literal> - parameter is set. <literal>nam</literal> is a pointer to a - <literal>sockaddr</literal> structure, - which describes the address on which to bind the service. A - more exact definition is that <literal>sockaddr</literal> "may be - used as a template for referring to the identifying tag and length of - each address". In the function - <literal>in_pcbbind_setup()</literal>, <literal>sin</literal> is a - pointer to a <literal>sockaddr_in</literal> structure, which - contains the port, address, length and domain family of the socket - which is to be bound. Basically, this disallows any processes from - <application>jail</application> to be able to specify the address - that does not belong to the <application>jail</application> in which - the calling process exists.</para> + TCP, UDP, IP and ICMP. IP and ICMP are on the same level: the + network layer 2. There are certain precautions which are + taken in order to prevent a jailed process from binding a + protocol to a certain address only if the + <literal>nam</literal> parameter is set. + <literal>nam</literal> is a pointer to a + <literal>sockaddr</literal> structure, which describes the + address on which to bind the service. A more exact definition + is that <literal>sockaddr</literal> "may be used as a template + for referring to the identifying tag and length of each + address". In the function + <literal>in_pcbbind_setup()</literal>, <literal>sin</literal> + is a pointer to a <literal>sockaddr_in</literal> structure, + which contains the port, address, length and domain family of + the socket which is to be bound. Basically, this disallows + any processes from <application>jail</application> to be able + to specify the address that does not belong to the + <application>jail</application> in which the calling process + exists.</para> <programlisting><filename>/usr/src/sys/netinet/in_pcb.c</filename>: int @@ -648,14 +694,15 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *n }</programlisting> <para>You might be wondering what function - <literal>prison_ip()</literal> does. <literal>prison_ip()</literal> - is given three arguments, a pointer to the credential(represented by - <literal>cred</literal>), any flags, and an IP address. It - returns 1 if the IP address does NOT belong to the - <application>jail</application> or 0 otherwise. As you can see - from the code, if it is indeed an IP address not belonging to the - <application>jail</application>, the protocol is not allowed to bind - to that address.</para> + <literal>prison_ip()</literal> does. + <literal>prison_ip()</literal> is given three arguments, a + pointer to the credential(represented by + <literal>cred</literal>), any flags, and an IP address. It + returns 1 if the IP address does NOT belong to the + <application>jail</application> or 0 otherwise. As you can + see from the code, if it is indeed an IP address not belonging + to the <application>jail</application>, the protocol is not + allowed to bind to that address.</para> <programlisting><filename>/usr/src/sys/kern/kern_jail.c:</filename> int @@ -693,10 +740,12 @@ prison_ip(struct ucred *cred, int flag, u_int32_t *ip) <title>Filesystem</title> <indexterm><primary>filesystem</primary></indexterm> + <para>Even <literal>root</literal> users within the - <application>jail</application> are not allowed to unset or modify - any file flags, such as immutable, append-only, and undeleteable - flags, if the securelevel is greater than 0.</para> + <application>jail</application> are not allowed to unset or + modify any file flags, such as immutable, append-only, and + undeleteable flags, if the securelevel is greater than + 0.</para> <programlisting><filename>/usr/src/sys/ufs/ufs/ufs_vnops.c:</filename> static int @@ -741,7 +790,5 @@ prison_priv_check(struct ucred *cred, int priv) ... }</programlisting> </sect2> - </sect1> - </chapter>
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201808261556.w7QFujta027786>