Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-doc
Path: blob/main/documentation/content/en/books/arch-handbook/jail/_index.po
18099 views
# SOME DESCRIPTIVE TITLE
# Copyright (C) YEAR The FreeBSD Project
# This file is distributed under the same license as the FreeBSD Documentation package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: FreeBSD Documentation VERSION\n"
"POT-Creation-Date: 2025-11-08 16:17+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#. type: Title =
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:1
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:14
#, no-wrap
msgid "The Jail Subsystem"
msgstr ""

#. type: YAML Front Matter: title
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:1
#, no-wrap
msgid "Chapter 4. The Jail Subsystem"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:52
msgid ""
"On most UNIX(R) systems, `root` has omnipotent power. This promotes "
"insecurity. If an attacker gained `root` on a system, he would have every "
"function at his fingertips. In FreeBSD there are sysctls which dilute the "
"power of `root`, in order to minimize the damage caused by an attacker. "
"Specifically, one of these functions is called `secure levels`. Similarly, "
"another function which is present from FreeBSD 4.0 and onward, is a utility "
"called man:jail[8]. Jail chroots an environment and sets certain "
"restrictions on processes which are forked within the jail. For example, a "
"jailed process cannot affect processes outside the jail, utilize certain "
"system calls, or inflict any damage on the host environment."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:54
msgid ""
"Jail is becoming the new security model. People are running potentially "
"vulnerable servers such as Apache, BIND, and sendmail within jails, so that "
"if an attacker gains `root` within the jail, it is only an annoyance, and "
"not a devastation. This article mainly focuses on the internals (source "
"code) of jail. For information on how to set up a jail see the extref:"
"{handbook}jails[handbook entry on jails, jails]."
msgstr ""

#. type: Title ==
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:56
#, no-wrap
msgid "Architecture"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:59
msgid ""
"Jail 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 then how jail is "
"implemented within the kernel."
msgstr ""

#. type: Title ===
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:60
#, no-wrap
msgid "Userland Code"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:63
msgid ""
"The source for the userland jail is located in [.filename]#/usr/src/usr.sbin/"
"jail#, consisting of one file, [.filename]#jail.c#. The program takes these "
"arguments: the path of the jail, hostname, IP address, and the command to be "
"executed."
msgstr ""

#. type: Title ====
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:64
#, no-wrap
msgid "Data Structures"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:67
msgid ""
"In [.filename]#jail.c#, the first thing I would note is the declaration of "
"an important structure `struct jail j;` which was included from [.filename]#/"
"usr/include/sys/jail.h#."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:69
msgid "The definition of the `jail` structure is:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:73
#, no-wrap
msgid "/usr/include/sys/jail.h:\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:80
#, no-wrap
msgid ""
"struct jail {\n"
"        u_int32_t       version;\n"
"        char            *path;\n"
"        char            *hostname;\n"
"        u_int32_t       ip_number;\n"
"};\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:83
msgid ""
"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."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:97
#, no-wrap
msgid ""
"/usr/src/usr.sbin/jail/jail.c\n"
"char path[PATH_MAX];\n"
"...\n"
"if (realpath(argv[0], path) == NULL)\n"
"    err(1, \"realpath: %s\", argv[0]);\n"
"if (chdir(path) != 0)\n"
"    err(1, \"chdir: %s\", path);\n"
"memset(&j, 0, sizeof(j));\n"
"j.version = 0;\n"
"j.path = path;\n"
"j.hostname = argv[1];\n"
msgstr ""

#. type: Title ====
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:99
#, no-wrap
msgid "Networking"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:102
msgid ""
"One of the arguments passed to the man:jail[8] program is an IP address with "
"which the jail can be accessed over the network. man:jail[8] translates the "
"IP address given into host byte order and then stores it in `j` (the `jail` "
"structure)."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:111
#, no-wrap
msgid ""
"/usr/src/usr.sbin/jail/jail.c:\n"
"struct in_addr in;\n"
"...\n"
"if (inet_aton(argv[2], &in) == 0)\n"
"    errx(1, \"Could not make sense of ip-number: %s\", argv[2]);\n"
"j.ip_number = ntohl(in.s_addr);\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:114
msgid ""
"The man:inet_aton[3] function \"interprets the specified character string as "
"an Internet address, placing the address into the structure provided.\" The "
"`ip_number` member in the `jail` structure is set only when the IP address "
"placed onto the `in` structure by man:inet_aton[3] is translated into host "
"byte order by man:ntohl[3]."
msgstr ""

#. type: Title ====
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:115
#, no-wrap
msgid "Jailing the Process"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:118
msgid ""
"Finally, the userland program jails the process. Jail now becomes an "
"imprisoned process itself and then executes the command given using "
"man:execv[3]."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:126
#, no-wrap
msgid ""
"/usr/src/usr.sbin/jail/jail.c\n"
"i = jail(&j);\n"
"...\n"
"if (execv(argv[3], argv + 3) != 0)\n"
"    err(1, \"execv: %s\", argv[3]);\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:129
msgid ""
"As you can see, the `jail()` function is called, and its argument is the "
"`jail` structure which has been filled with the arguments given to the "
"program. Finally, the program you specify is executed. I will now discuss "
"how jail is implemented within the kernel."
msgstr ""

#. type: Title ===
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:130
#, no-wrap
msgid "Kernel Space"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:133
msgid ""
"We will now be looking at the file [.filename]#/usr/src/sys/kern/"
"kern_jail.c#. This is the file where the man:jail[2] system call, "
"appropriate sysctls, and networking functions are defined."
msgstr ""

#. type: Title ====
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:134
#, no-wrap
msgid "Sysctls"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:137
msgid "In [.filename]#kern_jail.c#, the following sysctls are defined:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:145
#, no-wrap
msgid ""
"/usr/src/sys/kern/kern_jail.c:\n"
"int     jail_set_hostname_allowed = 1;\n"
"SYSCTL_INT(_security_jail, OID_AUTO, set_hostname_allowed, CTLFLAG_RW,\n"
"    &jail_set_hostname_allowed, 0,\n"
"    \"Processes in jail can set their hostnames\");\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:150
#, no-wrap
msgid ""
"int     jail_socket_unixiproute_only = 1;\n"
"SYSCTL_INT(_security_jail, OID_AUTO, socket_unixiproute_only, CTLFLAG_RW,\n"
"    &jail_socket_unixiproute_only, 0,\n"
"    \"Processes in jail are limited to creating UNIX/IPv4/route sockets only\");\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:155
#, no-wrap
msgid ""
"int     jail_sysvipc_allowed = 0;\n"
"SYSCTL_INT(_security_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW,\n"
"    &jail_sysvipc_allowed, 0,\n"
"    \"Processes in jail can use System V IPC primitives\");\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:160
#, no-wrap
msgid ""
"static int jail_enforce_statfs = 2;\n"
"SYSCTL_INT(_security_jail, OID_AUTO, enforce_statfs, CTLFLAG_RW,\n"
"    &jail_enforce_statfs, 0,\n"
"    \"Processes in jail cannot see all mounted file systems\");\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:165
#, no-wrap
msgid ""
"int    jail_allow_raw_sockets = 0;\n"
"SYSCTL_INT(_security_jail, OID_AUTO, allow_raw_sockets, CTLFLAG_RW,\n"
"    &jail_allow_raw_sockets, 0,\n"
"    \"Prison root can create raw sockets\");\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:170
#, no-wrap
msgid ""
"int    jail_chflags_allowed = 0;\n"
"SYSCTL_INT(_security_jail, OID_AUTO, chflags_allowed, CTLFLAG_RW,\n"
"    &jail_chflags_allowed, 0,\n"
"    \"Processes in jail can alter system file flags\");\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:175
#, no-wrap
msgid ""
"int     jail_mount_allowed = 0;\n"
"SYSCTL_INT(_security_jail, OID_AUTO, mount_allowed, CTLFLAG_RW,\n"
"    &jail_mount_allowed, 0,\n"
"    \"Processes in jail can mount/unmount jail-friendly file systems\");\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:178
msgid ""
"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 "
"`security.jail.set_hostname_allowed`."
msgstr ""

#. type: Title ====
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:179
#, no-wrap
msgid "man:jail[2] System Call"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:182
msgid ""
"Like all system calls, the man:jail[2] system call takes two arguments, "
"`struct thread *td` and `struct jail_args *uap`. `td` is a pointer to the "
"`thread` structure which describes the calling thread. In this context, "
"`uap` is a pointer to the structure in which a pointer to the `jail` "
"structure passed by the userland [.filename]#jail.c# is contained. When I "
"described the userland program before, you saw that the man:jail[2] system "
"call was given a `jail` structure as its own argument."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:193
#, no-wrap
msgid ""
"/usr/src/sys/kern/kern_jail.c:\n"
"/*\n"
" * struct jail_args {\n"
" *  struct jail *jail;\n"
" * };\n"
" */\n"
"int\n"
"jail(struct thread *td, struct jail_args *uap)\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:196
msgid ""
"Therefore, `uap->jail` can be used to access the `jail` structure which was "
"passed to the system call. Next, the system call copies the `jail` 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, `uap->jail`, where to store it, `j` and the size of the storage. The "
"`jail` structure pointed by `uap->jail` is copied into kernel space and is "
"stored in another `jail` structure, `j`."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:201
#, no-wrap
msgid ""
"/usr/src/sys/kern/kern_jail.c:\n"
"error = copyin(uap->jail, &j, sizeof(j));\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:204
msgid ""
"There is another important structure defined in [.filename]#jail.h#. It is "
"the `prison` structure. The `prison` structure is used exclusively within "
"kernel space. Here is the definition of the `prison` structure."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:222
#, no-wrap
msgid ""
"/usr/include/sys/jail.h:\n"
"struct prison {\n"
"        LIST_ENTRY(prison) pr_list;                     /* (a) all prisons */\n"
"        int              pr_id;                         /* (c) prison id */\n"
"        int              pr_ref;                        /* (p) refcount */\n"
"        char             pr_path[MAXPATHLEN];           /* (c) chroot path */\n"
"        struct vnode    *pr_root;                       /* (c) vnode to rdir */\n"
"        char             pr_host[MAXHOSTNAMELEN];       /* (p) jail hostname */\n"
"        u_int32_t        pr_ip;                         /* (c) ip addr host */\n"
"        void            *pr_linux;                      /* (p) linux abi */\n"
"        int              pr_securelevel;                /* (p) securelevel */\n"
"        struct task      pr_task;                       /* (d) destroy task */\n"
"        struct mtx       pr_mtx;\n"
"      void            **pr_slots;                     /* (p) additional data */\n"
"};\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:225
msgid ""
"The man:jail[2] system call then allocates memory for a `prison` structure "
"and copies data between the `jail` and `prison` structure."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:239
#, no-wrap
msgid ""
"/usr/src/sys/kern/kern_jail.c:\n"
"MALLOC(pr, struct prison *, sizeof(*pr), M_PRISON, M_WAITOK | M_ZERO);\n"
"...\n"
"error = copyinstr(j.path, &pr->pr_path, sizeof(pr->pr_path), 0);\n"
"if (error)\n"
"    goto e_killmtx;\n"
"...\n"
"error = copyinstr(j.hostname, &pr->pr_host, sizeof(pr->pr_host), 0);\n"
"if (error)\n"
"     goto e_dropvnref;\n"
"pr->pr_ip = j.ip_number;\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:242
msgid ""
"Next, we will discuss another important system call man:jail_attach[2], "
"which implements the function to put a process into the jail."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:253
#, no-wrap
msgid ""
"/usr/src/sys/kern/kern_jail.c:\n"
"/*\n"
" * struct jail_attach_args {\n"
" *      int jid;\n"
" * };\n"
" */\n"
"int\n"
"jail_attach(struct thread *td, struct jail_attach_args *uap)\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:256
msgid ""
"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."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:258
msgid ""
"On FreeBSD, each kernel visible thread is identified by its `thread` "
"structure, while the processes are described by their `proc` structures. You "
"can find the definitions of the `thread` and `proc` structure in "
"[.filename]#/usr/include/sys/proc.h#. For example, the `td` argument in any "
"system call is actually a pointer to the calling thread's `thread` "
"structure, as stated before. The `td_proc` member in the `thread` structure "
"pointed by `td` is a pointer to the `proc` structure which represents the "
"process that contains the thread represented by `td`. The `proc` structure "
"contains members which can describe the owner's identity(`p_ucred`), the "
"process resource limits(`p_limit`), and so on. In the `ucred` structure "
"pointed by `p_ucred` member in the `proc` structure, there is a pointer to "
"the `prison` structure(`cr_prison`)."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:278
#, no-wrap
msgid ""
"/usr/include/sys/proc.h:\n"
"struct thread {\n"
"    ...\n"
"    struct proc *td_proc;\n"
"    ...\n"
"};\n"
"struct proc {\n"
"    ...\n"
"    struct ucred *p_ucred;\n"
"    ...\n"
"};\n"
"/usr/include/sys/ucred.h\n"
"struct ucred {\n"
"    ...\n"
"    struct prison *cr_prison;\n"
"    ...\n"
"};\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:281
msgid ""
"In [.filename]#kern_jail.c#, the function `jail()` then calls function "
"`jail_attach()` with a given `jid`. And `jail_attach()` calls function "
"`change_root()` to change the root directory of the calling process. The "
"`jail_attach()` then creates a new `ucred` structure, and attaches the newly "
"created `ucred` structure to the calling process after it has successfully "
"attached the `prison` structure to the `ucred` structure. From then on, the "
"calling process is recognized as jailed. When the kernel routine `jailed()` "
"is called in the kernel with the newly created `ucred` structure as its "
"argument, it returns 1 to tell that the credential is connected with a jail. "
"The public ancestor process of all the process forked within the jail, 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 `ucred` structure, therefore it has a jailed "
"`ucred` structure."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:296
#, no-wrap
msgid ""
"/usr/src/sys/kern/kern_jail.c\n"
"int\n"
"jail(struct thread *td, struct jail_args *uap)\n"
"{\n"
"...\n"
"    struct jail_attach_args jaa;\n"
"...\n"
"    error = jail_attach(td, &jaa);\n"
"    if (error)\n"
"        goto e_dropprref;\n"
"...\n"
"}\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:314
#, no-wrap
msgid ""
"int\n"
"jail_attach(struct thread *td, struct jail_attach_args *uap)\n"
"{\n"
"    struct proc *p;\n"
"    struct ucred *newcred, *oldcred;\n"
"    struct prison *pr;\n"
"...\n"
"    p = td->td_proc;\n"
"...\n"
"    pr = prison_find(uap->jid);\n"
"...\n"
"    change_root(pr->pr_root, td);\n"
"...\n"
"    newcred->cr_prison = pr;\n"
"    p->p_ucred = newcred;\n"
"...\n"
"}\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:317
msgid ""
"When a process is forked from its parent process, the man:fork[2] system "
"call uses `crhold()` 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."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:324
#, no-wrap
msgid ""
"/usr/src/sys/kern/kern_fork.c:\n"
"p2->p_ucred = crhold(td->td_ucred);\n"
"...\n"
"td2->td_ucred = crhold(p2->p_ucred);\n"
msgstr ""

#. type: Title ==
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:327
#, no-wrap
msgid "Restrictions"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:330
msgid ""
"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 example:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:335
#, no-wrap
msgid ""
"if (jailed(td->td_ucred))\n"
"    return (EPERM);\n"
msgstr ""

#. type: Title ===
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:337
#, no-wrap
msgid "SysV IPC"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:340
msgid ""
"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 jail. One of these sysctls was "
"`security.jail.sysvipc_allowed`. By default, this sysctl is set to 0. If it "
"were set to 1, it would defeat the whole purpose of having a jail; "
"privileged users from the jail 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."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:342
msgid "[.filename]#/usr/src/sys/kern/sysv_msg.c#:"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:344
msgid ""
"`msgget(key, msgflg)`: `msgget` returns (and possibly creates) a message "
"descriptor that designates a message queue for use in other functions."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:345
msgid ""
"`msgctl(msgid, cmd, buf)`: Using this function, a process can query the "
"status of a message descriptor."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:346
msgid ""
"`msgsnd(msgid, msgp, msgsz, msgflg)`: `msgsnd` sends a message to a process."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:347
msgid ""
"`msgrcv(msgid, msgp, msgsz, msgtyp, msgflg)`: a process receives messages "
"using this function"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:349
msgid ""
"In each of the system calls corresponding to these functions, there is this "
"conditional:"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:355
#, no-wrap
msgid ""
"/usr/src/sys/kern/sysv_msg.c:\n"
"if (!jail_sysvipc_allowed && jailed(td->td_ucred))\n"
"    return (ENOSYS);\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:358
msgid ""
"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 "
"jail: man:semget[2], man:semctl[2] and man:semop[2]."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:360
msgid "[.filename]#/usr/src/sys/kern/sysv_sem.c#:"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:362
msgid ""
"`semctl(semid, semnum, cmd, ...)`: `semctl` does the specified `cmd` on the "
"semaphore queue indicated by `semid`."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:363
msgid ""
"`semget(key, nsems, flag)`: `semget` creates an array of semaphores, "
"corresponding to `key`."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:365
msgid "`key and flag take on the same meaning as they do in msgget.`"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:366
msgid ""
"`semop(semid, array, nops)`: `semop` performs a group of operations "
"indicated by `array`, to the set of semaphores identified by `semid`."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:368
msgid ""
"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]."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:370
msgid "[.filename]#/usr/src/sys/kern/sysv_shm.c#:"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:372
msgid ""
"`shmctl(shmid, cmd, buf)`: `shmctl` does various control operations on the "
"shared memory region identified by `shmid`."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:373
msgid ""
"`shmget(key, size, flag)`: `shmget` accesses or creates a shared memory "
"region of `size` bytes."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:374
msgid ""
"`shmat(shmid, addr, flag)`: `shmat` attaches a shared memory region "
"identified by `shmid` to the address space of a process."
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:375
msgid ""
"`shmdt(addr)`: `shmdt` detaches the shared memory region previously attached "
"at `addr`."
msgstr ""

#. type: Title ===
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:376
#, no-wrap
msgid "Sockets"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:379
msgid ""
"Jail 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 "
"`security.jail.socket_unixiproute_only` is set. If set, sockets are only "
"allowed to be created if the family specified is either `PF_LOCAL`, "
"`PF_INET` or `PF_ROUTE`. Otherwise, it returns an error."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:397
#, no-wrap
msgid ""
"/usr/src/sys/kern/uipc_socket.c:\n"
"int\n"
"socreate(int dom, struct socket **aso, int type, int proto,\n"
"    struct ucred *cred, struct thread *td)\n"
"{\n"
"    struct protosw *prp;\n"
"...\n"
"    if (jailed(cred) && jail_socket_unixiproute_only &&\n"
"        prp->pr_domain->dom_family != PF_LOCAL &&\n"
"        prp->pr_domain->dom_family != PF_INET &&\n"
"        prp->pr_domain->dom_family != PF_ROUTE) {\n"
"        return (EPROTONOSUPPORT);\n"
"    }\n"
"...\n"
"}\n"
msgstr ""

#. type: Title ===
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:399
#, no-wrap
msgid "Berkeley Packet Filter"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:402
msgid ""
"The Berkeley Packet Filter provides a raw interface to data link layers in a "
"protocol independent fashion. BPF is now controlled by the man:devfs[8] "
"whether it can be used in a jailed environment."
msgstr ""

#. type: Title ===
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:403
#, no-wrap
msgid "Protocols"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:406
msgid ""
"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 `nam` parameter is "
"set. `nam` is a pointer to a `sockaddr` structure, which describes the "
"address on which to bind the service. A more exact definition is that "
"`sockaddr` \"may be used as a template for referring to the identifying tag "
"and length of each address\". In the function `in_pcbbind_setup()`, `sin` is "
"a pointer to a `sockaddr_in` structure, which contains the port, address, "
"length and domain family of the socket which is to be bound. Basically, this "
"disallows any processes from jail to be able to specify the address that "
"does not belong to the jail in which the calling process exists."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:443
#, no-wrap
msgid ""
"/usr/src/sys/netinet/in_pcb.c:\n"
"int\n"
"in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,\n"
"    u_short *lportp, struct ucred *cred)\n"
"{\n"
"    ...\n"
"    struct sockaddr_in *sin;\n"
"    ...\n"
"    if (nam) {\n"
"        sin = (struct sockaddr_in *)nam;\n"
"        ...\n"
"        if (sin->sin_addr.s_addr != INADDR_ANY)\n"
"            if (prison_ip(cred, 0, &sin->sin_addr.s_addr))\n"
"                return(EINVAL);\n"
"        ...\n"
"        if (lport) {\n"
"            ...\n"
"            if (prison && prison_ip(cred, 0, &sin->sin_addr.s_addr))\n"
"                return (EADDRNOTAVAIL);\n"
"            ...\n"
"        }\n"
"    }\n"
"    if (lport == 0) {\n"
"        ...\n"
"        if (laddr.s_addr != INADDR_ANY)\n"
"            if (prison_ip(cred, 0, &laddr.s_addr))\n"
"                return (EINVAL);\n"
"        ...\n"
"    }\n"
"...\n"
"    if (prison_ip(cred, 0, &laddr.s_addr))\n"
"        return (EINVAL);\n"
"...\n"
"}\n"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:446
msgid ""
"You might be wondering what function `prison_ip()` does. `prison_ip()` is "
"given three arguments, a pointer to the credential(represented by `cred`), "
"any flags, and an IP address. It returns 1 if the IP address does NOT belong "
"to the jail or 0 otherwise. As you can see from the code, if it is indeed an "
"IP address not belonging to the jail, the protocol is not allowed to bind to "
"that address."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:454
#, no-wrap
msgid ""
"/usr/src/sys/kern/kern_jail.c:\n"
"int\n"
"prison_ip(struct ucred *cred, int flag, u_int32_t *ip)\n"
"{\n"
"    u_int32_t tmp;\n"
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:479
#, no-wrap
msgid ""
"    if (!jailed(cred))\n"
"        return (0);\n"
"    if (flag)\n"
"        tmp = *ip;\n"
"    else\n"
"        tmp = ntohl(*ip);\n"
"    if (tmp == INADDR_ANY) {\n"
"        if (flag)\n"
"            *ip = cred->cr_prison->pr_ip;\n"
"        else\n"
"            *ip = htonl(cred->cr_prison->pr_ip);\n"
"        return (0);\n"
"    }\n"
"    if (tmp == INADDR_LOOPBACK) {\n"
"        if (flag)\n"
"            *ip = cred->cr_prison->pr_ip;\n"
"        else\n"
"            *ip = htonl(cred->cr_prison->pr_ip);\n"
"        return (0);\n"
"    }\n"
"    if (cred->cr_prison->pr_ip != tmp)\n"
"        return (1);\n"
"    return (0);\n"
"}\n"
msgstr ""

#. type: Title ===
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:481
#, no-wrap
msgid "Filesystem"
msgstr ""

#. type: Plain text
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:484
msgid ""
"Even `root` users within the jail 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."
msgstr ""

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/jail/_index.adoc:529
#, no-wrap
msgid ""
"/usr/src/sys/ufs/ufs/ufs_vnops.c:\n"
"static int\n"
"ufs_setattr(ap)\n"
"    ...\n"
"{\n"
"    ...\n"
"        if (!priv_check_cred(cred, PRIV_VFS_SYSFLAGS, 0)) {\n"
"            if (ip->i_flags\n"
"                & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) {\n"
"                    error = securelevel_gt(cred, 0);\n"
"                    if (error)\n"
"                        return (error);\n"
"            }\n"
"            ...\n"
"        }\n"
"}\n"
"/usr/src/sys/kern/kern_priv.c\n"
"int\n"
"priv_check_cred(struct ucred *cred, int priv, int flags)\n"
"{\n"
"    ...\n"
"    error = prison_priv_check(cred, priv);\n"
"    if (error)\n"
"        return (error);\n"
"    ...\n"
"}\n"
"/usr/src/sys/kern/kern_jail.c\n"
"int\n"
"prison_priv_check(struct ucred *cred, int priv)\n"
"{\n"
"    ...\n"
"    switch (priv) {\n"
"    ...\n"
"    case PRIV_VFS_SYSFLAGS:\n"
"        if (jail_chflags_allowed)\n"
"            return (0);\n"
"        else\n"
"            return (EPERM);\n"
"    ...\n"
"    }\n"
"    ...\n"
"}\n"
msgstr ""