diff -ruP /usr/src/sys/kern/kern_exit.c src/sys/kern/kern_exit.c --- /usr/src/sys/kern/kern_exit.c Mon Jan 20 22:26:43 2003 +++ src/sys/kern/kern_exit.c Sun Feb 2 18:06:49 2003 @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_exit.c 8.7 (Berkeley) 2/12/94 - * $FreeBSD: src/sys/kern/kern_exit.c,v 1.92.2.11 2003/01/13 22:51:16 dillon Exp $ + * $FreeBSD$ */ #include "opt_compat.h" @@ -510,6 +510,7 @@ if (p->p_prison && !--p->p_prison->pr_ref) { if (p->p_prison->pr_linux != NULL) FREE(p->p_prison->pr_linux, M_PRISON); + FREE(p->p_prison->pr_ips, M_PRISON); FREE(p->p_prison, M_PRISON); } diff -ruP /usr/src/sys/kern/kern_jail.c src/sys/kern/kern_jail.c --- /usr/src/sys/kern/kern_jail.c Fri Aug 17 03:00:26 2001 +++ src/sys/kern/kern_jail.c Wed Nov 27 00:07:24 2002 @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $FreeBSD: src/sys/kern/kern_jail.c,v 1.6.2.3 2001/08/17 01:00:26 rwatson Exp $ + * $FreeBSD$ * */ @@ -62,14 +62,22 @@ error = copyin(uap->jail, &j, sizeof j); if (error) return (error); - if (j.version != 0) + if (j.version != 1) return (EINVAL); MALLOC(pr, struct prison *, sizeof *pr , M_PRISON, M_WAITOK); bzero((caddr_t)pr, sizeof *pr); error = copyinstr(j.hostname, &pr->pr_host, sizeof pr->pr_host, 0); if (error) goto bail; - pr->pr_ip = j.ip_number; + + MALLOC(pr->pr_ips, u_int32_t *, sizeof(u_int32_t) * j.nips, M_PRISON, + M_WAITOK); + error = copyin(j.ips, pr->pr_ips, sizeof(u_int32_t) * j.nips); + if (error) { + FREE(pr->pr_ips, M_PRISON); + goto bail; + } + pr->pr_nips = j.nips; ca.path = j.path; error = chroot(p, &ca); @@ -99,20 +107,21 @@ tmp = ntohl(*ip); if (tmp == INADDR_ANY) { if (flag) - *ip = p->p_prison->pr_ip; + *ip = p->p_prison->pr_ips[0]; else - *ip = htonl(p->p_prison->pr_ip); + *ip = htonl(p->p_prison->pr_ips[0]); return (0); } if (tmp == INADDR_LOOPBACK) { if (flag) - *ip = p->p_prison->pr_ip; + *ip = p->p_prison->pr_ips[0]; else - *ip = htonl(p->p_prison->pr_ip); + *ip = htonl(p->p_prison->pr_ips[0]); return (0); } - if (p->p_prison->pr_ip != tmp) + if (!prison_check_ip(p->p_prison, tmp)) return (1); + return (0); } @@ -129,9 +138,9 @@ tmp = ntohl(*ip); if (tmp == INADDR_LOOPBACK) { if (flag) - *ip = p->p_prison->pr_ip; + *ip = p->p_prison->pr_ips[0]; else - *ip = htonl(p->p_prison->pr_ip); + *ip = htonl(p->p_prison->pr_ips[0]); return; } return; @@ -147,9 +156,22 @@ ok = 1; else if (sai->sin_family != AF_INET) ok = 0; - else if (p->p_prison->pr_ip != ntohl(sai->sin_addr.s_addr)) + else if (!prison_check_ip(p->p_prison, ntohl(sai->sin_addr.s_addr))) ok = 1; else ok = 0; return (ok); +} + +int +prison_check_ip(struct prison *pr, u_int32_t ip) +{ + register u_int i; + + for (i = 0; i < pr->pr_nips; ++i) { + if (pr->pr_ips[i] == ip) + return (1); + } + + return (0); } diff -ruP /usr/src/sys/netinet/in.h src/sys/netinet/in.h --- /usr/src/sys/netinet/in.h Sun Dec 1 15:03:10 2002 +++ src/sys/netinet/in.h Sun Feb 2 18:00:00 2003 @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)in.h 8.3 (Berkeley) 1/3/94 - * $FreeBSD: src/sys/netinet/in.h,v 1.48.2.9 2002/12/01 14:03:10 sobomax Exp $ + * $FreeBSD$ */ #ifndef _NETINET_IN_H_ @@ -462,6 +462,7 @@ #ifdef _KERNEL struct ifnet; struct mbuf; /* forward declarations for Standard C */ +struct prison; #endif /* INET6 stuff */ @@ -479,6 +480,7 @@ int prison_ip __P((struct proc *p, int flag, u_int32_t *ip)); void prison_remote_ip __P((struct proc *p, int flag, u_int32_t *ip)); +int prison_check_ip __P((struct prison *pr, u_int32_t ip)); #define in_hosteq(s, t) ((s).s_addr == (t).s_addr) #define in_nullhost(x) ((x).s_addr == INADDR_ANY) diff -ruP /usr/src/sys/netinet/in_pcb.c src/sys/netinet/in_pcb.c --- /usr/src/sys/netinet/in_pcb.c Sun Feb 2 17:34:01 2003 +++ src/sys/netinet/in_pcb.c Sun Feb 2 18:02:43 2003 @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)in_pcb.c 8.4 (Berkeley) 5/24/95 - * $FreeBSD: src/sys/netinet/in_pcb.c,v 1.59.2.26 2003/01/24 05:11:33 sam Exp $ + * $FreeBSD$ */ #include "opt_ipsec.h" @@ -513,7 +513,7 @@ if (inp->inp_laddr.s_addr == INADDR_ANY && p->p_prison != NULL) { bzero(&sa, sizeof (sa)); - sa.sin_addr.s_addr = htonl(p->p_prison->pr_ip); + sa.sin_addr.s_addr = htonl(p->p_prison->pr_ips[0]); sa.sin_len=sizeof (sa); sa.sin_family = AF_INET; error = in_pcbbind(inp, (struct sockaddr *)&sa, p); @@ -1039,7 +1039,7 @@ { if (!p->p_prison) return (0); - if (ntohl(inp->inp_laddr.s_addr) == p->p_prison->pr_ip) + if (prison_check_ip(p->p_prison, ntohl(inp->inp_laddr.s_addr))) return (0); return (1); } diff -ruP /usr/src/sys/sys/jail.h src/sys/sys/jail.h --- /usr/src/sys/sys/jail.h Wed Nov 1 18:58:06 2000 +++ src/sys/sys/jail.h Sun Feb 2 18:04:33 2003 @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $FreeBSD: src/sys/sys/jail.h,v 1.8.2.2 2000/11/01 17:58:06 rwatson Exp $ + * $FreeBSD$ * */ @@ -17,7 +17,8 @@ u_int32_t version; char *path; char *hostname; - u_int32_t ip_number; + u_int32_t *ips; + u_int nips; }; #ifndef _KERNEL @@ -39,7 +40,8 @@ struct prison { int pr_ref; char pr_host[MAXHOSTNAMELEN]; - u_int32_t pr_ip; + u_int32_t *pr_ips; + u_int pr_nips; void *pr_linux; }; diff -ruP /usr/src/usr.sbin/jail/jail.c src/usr.sbin/jail/jail.c --- /usr/src/usr.sbin/jail/jail.c Mon Jul 30 12:19:54 2001 +++ src/usr.sbin/jail/jail.c Wed Nov 27 00:07:24 2002 @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $FreeBSD: src/usr.sbin/jail/jail.c,v 1.5.2.1 2001/07/30 10:19:54 dd Exp $ + * $FreeBSD$ * */ @@ -22,23 +22,39 @@ main(int argc, char **argv) { struct jail j; - int i; + int i, c; + char *ip; struct in_addr in; - if (argc < 5) - errx(1, "Usage: %s path hostname ip-number command ...\n", + if (argc < 5) { + errx(1, "Usage: %s path hostname ip1[,ip2[...]] command ...\n", argv[0]); + } i = chdir(argv[1]); if (i) err(1, "chdir %s", argv[1]); memset(&j, 0, sizeof(j)); - j.version = 0; + j.version = 1; j.path = argv[1]; j.hostname = argv[2]; - i = inet_aton(argv[3], &in); - if (!i) - errx(1, "Couldn't make sense of ip-number\n"); - j.ip_number = ntohl(in.s_addr); + for (c = 1, ip = argv[3]; *ip; ++ip) { + if (*ip == ',') + ++c; + } + if ((j.ips = (u_int32_t *)malloc(sizeof(u_int32_t) * c)) == NULL) + errx(1, "malloc()"); + + for (c = 0, ip = strtok(argv[3], ","); ip; + ++c, ip = strtok(NULL, ",")) { + i = inet_aton(ip, &in); + if (!i) { + free(j.ips); + errx(1, "Couldn't make sense of ip-number\n"); + } + j.ips[c] = ntohl(in.s_addr); + } + j.nips = c; + i = jail(&j); if (i) err(1, "Imprisonment failed");