The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/kern_jail.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * ----------------------------------------------------------------------------
    3  * "THE BEER-WARE LICENSE" (Revision 42):
    4  * <phk@FreeBSD.ORG> wrote this file.  As long as you retain this notice you
    5  * can do whatever you want with this stuff. If we meet some day, and you think
    6  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
    7  * ----------------------------------------------------------------------------
    8  *
    9  * $FreeBSD: releng/5.0/sys/kern/kern_jail.c 108086 2002-12-19 09:40:13Z alfred $
   10  *
   11  */
   12 
   13 #include <sys/param.h>
   14 #include <sys/types.h>
   15 #include <sys/kernel.h>
   16 #include <sys/systm.h>
   17 #include <sys/errno.h>
   18 #include <sys/sysproto.h>
   19 #include <sys/malloc.h>
   20 #include <sys/proc.h>
   21 #include <sys/jail.h>
   22 #include <sys/lock.h>
   23 #include <sys/mutex.h>
   24 #include <sys/socket.h>
   25 #include <sys/sysctl.h>
   26 #include <net/if.h>
   27 #include <netinet/in.h>
   28 
   29 MALLOC_DEFINE(M_PRISON, "prison", "Prison structures");
   30 
   31 SYSCTL_DECL(_security);
   32 SYSCTL_NODE(_security, OID_AUTO, jail, CTLFLAG_RW, 0,
   33     "Jail rules");
   34 
   35 mp_fixme("these variables need a lock")
   36 
   37 int     jail_set_hostname_allowed = 1;
   38 SYSCTL_INT(_security_jail, OID_AUTO, set_hostname_allowed, CTLFLAG_RW,
   39     &jail_set_hostname_allowed, 0,
   40     "Processes in jail can set their hostnames");
   41 
   42 int     jail_socket_unixiproute_only = 1;
   43 SYSCTL_INT(_security_jail, OID_AUTO, socket_unixiproute_only, CTLFLAG_RW,
   44     &jail_socket_unixiproute_only, 0,
   45     "Processes in jail are limited to creating UNIX/IPv4/route sockets only");
   46 
   47 int     jail_sysvipc_allowed = 0;
   48 SYSCTL_INT(_security_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW,
   49     &jail_sysvipc_allowed, 0,
   50     "Processes in jail can use System V IPC primitives");
   51 
   52 /*
   53  * MPSAFE
   54  */
   55 int
   56 jail(td, uap)
   57         struct thread *td;
   58         struct jail_args /* {
   59                 struct jail *jail;
   60         } */ *uap;
   61 {
   62         struct proc *p = td->td_proc;
   63         int error;
   64         struct prison *pr;
   65         struct jail j;
   66         struct chroot_args ca;
   67         struct ucred *newcred = NULL, *oldcred;
   68 
   69         error = copyin(uap->jail, &j, sizeof j);
   70         if (error)
   71                 return (error);
   72         if (j.version != 0)
   73                 return (EINVAL);
   74 
   75         MALLOC(pr, struct prison *, sizeof *pr , M_PRISON, M_WAITOK | M_ZERO);
   76         mtx_init(&pr->pr_mtx, "jail mutex", NULL, MTX_DEF);
   77         pr->pr_securelevel = securelevel;
   78         error = copyinstr(j.hostname, &pr->pr_host, sizeof pr->pr_host, 0);
   79         if (error)
   80                 goto bail;
   81         ca.path = j.path;
   82         mtx_lock(&Giant);
   83         error = chroot(td, &ca);
   84         mtx_unlock(&Giant);
   85         if (error)
   86                 goto bail;
   87         newcred = crget();
   88         pr->pr_ip = j.ip_number;
   89         PROC_LOCK(p);
   90         /* Implicitly fail if already in jail.  */
   91         error = suser_cred(p->p_ucred, 0);
   92         if (error)
   93                 goto badcred;
   94         oldcred = p->p_ucred;
   95         crcopy(newcred, oldcred);
   96         p->p_ucred = newcred;
   97         p->p_ucred->cr_prison = pr;
   98         pr->pr_ref = 1;
   99         PROC_UNLOCK(p);
  100         crfree(oldcred);
  101         return (0);
  102 badcred:
  103         PROC_UNLOCK(p);
  104         crfree(newcred);
  105 bail:
  106         FREE(pr, M_PRISON);
  107         return (error);
  108 }
  109 
  110 void
  111 prison_free(struct prison *pr)
  112 {
  113 
  114         mtx_lock(&pr->pr_mtx);
  115         pr->pr_ref--;
  116         if (pr->pr_ref == 0) {
  117                 mtx_unlock(&pr->pr_mtx);
  118                 mtx_destroy(&pr->pr_mtx);
  119                 if (pr->pr_linux != NULL)
  120                         FREE(pr->pr_linux, M_PRISON);
  121                 FREE(pr, M_PRISON);
  122                 return;
  123         }
  124         mtx_unlock(&pr->pr_mtx);
  125 }
  126 
  127 void
  128 prison_hold(struct prison *pr)
  129 {
  130 
  131         mtx_lock(&pr->pr_mtx);
  132         pr->pr_ref++;
  133         mtx_unlock(&pr->pr_mtx);
  134 }
  135 
  136 u_int32_t
  137 prison_getip(struct ucred *cred)
  138 {
  139 
  140         return (cred->cr_prison->pr_ip);
  141 }
  142 
  143 int
  144 prison_ip(struct ucred *cred, int flag, u_int32_t *ip)
  145 {
  146         u_int32_t tmp;
  147 
  148         if (!jailed(cred))
  149                 return (0);
  150         if (flag) 
  151                 tmp = *ip;
  152         else
  153                 tmp = ntohl(*ip);
  154         if (tmp == INADDR_ANY) {
  155                 if (flag) 
  156                         *ip = cred->cr_prison->pr_ip;
  157                 else
  158                         *ip = htonl(cred->cr_prison->pr_ip);
  159                 return (0);
  160         }
  161         if (tmp == INADDR_LOOPBACK) {
  162                 if (flag)
  163                         *ip = cred->cr_prison->pr_ip;
  164                 else
  165                         *ip = htonl(cred->cr_prison->pr_ip);
  166                 return (0);
  167         }
  168         if (cred->cr_prison->pr_ip != tmp)
  169                 return (1);
  170         return (0);
  171 }
  172 
  173 void
  174 prison_remote_ip(struct ucred *cred, int flag, u_int32_t *ip)
  175 {
  176         u_int32_t tmp;
  177 
  178         if (!jailed(cred))
  179                 return;
  180         if (flag)
  181                 tmp = *ip;
  182         else
  183                 tmp = ntohl(*ip);
  184         if (tmp == INADDR_LOOPBACK) {
  185                 if (flag)
  186                         *ip = cred->cr_prison->pr_ip;
  187                 else
  188                         *ip = htonl(cred->cr_prison->pr_ip);
  189                 return;
  190         }
  191         return;
  192 }
  193 
  194 int
  195 prison_if(struct ucred *cred, struct sockaddr *sa)
  196 {
  197         struct sockaddr_in *sai = (struct sockaddr_in*) sa;
  198         int ok;
  199 
  200         if ((sai->sin_family != AF_INET) && jail_socket_unixiproute_only)
  201                 ok = 1;
  202         else if (sai->sin_family != AF_INET)
  203                 ok = 0;
  204         else if (cred->cr_prison->pr_ip != ntohl(sai->sin_addr.s_addr))
  205                 ok = 1;
  206         else
  207                 ok = 0;
  208         return (ok);
  209 }
  210 
  211 /*
  212  * Return 0 if jails permit p1 to frob p2, otherwise ESRCH.
  213  */
  214 int
  215 prison_check(cred1, cred2)
  216         struct ucred *cred1, *cred2;
  217 {
  218 
  219         if (jailed(cred1)) {
  220                 if (!jailed(cred2))
  221                         return (ESRCH);
  222                 if (cred2->cr_prison != cred1->cr_prison)
  223                         return (ESRCH);
  224         }
  225 
  226         return (0);
  227 }
  228 
  229 /*
  230  * Return 1 if the passed credential is in a jail, otherwise 0.
  231  */
  232 int
  233 jailed(cred)
  234         struct ucred *cred;
  235 {
  236 
  237         return (cred->cr_prison != NULL);
  238 }
  239 
  240 /*
  241  * Return the correct hostname for the passed credential.
  242  */
  243 void
  244 getcredhostname(cred, buf, size)
  245         struct ucred *cred;
  246         char *buf;
  247         size_t size;
  248 {
  249 
  250         if (jailed(cred)) {
  251                 mtx_lock(&cred->cr_prison->pr_mtx);
  252                 strlcpy(buf, cred->cr_prison->pr_host, size);
  253                 mtx_unlock(&cred->cr_prison->pr_mtx);
  254         }
  255         else
  256                 strlcpy(buf, hostname, size);
  257 }

Cache object: 53d56a901a1285e2c19e26c4ac99cbd0


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.