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: src/sys/kern/kern_jail.c,v 1.6.2.3 2001/08/17 01:00:26 rwatson Exp $ 10 * $DragonFly: src/sys/kern/kern_jail.c,v 1.2 2003/06/17 04:28:41 dillon Exp $ 11 * 12 */ 13 14 #include <sys/param.h> 15 #include <sys/types.h> 16 #include <sys/kernel.h> 17 #include <sys/systm.h> 18 #include <sys/errno.h> 19 #include <sys/sysproto.h> 20 #include <sys/malloc.h> 21 #include <sys/proc.h> 22 #include <sys/jail.h> 23 #include <sys/socket.h> 24 #include <sys/sysctl.h> 25 #include <net/if.h> 26 #include <netinet/in.h> 27 28 MALLOC_DEFINE(M_PRISON, "prison", "Prison structures"); 29 30 SYSCTL_NODE(, OID_AUTO, jail, CTLFLAG_RW, 0, 31 "Jail rules"); 32 33 int jail_set_hostname_allowed = 1; 34 SYSCTL_INT(_jail, OID_AUTO, set_hostname_allowed, CTLFLAG_RW, 35 &jail_set_hostname_allowed, 0, 36 "Processes in jail can set their hostnames"); 37 38 int jail_socket_unixiproute_only = 1; 39 SYSCTL_INT(_jail, OID_AUTO, socket_unixiproute_only, CTLFLAG_RW, 40 &jail_socket_unixiproute_only, 0, 41 "Processes in jail are limited to creating UNIX/IPv4/route sockets only"); 42 43 int jail_sysvipc_allowed = 0; 44 SYSCTL_INT(_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW, 45 &jail_sysvipc_allowed, 0, 46 "Processes in jail can use System V IPC primitives"); 47 48 int 49 jail(p, uap) 50 struct proc *p; 51 struct jail_args /* { 52 syscallarg(struct jail *) jail; 53 } */ *uap; 54 { 55 int error; 56 struct prison *pr; 57 struct jail j; 58 struct chroot_args ca; 59 60 error = suser(p); 61 if (error) 62 return (error); 63 error = copyin(uap->jail, &j, sizeof j); 64 if (error) 65 return (error); 66 if (j.version != 0) 67 return (EINVAL); 68 MALLOC(pr, struct prison *, sizeof *pr , M_PRISON, M_WAITOK); 69 bzero((caddr_t)pr, sizeof *pr); 70 error = copyinstr(j.hostname, &pr->pr_host, sizeof pr->pr_host, 0); 71 if (error) 72 goto bail; 73 pr->pr_ip = j.ip_number; 74 75 ca.path = j.path; 76 error = chroot(p, &ca); 77 if (error) 78 goto bail; 79 80 pr->pr_ref++; 81 p->p_prison = pr; 82 p->p_flag |= P_JAILED; 83 return (0); 84 85 bail: 86 FREE(pr, M_PRISON); 87 return (error); 88 } 89 90 int 91 prison_ip(struct proc *p, int flag, u_int32_t *ip) 92 { 93 u_int32_t tmp; 94 95 if (!p->p_prison) 96 return (0); 97 if (flag) 98 tmp = *ip; 99 else 100 tmp = ntohl(*ip); 101 if (tmp == INADDR_ANY) { 102 if (flag) 103 *ip = p->p_prison->pr_ip; 104 else 105 *ip = htonl(p->p_prison->pr_ip); 106 return (0); 107 } 108 if (tmp == INADDR_LOOPBACK) { 109 if (flag) 110 *ip = p->p_prison->pr_ip; 111 else 112 *ip = htonl(p->p_prison->pr_ip); 113 return (0); 114 } 115 if (p->p_prison->pr_ip != tmp) 116 return (1); 117 return (0); 118 } 119 120 void 121 prison_remote_ip(struct proc *p, int flag, u_int32_t *ip) 122 { 123 u_int32_t tmp; 124 125 if (!p || !p->p_prison) 126 return; 127 if (flag) 128 tmp = *ip; 129 else 130 tmp = ntohl(*ip); 131 if (tmp == INADDR_LOOPBACK) { 132 if (flag) 133 *ip = p->p_prison->pr_ip; 134 else 135 *ip = htonl(p->p_prison->pr_ip); 136 return; 137 } 138 return; 139 } 140 141 int 142 prison_if(struct proc *p, struct sockaddr *sa) 143 { 144 struct sockaddr_in *sai = (struct sockaddr_in*) sa; 145 int ok; 146 147 if ((sai->sin_family != AF_INET) && jail_socket_unixiproute_only) 148 ok = 1; 149 else if (sai->sin_family != AF_INET) 150 ok = 0; 151 else if (p->p_prison->pr_ip != ntohl(sai->sin_addr.s_addr)) 152 ok = 1; 153 else 154 ok = 0; 155 return (ok); 156 } 157