kern_jail.c revision 72786
146197Sphk/* 246197Sphk * ---------------------------------------------------------------------------- 346197Sphk * "THE BEER-WARE LICENSE" (Revision 42): 446197Sphk * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you 546197Sphk * can do whatever you want with this stuff. If we meet some day, and you think 646197Sphk * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 746197Sphk * ---------------------------------------------------------------------------- 846197Sphk * 950477Speter * $FreeBSD: head/sys/kern/kern_jail.c 72786 2001-02-21 06:39:57Z rwatson $ 1046197Sphk * 1146197Sphk */ 1246155Sphk 1346155Sphk#include <sys/param.h> 1446155Sphk#include <sys/types.h> 1546155Sphk#include <sys/kernel.h> 1646155Sphk#include <sys/systm.h> 1746155Sphk#include <sys/errno.h> 1846155Sphk#include <sys/sysproto.h> 1946155Sphk#include <sys/malloc.h> 2046155Sphk#include <sys/proc.h> 2146155Sphk#include <sys/jail.h> 2246155Sphk#include <sys/socket.h> 2357163Srwatson#include <sys/sysctl.h> 2446155Sphk#include <net/if.h> 2546155Sphk#include <netinet/in.h> 2646155Sphk 2746155SphkMALLOC_DEFINE(M_PRISON, "prison", "Prison structures"); 2846155Sphk 2957163SrwatsonSYSCTL_NODE(, OID_AUTO, jail, CTLFLAG_RW, 0, 3057163Srwatson "Jail rules"); 3157163Srwatson 3257163Srwatsonint jail_set_hostname_allowed = 1; 3357163SrwatsonSYSCTL_INT(_jail, OID_AUTO, set_hostname_allowed, CTLFLAG_RW, 3457163Srwatson &jail_set_hostname_allowed, 0, 3557163Srwatson "Processes in jail can set their hostnames"); 3657163Srwatson 3761235Srwatsonint jail_socket_unixiproute_only = 1; 3861235SrwatsonSYSCTL_INT(_jail, OID_AUTO, socket_unixiproute_only, CTLFLAG_RW, 3961235Srwatson &jail_socket_unixiproute_only, 0, 4061235Srwatson "Processes in jail are limited to creating UNIX/IPv4/route sockets only"); 4161235Srwatson 4268024Srwatsonint jail_sysvipc_allowed = 0; 4368024SrwatsonSYSCTL_INT(_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW, 4468024Srwatson &jail_sysvipc_allowed, 0, 4568024Srwatson "Processes in jail can use System V IPC primitives"); 4668024Srwatson 4746155Sphkint 4846155Sphkjail(p, uap) 4972786Srwatson struct proc *p; 5072786Srwatson struct jail_args /* { 5172786Srwatson syscallarg(struct jail *) jail; 5272786Srwatson } */ *uap; 5346155Sphk{ 5446155Sphk int error; 5546155Sphk struct prison *pr; 5646155Sphk struct jail j; 5746155Sphk struct chroot_args ca; 5846155Sphk 5972786Srwatson /* Implicitly fail if already in jail. */ 6046155Sphk error = suser(p); 6146155Sphk if (error) 6246155Sphk return (error); 6346155Sphk error = copyin(uap->jail, &j, sizeof j); 6446155Sphk if (error) 6546155Sphk return (error); 6651398Sphk if (j.version != 0) 6751398Sphk return (EINVAL); 6869781Sdwmalone MALLOC(pr, struct prison *, sizeof *pr , M_PRISON, M_WAITOK | M_ZERO); 6946155Sphk error = copyinstr(j.hostname, &pr->pr_host, sizeof pr->pr_host, 0); 7046155Sphk if (error) 7146155Sphk goto bail; 7246155Sphk pr->pr_ip = j.ip_number; 7346155Sphk 7446155Sphk ca.path = j.path; 7546155Sphk error = chroot(p, &ca); 7646155Sphk if (error) 7746155Sphk goto bail; 7846155Sphk 7972786Srwatson p->p_ucred = crcopy(p->p_ucred); 8072786Srwatson p->p_ucred->cr_prison = pr; 8172786Srwatson pr->pr_ref = 1; 8246155Sphk return (0); 8346155Sphk 8446155Sphkbail: 8546155Sphk FREE(pr, M_PRISON); 8646155Sphk return (error); 8746155Sphk} 8846155Sphk 8972786Srwatsonvoid 9072786Srwatsonprison_free(struct prison *pr) 9172786Srwatson{ 9272786Srwatson 9372786Srwatson pr->pr_ref--; 9472786Srwatson if (pr->pr_ref == 0) { 9572786Srwatson if (pr->pr_linux != NULL) 9672786Srwatson FREE(pr->pr_linux, M_PRISON); 9772786Srwatson FREE(pr, M_PRISON); 9872786Srwatson } 9972786Srwatson} 10072786Srwatson 10172786Srwatsonvoid 10272786Srwatsonprison_hold(struct prison *pr) 10372786Srwatson{ 10472786Srwatson 10572786Srwatson pr->pr_ref++; 10672786Srwatson} 10772786Srwatson 10846155Sphkint 10972786Srwatsonprison_ip(struct ucred *cred, int flag, u_int32_t *ip) 11046155Sphk{ 11146155Sphk u_int32_t tmp; 11246155Sphk 11372786Srwatson if (!jailed(cred)) 11446155Sphk return (0); 11546155Sphk if (flag) 11646155Sphk tmp = *ip; 11746155Sphk else 11846155Sphk tmp = ntohl(*ip); 11946155Sphk if (tmp == INADDR_ANY) { 12046155Sphk if (flag) 12172786Srwatson *ip = cred->cr_prison->pr_ip; 12246155Sphk else 12372786Srwatson *ip = htonl(cred->cr_prison->pr_ip); 12446155Sphk return (0); 12546155Sphk } 12672786Srwatson if (cred->cr_prison->pr_ip != tmp) 12746155Sphk return (1); 12846155Sphk return (0); 12946155Sphk} 13046155Sphk 13146155Sphkvoid 13272786Srwatsonprison_remote_ip(struct ucred *cred, int flag, u_int32_t *ip) 13346155Sphk{ 13446155Sphk u_int32_t tmp; 13546155Sphk 13672786Srwatson if (!jailed(cred)) 13746155Sphk return; 13846155Sphk if (flag) 13946155Sphk tmp = *ip; 14046155Sphk else 14146155Sphk tmp = ntohl(*ip); 14246155Sphk if (tmp == 0x7f000001) { 14346155Sphk if (flag) 14472786Srwatson *ip = cred->cr_prison->pr_ip; 14546155Sphk else 14672786Srwatson *ip = htonl(cred->cr_prison->pr_ip); 14746155Sphk return; 14846155Sphk } 14946155Sphk return; 15046155Sphk} 15146155Sphk 15246155Sphkint 15372786Srwatsonprison_if(struct ucred *cred, struct sockaddr *sa) 15446155Sphk{ 15546155Sphk struct sockaddr_in *sai = (struct sockaddr_in*) sa; 15646155Sphk int ok; 15746155Sphk 15861235Srwatson if ((sai->sin_family != AF_INET) && jail_socket_unixiproute_only) 15961235Srwatson ok = 1; 16061235Srwatson else if (sai->sin_family != AF_INET) 16146155Sphk ok = 0; 16272786Srwatson else if (cred->cr_prison->pr_ip != ntohl(sai->sin_addr.s_addr)) 16346155Sphk ok = 1; 16446155Sphk else 16546155Sphk ok = 0; 16646155Sphk return (ok); 16746155Sphk} 16872786Srwatson 16972786Srwatson/* 17072786Srwatson * Return 0 if jails permit p1 to frob p2, otherwise ESRCH. 17172786Srwatson */ 17272786Srwatsonint 17372786Srwatsonprison_check(cred1, cred2) 17472786Srwatson struct ucred *cred1, *cred2; 17572786Srwatson{ 17672786Srwatson 17772786Srwatson if (jailed(cred1)) { 17872786Srwatson if (!jailed(cred2)) 17972786Srwatson return (ESRCH); 18072786Srwatson if (cred2->cr_prison != cred1->cr_prison) 18172786Srwatson return (ESRCH); 18272786Srwatson } 18372786Srwatson 18472786Srwatson return (0); 18572786Srwatson} 18672786Srwatson 18772786Srwatson/* 18872786Srwatson * Return 1 if the passed credential is in a jail, otherwise 0. 18972786Srwatson */ 19072786Srwatsonint 19172786Srwatsonjailed(cred) 19272786Srwatson struct ucred *cred; 19372786Srwatson{ 19472786Srwatson 19572786Srwatson return (cred->cr_prison != NULL); 19672786Srwatson} 197