kern_jail.c revision 46155
1 2#include <sys/param.h> 3#include <sys/types.h> 4#include <sys/kernel.h> 5#include <sys/systm.h> 6#include <sys/errno.h> 7#include <sys/sysproto.h> 8#include <sys/malloc.h> 9#include <sys/proc.h> 10#include <sys/jail.h> 11#include <sys/socket.h> 12#include <net/if.h> 13#include <netinet/in.h> 14 15MALLOC_DEFINE(M_PRISON, "prison", "Prison structures"); 16 17int 18jail(p, uap) 19 struct proc *p; 20 struct jail_args /* { 21 syscallarg(struct jail *) jail; 22 } */ *uap; 23{ 24 int error; 25 struct prison *pr; 26 struct jail j; 27 struct chroot_args ca; 28 29 error = suser(p); 30 if (error) 31 return (error); 32 error = copyin(uap->jail, &j, sizeof j); 33 if (error) 34 return (error); 35 MALLOC(pr, struct prison *, sizeof *pr , M_PRISON, M_WAITOK); 36 bzero((caddr_t)pr, sizeof *pr); 37 error = copyinstr(j.hostname, &pr->pr_host, sizeof pr->pr_host, 0); 38 if (error) 39 goto bail; 40 pr->pr_ip = j.ip_number; 41 42 ca.path = j.path; 43 error = chroot(p, &ca); 44 if (error) 45 goto bail; 46 47 pr->pr_ref++; 48 p->p_prison = pr; 49 p->p_flag |= P_JAILED; 50 return (0); 51 52bail: 53 FREE(pr, M_PRISON); 54 return (error); 55} 56 57int 58prison_ip(struct proc *p, int flag, u_int32_t *ip) 59{ 60 u_int32_t tmp; 61 62 if (!p->p_prison) 63 return (0); 64 if (flag) 65 tmp = *ip; 66 else 67 tmp = ntohl(*ip); 68 if (tmp == INADDR_ANY) { 69 if (flag) 70 *ip = p->p_prison->pr_ip; 71 else 72 *ip = htonl(p->p_prison->pr_ip); 73 return (0); 74 } 75 if (p->p_prison->pr_ip != tmp) 76 return (1); 77 return (0); 78} 79 80void 81prison_remote_ip(struct proc *p, int flag, u_int32_t *ip) 82{ 83 u_int32_t tmp; 84 85 if (!p->p_prison) 86 return; 87 if (flag) 88 tmp = *ip; 89 else 90 tmp = ntohl(*ip); 91 if (tmp == 0x7f000001) { 92 if (flag) 93 *ip = p->p_prison->pr_ip; 94 else 95 *ip = htonl(p->p_prison->pr_ip); 96 return; 97 } 98 return; 99} 100 101int 102prison_if(struct proc *p, struct sockaddr *sa) 103{ 104 struct sockaddr_in *sai = (struct sockaddr_in*) sa; 105 int ok; 106 107 if (sai->sin_family != AF_INET) 108 ok = 0; 109 else if (p->p_prison->pr_ip != ntohl(sai->sin_addr.s_addr)) 110 ok = 1; 111 else 112 ok = 0; 113 return (ok); 114} 115