kern/69064: [patch] No multiple ip4/6's could assigned to a
jail.
Meno Abels
meno.abels at adviser.com
Thu Dec 2 14:20:28 PST 2004
The following reply was made to PR kern/69064; it has been noted by GNATS.
From: "Meno Abels" <meno.abels at adviser.com>
To: <freebsd-gnats-submit at FreeBSD.org>, <abels at adviser.com>
Cc:
Subject: Re: kern/69064: [patch] No multiple ip4/6's could assigned to a jail.
Date: Thu, 2 Dec 2004 23:16:04 +0100
Now the patch works agains RELEASE_5_3 and i fixed some usage problems =
and a
stall in the kernel which was cause by illegal parameters in the jail =
system
call.
The jail tool now can handle this:
jail path hostname ip,ip,ip /bin/sh /etc/rc
This allows to use it without change from /etc/rc.d/jail
Here is the complete patch against RELEASE_5_3:
# This is a shell archive. Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file". Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
# ipv6.jail.patch
#
echo x - ipv6.jail.patch
sed 's/^X//' >ipv6.jail.patch << 'END-of-ipv6.jail.patch'
XIndex: usr.sbin/jail/jail.8
X=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
XRCS file: /usr/freebsd.cvs/src/usr.sbin/jail/jail.8,v
Xretrieving revision 1.58
Xdiff -c -r1.58 jail.8
X*** usr.sbin/jail/jail.8 15 Aug 2004 08:21:50 -0000 1.58
X--- usr.sbin/jail/jail.8 2 Dec 2004 21:17:28 -0000
X***************
X*** 43,49 ****
X .Nm
X .Op Fl i
X .Op Fl l Fl u Ar username | Fl U Ar username
X! .Ar path hostname ip-number command ...
X .Sh DESCRIPTION
X The
X .Nm
X--- 43,52 ----
X .Nm
X .Op Fl i
X .Op Fl l Fl u Ar username | Fl U Ar username
X! .Op Fl j Ar jail identifier
X! .Op Fl a Ar ip4 or ip6 address
X! .Op Fl d Ar ip4 or ip6 address
X! .Ar path hostname [ip4|ip6] command ...
X .Sh DESCRIPTION
X The
X .Nm
X***************
X*** 52,58 ****
X The options are as follows:
X .Bl -tag -width ".Fl u Ar username"
X .It Fl i
X! Output the jail identifier of the newly created jail.
X .It Fl l
X Run program in the clean environment.
X The environment is discarded except for
X--- 55,61 ----
X The options are as follows:
X .Bl -tag -width ".Fl u Ar username"
X .It Fl i
X! Output the jail identifier of the newly created jail. Only valid =
without
-j.
X .It Fl l
X Run program in the clean environment.
X The environment is discarded except for
X***************
X*** 76,82 ****
X .Ar command
X should run.
X .It Fl U Ar username
X! The user name from jailed environment as whom the
X .Ar command
X should run.
X .It Ar path
X--- 79,95 ----
X .Ar command
X should run.
X .It Fl U Ar username
X!=20
X! The user name from jailed environment as whom the. Only valid without =
-j.
X! .It Fl j Ar jail identifier
X! This options set the jail identifier which is modified with -a oder =
-d.
X! The jail identifier could be retrieved with jls.
X! .It Fl a Ar ip4 or ip6
X! This options add the specified ip number to the jail that is give =
with
-j. You
X! can only have one -a per call.=20
X! .It Fl d Ar ip4 or ip6
X! This options deletes the specified ip number from the jail that is =
give
with -j.
X! You can only have one -d per call.
X .Ar command
X should run.
X .It Ar path
X***************
X*** 84,90 ****
X .It Ar hostname
X Hostname of the prison.
X .It Ar ip-number
X! IP number assigned to the prison.
X .It Ar command
X Pathname of the program which is to be executed.
X .El
X--- 97,103 ----
X .It Ar hostname
X Hostname of the prison.
X .It Ar ip-number
X! IP4 or IP6 number assigned to the prison.
X .It Ar command
X Pathname of the program which is to be executed.
X .El
XIndex: usr.sbin/jail/jail.c
X=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
XRCS file: /usr/freebsd.cvs/src/usr.sbin/jail/jail.c,v
Xretrieving revision 1.17
Xdiff -c -r1.17 jail.c
X*** usr.sbin/jail/jail.c 15 Aug 2004 08:21:50 -0000 1.17
X--- usr.sbin/jail/jail.c 2 Dec 2004 21:31:38 -0000
X***************
X*** 13,21 ****
X--- 13,24 ----
X #include <sys/param.h>
X #include <sys/jail.h>
X =20
X+ #include <sys/types.h>
X+ #include <sys/socket.h>
X #include <netinet/in.h>
X #include <arpa/inet.h>
X =20
X+=20
X #include <err.h>
X #include <errno.h>
X #include <grp.h>
X***************
X*** 52,67 ****
X login_cap_t *lcap;
X struct jail j;
X struct passwd *pwd;
X! struct in_addr in;
X int ch, groups[NGROUPS], i, iflag, lflag, ngroups, uflag, Uflag;
X char path[PATH_MAX], *username;
X static char *cleanenv;
X const char *shell, *p;
X =20
X iflag =3D lflag =3D uflag =3D Uflag =3D 0;
X username =3D cleanenv =3D NULL;
X =20
X! while ((ch =3D getopt(argc, argv, "ilu:U:")) !=3D -1) {
X switch (ch) {
X case 'i':
X iflag =3D 1;
X--- 55,73 ----
X login_cap_t *lcap;
X struct jail j;
X struct passwd *pwd;
X! int jid =3D 0;
X int ch, groups[NGROUPS], i, iflag, lflag, ngroups, uflag, Uflag;
X char path[PATH_MAX], *username;
X static char *cleanenv;
X const char *shell, *p;
X+ const char *address =3D 0;
X+ int add =3D 0;
X+ int del =3D 0;
X =20
X iflag =3D lflag =3D uflag =3D Uflag =3D 0;
X username =3D cleanenv =3D NULL;
X =20
X! while ((ch =3D getopt(argc, argv, "iu:U:j:a:d:")) !=3D -1) {
X switch (ch) {
X case 'i':
X iflag =3D 1;
X***************
X*** 77,90 ****
X case 'l':
X lflag =3D 1;
X break;
X default:
X usage();
X }
X }
X argc -=3D optind;
X argv +=3D optind;
X! if (argc < 4)
X usage();
X if (uflag && Uflag)
X usage();
X if (lflag && username =3D=3D NULL)
X--- 83,135 ----
X case 'l':
X lflag =3D 1;
X break;
X+ case 'j':
X+ jid =3D atol(optarg);
X+ break;
X+ case 'a':
X+ add =3D 1;
X+ address =3D optarg;
X+ break;
X+ case 'd':
X+ del =3D 1;
X+ address =3D optarg;
X+ break;
X+=20
X default:
X usage();
X }
X }
X argc -=3D optind;
X argv +=3D optind;
X! if ((jid =3D=3D 0 && argc < 4) ||
X! (jid < 1 && (add || del)) ||
X! (add && del) ||
X! (jid > 0 && !(add || del)))
X usage();
X+ if (jid > 0) {
X+ if (!address)
X+ {
X+ err(1, "jail: address has to be specified");
X+ }
X+ int function;
X+ if (inet_pton(AF_INET, address,
&j.u.v2.u.add_del.v4_6.ip4_num) > 0) {
X+ function =3D add ? ADDIP4 : DELIP4;
X+ }
X+ else if (inet_pton(AF_INET6, address,
&j.u.v2.u.add_del.v4_6.ip6_num) > 0) {
X+ function =3D add ? ADDIP6 : DELIP6;
X+ }
X+ else {
X+ err(1, "inet_pton: %s", address);
X+ }
X+ j.version =3D XPRISON_VERSION;
X+ j.u.v2.function =3D function;
X+ j.u.v2.u.add_del.id =3D jid;
X+ i =3D jail(&j);
X+ if (i =3D=3D -1)
X+ err(1, "jail(%d)", function);
X+ exit (0);
X+ }
X+=20
X if (uflag && Uflag)
X usage();
X if (lflag && username =3D=3D NULL)
X***************
X*** 96,114 ****
X if (chdir(path) !=3D 0)
X err(1, "chdir: %s", path);
X memset(&j, 0, sizeof(j));
X! j.version =3D 0;
X! j.path =3D path;
X! j.hostname =3D argv[1];
X! if (inet_aton(argv[2], &in) =3D=3D 0)
X! errx(1, "Could not make sense of ip-number: %s", argv[2]);
X! j.ip_number =3D ntohl(in.s_addr);
X! i =3D jail(&j);
X if (i =3D=3D -1)
X! err(1, "jail");
X if (iflag) {
X! printf("%d\n", i);
X fflush(stdout);
X }
X if (username !=3D NULL) {
X if (Uflag)
X GET_USER_INFO;
X--- 141,177 ----
X if (chdir(path) !=3D 0)
X err(1, "chdir: %s", path);
X memset(&j, 0, sizeof(j));
X! j.version =3D XPRISON_VERSION;
X! j.u.v2.function =3D CREATEJAIL;
X! j.u.v2.u.createjail.path =3D path;
X! j.u.v2.u.createjail.hostname =3D argv[1];
X! jid =3D i =3D jail(&j);
X if (i =3D=3D -1)
X! err(1, "jail(CREATEJAIL)");
X!=20
X if (iflag) {
X! printf("%d\n", jid);
X fflush(stdout);
X }
X+=20
X+ const char *tok;
X+ for (tok =3D strtok(argv[2], ","); tok; tok =3D strtok(0, ","))
X+ {
X+ j.version =3D XPRISON_VERSION;
X+ j.u.v2.u.add_del.id =3Djid;
X+ j.u.v2.function =3D ADDIP4;
X+ address =3D tok;
X+ if (inet_pton(AF_INET, address,
&j.u.v2.u.add_del.v4_6.ip4_num) <=3D 0) {
X+ j.u.v2.function =3D ADDIP6;
X+ if (inet_pton(AF_INET6, address,
&j.u.v2.u.add_del.v4_6.ip6_num) <=3D 0) {
X+ errx(1, "Could not make sense of ip-number:
%s", argv[2]);
X+ }
X+ }
X+ i =3D jail(&j);
X+ if (i =3D=3D -1)
X+ err(1, "jail(%d)", j.u.v2.function);
X+=20
X+ }
X if (username !=3D NULL) {
X if (Uflag)
X GET_USER_INFO;
X***************
X*** 147,154 ****
X usage(void)
X {
X =20
X! (void)fprintf(stderr, "%s%s\n",
X! "usage: jail [-i] [-l -u username | -U username]",
X! " path hostname ip-number command ...");
X! exit(1);
X }
X--- 210,216 ----
X usage(void)
X {
X =20
X! (void)fprintf(stderr,
X! "usage: jail [-i] [-u username] [-j id] [[-a [ip4|ip6]|[-d
[ip4|ip6]] [path hostname {[ip4|ip6],} command ...]\n");
X! exit(1);
X }
XIndex: usr.sbin/jls/jls.8
X=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
XRCS file: /usr/freebsd.cvs/src/usr.sbin/jls/jls.8,v
Xretrieving revision 1.1
Xdiff -c -r1.1 jls.8
X*** usr.sbin/jls/jls.8 9 Apr 2003 03:04:12 -0000 1.1
X--- usr.sbin/jls/jls.8 24 Nov 2004 23:41:10 -0000
X***************
X*** 33,42 ****
X--- 33,55 ----
X .Nd "list active jails"
X .Sh SYNOPSIS
X .Nm
X+ .Op Fl a
X+ .Op Fl 6
X .Sh DESCRIPTION
X The
X .Nm
X utility lists all active jails.
X+ .Pp
X+ The options are as follows:
X+ .Bl -tag -width ".Fl a "
X+ .It Fl a=20
X+ output all ip4 assigments to the jail identifier(JID). Each ip4 gets
X+ one line in output. If no ip4 address is assigned 0.0.0.0 is the =
output.
X+ .It Fl 6=20
X+ output ip6 address also a new column is generated between IP Address=20
X+ and Hostname. If no ip6 address is assigned :: is the output.
X+ .El
X+ .Pp
X Each jail is represented by one row which contains the following =
columns:
X jail identifier (JID), IP address, hostname, and path.
X .Sh SEE ALSO
XIndex: usr.sbin/jls/jls.c
X=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
XRCS file: /usr/freebsd.cvs/src/usr.sbin/jls/jls.c,v
Xretrieving revision 1.3
Xdiff -c -r1.3 jls.c
X*** usr.sbin/jls/jls.c 22 Apr 2003 13:24:56 -0000 1.3
X--- usr.sbin/jls/jls.c 24 Nov 2004 23:41:10 -0000
X***************
X*** 30,49 ****
X #include <sys/jail.h>
X #include <sys/sysctl.h>
X =20
X #include <arpa/inet.h>
X #include <err.h>
X #include <errno.h>
X #include <limits.h>
X #include <stdio.h>
X #include <stdlib.h>
X =20
X =20
X int
X! main(void)
X {=20
X struct xprison *sxp, *xp;
X- struct in_addr in;
X size_t i, len;
X =20
X if (sysctlbyname("security.jail.list", NULL, &len, NULL, 0) =3D=3D =
-1)
X err(1, "sysctlbyname(): security.jail.list");
X--- 30,81 ----
X #include <sys/jail.h>
X #include <sys/sysctl.h>
X =20
X+ #include <sys/types.h>
X+ #include <sys/socket.h>
X+ #include <netinet/in.h>
X #include <arpa/inet.h>
X+=20
X #include <err.h>
X #include <errno.h>
X #include <limits.h>
X #include <stdio.h>
X #include <stdlib.h>
X+ #include <unistd.h>
X+=20
X+ static int
X+ usage(void)
X+ {
X+ fprintf(stderr, "%s\n%s\n%s\n",
X+ "usage: jls [-a] [-6]",
X+ " -a output all jail assigned ip addresses",
X+ " -6 output includes ipv6 addresses");
X+ exit(1);
X+ }
X =20
X =20
X int
X! main(int argc, char **argv)
X {=20
X struct xprison *sxp, *xp;
X size_t i, len;
X+ int allflag =3D 0;
X+ int ip6flag =3D 0;
X+ int ch;
X+=20
X+ while ((ch =3D getopt(argc, argv, "a6")) !=3D -1) {
X+ switch (ch) {
X+ case 'a':
X+ allflag =3D 1;
X+ break;
X+ case '6':
X+ ip6flag =3D 1;
X+ break;
X+ default:
X+ usage();
X+ }
X+ }
X+ argc -=3D optind;
X+ argv +=3D optind;
X =20
X if (sysctlbyname("security.jail.list", NULL, &len, NULL, 0) =3D=3D =
-1)
X err(1, "sysctlbyname(): security.jail.list");
X***************
X*** 65,75 ****
X xp->pr_version !=3D XPRISON_VERSION)
X errx(1, "Kernel and userland out of sync");
X =20
X! printf(" JID IP Address Hostname
Path\n");
X for (i =3D 0; i < len / sizeof(*xp); i++) {
X! in.s_addr =3D ntohl(xp->pr_ip);
X! printf("%6d %-15.15s %-29.29s %.74s\n",
X! xp->pr_id, inet_ntoa(in), xp->pr_host, xp->pr_path);
X xp++;
X }
X free(sxp);
X--- 97,122 ----
X xp->pr_version !=3D XPRISON_VERSION)
X errx(1, "Kernel and userland out of sync");
X =20
X! if (ip6flag)
X! printf(" JID IP4 Address IP6 Address
Hostname Path\n");
X! else
X! printf(" JID IP Address Hostname
Path\n");
X for (i =3D 0; i < len / sizeof(*xp); i++) {
X! if (allflag || xp->pr4_id =3D=3D 0) {
X! if (ip6flag) {
X! char buffer[128];
X! printf("%6d %-15.15s %-22.22s %-29.29s
%.74s\n",
X! xp->pr_id,=20
X! inet_ntoa(xp->pr4_num),
X! inet_ntop(AF_INET6, xp->pr6_num.s6_addr,
buffer, sizeof(buffer)),
X! xp->pr_host,=20
X! xp->pr_path);
X! }
X! else {
X! printf("%6d %-15.15s %-29.29s %.74s\n",
X! xp->pr_id, inet_ntoa(xp->pr4_num),
xp->pr_host, xp->pr_path);
X! }
X! }
X xp++;
X }
X free(sxp);
XIndex: sys/kern/kern_jail.c
X=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
XRCS file: /usr/freebsd.cvs/src/sys/kern/kern_jail.c,v
Xretrieving revision 1.44
Xdiff -c -r1.44 kern_jail.c
X*** sys/kern/kern_jail.c 27 Jun 2004 09:03:21 -0000 1.44
X--- sys/kern/kern_jail.c 2 Dec 2004 21:35:54 -0000
X***************
X*** 33,40 ****
X--- 33,43 ----
X #include <sys/vnode.h>
X #include <net/if.h>
X #include <netinet/in.h>
X+ #include <netinet6/in6_var.h>
X =20
X MALLOC_DEFINE(M_PRISON, "prison", "Prison structures");
X+ MALLOC_DEFINE(M_PRISON_IP4, "prison", "Prison ipv4 addresses");
X+ MALLOC_DEFINE(M_PRISON_IP6, "prison", "Prison ipv6 addresses");
X =20
X SYSCTL_DECL(_security);
X SYSCTL_NODE(_security, OID_AUTO, jail, CTLFLAG_RW, 0,
X***************
X*** 75,80 ****
X--- 78,88 ----
X =20
X static void init_prison(void *);
X static void prison_complete(void *context, int pending);
X+ static int prison_add_ip4(struct in_addr *tmpv4, struct prison
*pr, void *pr_new, void **pr_old);
X+ static int prison_add_ip6(struct in6_addr *tmpv4, struct
prison *pr, void *pr_new, void **pr_old);
X+ static int prison_del_ip4(struct in_addr *tmpv4, struct prison
*pr, void *pr_new, void **pr_old);
X+ static int prison_del_ip6(struct in6_addr *tmpv4, struct
prison *pr, void *pr_new, void **pr_old);
X+ static int prison_check_duplicate(char *hostname, char
*path);
X static struct prison *prison_find(int);
X static int sysctl_jail_list(SYSCTL_HANDLER_ARGS);
X =20
X***************
X*** 95,139 ****
X * struct jail *jail;
X * };
X */
X! int
X! jail(struct thread *td, struct jail_args *uap)
X {
X struct nameidata nd;
X- struct prison *pr, *tpr;
X- struct jail j;
X- struct jail_attach_args jaa;
X- int error, tryprid;
X =20
X! error =3D copyin(uap->jail, &j, sizeof(j));
X if (error)
X! return (error);
X! if (j.version !=3D 0)
X! return (EINVAL);
X!=20
X! MALLOC(pr, struct prison *, sizeof(*pr), M_PRISON, M_WAITOK |
M_ZERO);
X! mtx_init(&pr->pr_mtx, "jail mutex", NULL, MTX_DEF);
X! pr->pr_ref =3D 1;
X! error =3D copyinstr(j.path, &pr->pr_path, sizeof(pr->pr_path), 0);
X if (error)
X goto e_killmtx;
X mtx_lock(&Giant);
X! NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, pr->pr_path,
td);
X error =3D namei(&nd);
X if (error) {
X mtx_unlock(&Giant);
X goto e_killmtx;
X }
X! pr->pr_root =3D nd.ni_vp;
X VOP_UNLOCK(nd.ni_vp, 0, td);
X NDFREE(&nd, NDF_ONLY_PNBUF);
X mtx_unlock(&Giant);
X- error =3D copyinstr(j.hostname, &pr->pr_host, sizeof(pr->pr_host), =
0);
X- if (error)
X- goto e_dropvnref;
X- pr->pr_ip =3D j.ip_number;
X- pr->pr_linux =3D NULL;
X- pr->pr_securelevel =3D securelevel;
X =20
X /* Determine next pr_id and add prison to allprison list. */
X mtx_lock(&allprison_mtx);
X tryprid =3D lastprid + 1;
X--- 103,281 ----
X * struct jail *jail;
X * };
X */
X! static int=20
X! jail_createjail(struct thread *td, char *user_hostname, char =
*user_path,
struct prison **pr)
X {
X+ int error;
X struct nameidata nd;
X =20
X! MALLOC(*pr, struct prison *, sizeof(**pr), M_PRISON, M_WAITOK |
M_ZERO);
X! mtx_init(&(*pr)->pr_mtx, "jail mutex", NULL, MTX_DEF);
X! (*pr)->pr_ref =3D 1;
X! error =3D copyinstr(user_path, &(*pr)->pr_path,
sizeof((*pr)->pr_path), 0);
X if (error)
X! goto e_killmtx;
X! error =3D copyinstr(user_hostname, &(*pr)->pr_host,
sizeof((*pr)->pr_host), 0);
X if (error)
X goto e_killmtx;
X+ if (prison_check_duplicate((*pr)->pr_host, (*pr)->pr_path)) {
X+ error =3D EAGAIN;
X+ goto e_killmtx;
X+ }
X+=20
X mtx_lock(&Giant);
X! NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, (*pr)->pr_path,
td);
X error =3D namei(&nd);
X if (error) {
X mtx_unlock(&Giant);
X goto e_killmtx;
X }
X! (*pr)->pr_root =3D nd.ni_vp;
X VOP_UNLOCK(nd.ni_vp, 0, td);
X NDFREE(&nd, NDF_ONLY_PNBUF);
X mtx_unlock(&Giant);
X =20
X+ (*pr)->pr_linux =3D NULL;
X+ (*pr)->pr_securelevel =3D securelevel;
X+ return (0);
X+=20
X+ e_killmtx:
X+ mtx_destroy(&(*pr)->pr_mtx);
X+ FREE(*pr, M_PRISON);
X+ return (error);
X+=20
X+ }
X+=20
X+=20
X+ static void=20
X+ jail_dropvnref(struct prison *pr)
X+ {
X+ mtx_lock(&Giant);
X+ vrele(pr->pr_root);
X+ mtx_unlock(&Giant);
X+ }
X+=20
X+ int
X+ jail(struct thread *td, struct jail_args *uap)
X+ {
X+ struct prison *pr, *tpr;
X+ struct jail j;
X+ struct jail_attach_args jaa;
X+ int error, tryprid;
X+ void *pr_new =3D 0;
X+ void *pr_old =3D 0;
X+=20
X+ error =3D copyin(uap->jail, &j, sizeof(j));
X+ if (error)
X+ return (error);
X+ if (j.version < XPRISON_VERSION)
X+ {
X+ struct in_addr tmpv4;
X+=20
X+ error =3D jail_createjail(td, j.u.v1.hostname, j.u.v1.path,
&pr);
X+ if (error) {
X+ return error;
X+ }
X+ MALLOC(pr_new, void *, sizeof(struct in_addr)*1,
M_PRISON_IP4, M_WAITOK | M_ZERO);
X+ tmpv4.s_addr =3D htonl(j.u.v1.ip_number); =09
X+ mtx_lock(&pr->pr_mtx);
X+ error =3D prison_add_ip4(&tmpv4, pr, pr_new, &pr_old);
X+ mtx_unlock(&pr->pr_mtx);
X+ if (error) {
X+ jail_dropvnref(pr);
X+ }
X+ }
X+ else
X+ {
X+ if (j.u.v2.function =3D=3D CREATEJAIL) {
X+ error =3D jail_createjail(td,
j.u.v2.u.createjail.hostname, j.u.v2.u.createjail.path, &pr);
X+ if (error) {
X+ return error;
X+ }
X+ }
X+ else {
X+ int cnt =3D 0;
X+ struct malloc_type *alloc_type;
X+ retry_alloc:
X+ mtx_lock(&allprison_mtx);
X+ pr =3D prison_find(j.u.v2.u.add_del.id);
X+ if (pr) {
X+ cnt =3D (j.u.v2.function =3D=3D ADDIP4 ||
j.u.v2.function =3D=3D DELIP4) ?=20
X+ pr->pr_ip4s : pr->pr_ip6s;=09
X+ mtx_unlock(&pr->pr_mtx);
X+ }
X+ mtx_unlock(&allprison_mtx);
X+ if (pr =3D=3D NULL) {
X+ return (EINVAL);
X+ }
X+ if (j.u.v2.function =3D=3D ADDIP4 || j.u.v2.function =3D=3D
DELIP4) {
X+ alloc_type=3DM_PRISON_IP4;
X+ if (pr->pr_ip4s >=3D (j.u.v2.function =3D=3D
DELIP4 ? 2 : 0)) {
X+ MALLOC(pr_new, void *,=20
X+ sizeof(struct
in_addr)*(pr->pr_ip4s+
X+ (j.u.v2.function =3D=3D DELIP4 ?
-1 : +1)),
X+ alloc_type, M_WAITOK |
M_ZERO);
X+ /*printf("pr_ip4s:%d\n",
pr->pr_ip4s);*/
X+ }
X+ }
X+ else {
X+ alloc_type=3DM_PRISON_IP6;
X+ if (pr->pr_ip6s >=3D (j.u.v2.function =3D=3D
DELIP6 ? 2 : 0)) {
X+ MALLOC(pr_new, void *,=20
X+ sizeof(struct
in6_addr)*(pr->pr_ip6s+
X+ (j.u.v2.function =3D=3D DELIP6 ?
-1 : +1)),
X+ alloc_type, M_WAITOK |
M_ZERO);
X+ /*printf("pr_ip4s:%d\n",
pr->pr_ip6s);*/
X+ }
X+ }
X+ mtx_lock(&allprison_mtx);
X+ pr =3D prison_find(j.u.v2.u.add_del.id);
X+ if (pr)
X+ {
X+ if (cnt !=3D ((j.u.v2.function =3D=3D ADDIP4 ||
j.u.v2.function =3D=3D DELIP4) ?=20
X+ pr->pr_ip4s : pr->pr_ip6s))=09
X+ {
X+ /* should i sleep ? */
X+ mtx_unlock(&pr->pr_mtx);
X+ mtx_unlock(&allprison_mtx);
X+ FREE(pr_new, alloc_type);
X+ /*printf("jail retry alloc\n");*/
X+ goto retry_alloc;
X+ }
X+ mtx_unlock(&allprison_mtx);
X+ }
X+ else
X+ {
X+ mtx_unlock(&allprison_mtx);
X+ return (EINVAL);
X+ }
X+ =09
X+ switch (j.u.v2.function) {
X+ case ADDIP4:
X+ error =3D
prison_add_ip4(&j.u.v2.u.add_del.v4_6.ip4_num, pr, pr_new, &pr_old);
X+ break;
X+ case ADDIP6:
X+ error =3D
prison_add_ip6(&j.u.v2.u.add_del.v4_6.ip6_num, pr, pr_new, &pr_old);
X+ break;
X+ case DELIP4:
X+ error =3D
prison_del_ip4(&j.u.v2.u.add_del.v4_6.ip4_num, pr, pr_new, &pr_old);
X+ break;
X+ case DELIP6:
X+ error =3D
prison_del_ip6(&j.u.v2.u.add_del.v4_6.ip6_num, pr, pr_new, &pr_old);
X+ break;
X+ default:
X+ mtx_unlock(&pr->pr_mtx);
X+ return EINVAL;
X+ }
X+ mtx_unlock(&pr->pr_mtx);
X+ if (pr_old) {
X+ /*printf("jail free:%p\n", pr_old);*/
X+ FREE(pr_old, alloc_type);
X+ }
X+ return (error);
X+ }
X+ }
X+ /* REST of Create Code */
X /* Determine next pr_id and add prison to allprison list. */
X mtx_lock(&allprison_mtx);
X tryprid =3D lastprid + 1;
X***************
X*** 146,152 ****
X if (tryprid =3D=3D JAIL_MAX) {
X mtx_unlock(&allprison_mtx);
X error =3D EAGAIN;
X! goto e_dropvnref;
X }
X goto next;
X }
X--- 288,295 ----
X if (tryprid =3D=3D JAIL_MAX) {
X mtx_unlock(&allprison_mtx);
X error =3D EAGAIN;
X! jail_dropvnref(pr);
X! return error;
X }
X goto next;
X }
X***************
X*** 164,181 ****
X mtx_unlock(&pr->pr_mtx);
X td->td_retval[0] =3D jaa.jid;
X return (0);
X e_dropprref:
X mtx_lock(&allprison_mtx);
X LIST_REMOVE(pr, pr_list);
X prisoncount--;
X mtx_unlock(&allprison_mtx);
X! e_dropvnref:
X! mtx_lock(&Giant);
X! vrele(pr->pr_root);
X! mtx_unlock(&Giant);
X! e_killmtx:
X! mtx_destroy(&pr->pr_mtx);
X! FREE(pr, M_PRISON);
X return (error);
X }
X =20
X--- 307,319 ----
X mtx_unlock(&pr->pr_mtx);
X td->td_retval[0] =3D jaa.jid;
X return (0);
X+=20
X e_dropprref:
X mtx_lock(&allprison_mtx);
X LIST_REMOVE(pr, pr_list);
X prisoncount--;
X mtx_unlock(&allprison_mtx);
X! jail_dropvnref(pr);
X return (error);
X }
X =20
X***************
X*** 248,253 ****
X--- 386,417 ----
X return (error);
X }
X =20
X+ /* return 0 on not duplicate */
X+ static int
X+ prison_check_duplicate(char *hostname, char *path)
X+ {
X+ struct prison *pr;
X+ mtx_lock(&allprison_mtx);
X+ LIST_FOREACH(pr, &allprison, pr_list) {
X+ if (!strncmp(hostname, pr->pr_host, sizeof(pr->pr_host))) {
X+ mtx_unlock(&allprison_mtx);
X+ return 1;
X+ }
X+ /* this is not perfect remove of trailing / or duplicated //
X+ should be done, who knows the kernel method for
this-:)
X+ */
X+ /*
X+ if (!strncmp(path, pr->pr_path, sizeof(pr->pr_path))) {
X+ mtx_unlock(&allprison_mtx);
X+ return 1;
X+ }
X+ */
X+ }
X+ mtx_unlock(&allprison_mtx);
X+ return 0;
X+ }
X+=20
X+=20
X /*
X * Returns a locked prison instance, or NULL on failure.
X */
X***************
X*** 299,304 ****
X--- 463,472 ----
X mtx_unlock(&Giant);
X =20
X mtx_destroy(&pr->pr_mtx);
X+ if (pr->pr_ip4 !=3D NULL)
X+ FREE(pr->pr_ip4, M_PRISON_IP4);
X+ if (pr->pr_ip6 !=3D NULL)
X+ FREE(pr->pr_ip6, M_PRISON_IP6);
X if (pr->pr_linux !=3D NULL)
X FREE(pr->pr_linux, M_PRISON);
X FREE(pr, M_PRISON);
X***************
X*** 313,371 ****
X mtx_unlock(&pr->pr_mtx);
X }
X =20
X! u_int32_t
X! prison_getip(struct ucred *cred)
X {
X =20
X! return (cred->cr_prison->pr_ip);
X }
X =20
X int
X! prison_ip(struct ucred *cred, int flag, u_int32_t *ip)
X {
X u_int32_t tmp;
X =20
X if (!jailed(cred))
X return (0);
X! if (flag)=20
X! tmp =3D *ip;
X! else
X! tmp =3D ntohl(*ip);
X! if (tmp =3D=3D INADDR_ANY) {
X! if (flag)=20
X! *ip =3D cred->cr_prison->pr_ip;
X! else
X! *ip =3D htonl(cred->cr_prison->pr_ip);
X! return (0);
X! }
X! if (tmp =3D=3D INADDR_LOOPBACK) {
X! if (flag)
X! *ip =3D cred->cr_prison->pr_ip;
X! else
X! *ip =3D htonl(cred->cr_prison->pr_ip);
X return (0);
X }
X! if (cred->cr_prison->pr_ip !=3D tmp)
X! return (1);
X! return (0);
X }
X =20
X! void
X! prison_remote_ip(struct ucred *cred, int flag, u_int32_t *ip)
X {
X u_int32_t tmp;
X =20
X if (!jailed(cred))
X return;
X! if (flag)
X! tmp =3D *ip;
X! else
X! tmp =3D ntohl(*ip);
X! if (tmp =3D=3D INADDR_LOOPBACK) {
X! if (flag)
X! *ip =3D cred->cr_prison->pr_ip;
X! else
X! *ip =3D htonl(cred->cr_prison->pr_ip);
X return;
X }
X return;
X--- 481,610 ----
X mtx_unlock(&pr->pr_mtx);
X }
X =20
X! int
X! prison_first_ip4(struct ucred *cred, struct in_addr *out)
X {
X+ int errno =3D 0;
X+ mtx_lock(&cred->cr_prison->pr_mtx);
X+ if (cred->cr_prison->pr_ip4s)=20
X+ *out =3D cred->cr_prison->pr_ip4[0];
X+ else
X+ errno =3D EADDRNOTAVAIL;
X+ mtx_unlock(&cred->cr_prison->pr_mtx);
X+ return errno;
X+ }
X =20
X! int
X! prison_first_ip6(struct ucred *cred, struct in6_addr *out)
X! {
X! int errno =3D 0;
X! mtx_lock(&cred->cr_prison->pr_mtx);
X! if (cred->cr_prison->pr_ip6s)
X! *out =3D cred->cr_prison->pr_ip6[0];
X! else
X! errno =3D EADDRNOTAVAIL;
X! mtx_unlock(&cred->cr_prison->pr_mtx);
X! return errno;
X }
X =20
X int
X! prison_match_ip4(struct ucred *cred, struct in_addr *ip)
X {
X u_int32_t tmp;
X =20
X if (!jailed(cred))
X return (0);
X!=20
X! for (tmp =3D 0; tmp < cred->cr_prison->pr_ip4s; ++tmp)
X! {
X! if (cred->cr_prison->pr_ip4[tmp].s_addr =3D=3D ip->s_addr)
X! {
X! return 0;
X! }
X! }
X! return (1);
X! }
X!=20
X! int
X! prison_redirect_ip4(struct ucred *cred, struct in_addr *ip)
X! {
X! if (!jailed(cred))
X! return (0);
X! if (cred->cr_prison->pr_ip4s <=3D 0)
X! return (0);
X!=20
X! if (ip->s_addr =3D=3D htonl(INADDR_ANY)) {
X! *ip =3D cred->cr_prison->pr_ip4[0];
X return (0);
X }
X! if (ip->s_addr =3D=3D htonl(INADDR_LOOPBACK)) {
X! *ip =3D cred->cr_prison->pr_ip4[0];
X! return (0);
X! }
X! return prison_match_ip4(cred, ip);
X }
X =20
X! int
X! prison_match_ip6(struct ucred *cred, struct in6_addr *ip)
X {
X u_int32_t tmp;
X =20
X if (!jailed(cred))
X+ return (0);
X+=20
X+ for (tmp =3D 0; tmp < cred->cr_prison->pr_ip6s; ++tmp)
X+ {
X+ if (IN6_ARE_ADDR_EQUAL(&(cred->cr_prison->pr_ip6[tmp]), ip))
X+ {
X+ return 0;
X+ }
X+ }
X+ return (1);
X+ }
X+=20
X+=20
X+ int
X+ prison_redirect_ip6(struct ucred *cred, struct in6_addr *ip)
X+ {
X+ if (!jailed(cred))
X+ return (0);
X+ if (cred->cr_prison->pr_ip6s <=3D 0)
X+ return (0);
X+=20
X+ if (IN6_ARE_ADDR_EQUAL(ip, &in6addr_any)) {
X+ *ip =3D cred->cr_prison->pr_ip6[0];
X+ return (0);
X+ }
X+ if (IN6_IS_ADDR_LOOPBACK(ip)) {
X+ *ip =3D cred->cr_prison->pr_ip6[0];
X+ return (0);
X+ }
X+ return prison_match_ip6(cred, ip);
X+ }
X+=20
X+ void
X+ prison_remote_ip4(struct ucred *cred, struct in_addr *ip)
X+ {
X+ if (!jailed(cred))
X return;
X! if (cred->cr_prison->pr_ip4s <=3D 0)
X! return;
X! if (ip->s_addr =3D=3D INADDR_LOOPBACK) {
X! *ip =3D cred->cr_prison->pr_ip4[0];
X! return;
X! }
X! return;
X! }
X!=20
X! void
X! prison_remote_ip6(struct ucred *cred, struct in6_addr *ip)
X! {
X! if (!jailed(cred))
X! return;
X! if (cred->cr_prison->pr_ip6s <=3D 0)
X! return;
X! if (IN6_IS_ADDR_LOOPBACK(ip)) {
X! *ip =3D cred->cr_prison->pr_ip6[0];
X return;
X }
X return;
X***************
X*** 374,391 ****
X int
X prison_if(struct ucred *cred, struct sockaddr *sa)
X {
X! struct sockaddr_in *sai;
X! int ok;
X =20
X! sai =3D (struct sockaddr_in *)sa;
X! if ((sai->sin_family !=3D AF_INET) && jail_socket_unixiproute_only)
X ok =3D 1;
X! else if (sai->sin_family !=3D AF_INET)
X! ok =3D 0;
X! else if (cred->cr_prison->pr_ip !=3D ntohl(sai->sin_addr.s_addr))
X! ok =3D 1;
X! else
X! ok =3D 0;
X return (ok);
X }
X =20
X--- 613,655 ----
X int
X prison_if(struct ucred *cred, struct sockaddr *sa)
X {
X! int ok =3D 0;
X =20
X! if (!(sa->sa_family =3D=3D AF_INET || sa->sa_family =3D=3D AF_INET6) =
X! && jail_socket_unixiproute_only)
X ok =3D 1;
X! else=20
X! {
X! if (sa->sa_family =3D=3D AF_INET)
X! {
X! int tmp;
X! struct sockaddr_in *sai =3D (struct sockaddr_in *)sa;
X! ok =3D 1;
X! for (tmp =3D 0; tmp < cred->cr_prison->pr_ip4s; ++tmp)
X! {
X! if (cred->cr_prison->pr_ip4[tmp].s_addr =3D=3D
sai->sin_addr.s_addr)
X! {
X! ok =3D 0;
X! break;
X! }
X! }
X! }
X! else if (sa->sa_family =3D=3D AF_INET6)
X! {
X! struct sockaddr_in6 *sa6 =3D (struct sockaddr_in6
*)sa;
X! int tmp;
X! ok =3D 1;
X! for (tmp =3D 0; tmp < cred->cr_prison->pr_ip6s; ++tmp)
X! {
X! if
(IN6_ARE_ADDR_EQUAL(&(cred->cr_prison->pr_ip6[tmp]),=20
X! &(sa6->sin6_addr)))
X! {
X! ok =3D 0;
X! break;
X! }
X! }
X! }
X! }
X return (ok);
X }
X =20
X***************
X*** 407,412 ****
X--- 671,808 ----
X }
X =20
X /*
X+ * assumes that mtx_lock (pr->mtx) is done
X+ */
X+ static int
X+ prison_add_ip4(struct in_addr *ip, struct prison *pr, void *vpr_new, =
void
**pr_free)
X+ {
X+ struct in_addr *pr_new =3D vpr_new;
X+ struct in_addr *wrk_new;
X+=20
X+ wrk_new =3D pr_new;
X+ if (pr->pr_ip4s > 0)
X+ {
X+ struct in_addr *pr_old =3D pr->pr_ip4;
X+ for (;pr_old < &(pr->pr_ip4[pr->pr_ip4s]) ; ++pr_old)
X+ {
X+ if (pr_old->s_addr =3D=3D ip->s_addr)
X+ {
X+ *pr_free =3D pr_new;
X+ return 0;
X+ }
X+ *wrk_new++ =3D *pr_old;
X+ }=20
X+ }
X+ *wrk_new =3D *ip;
X+ ++(pr->pr_ip4s);
X+ if (pr->pr_ip4)
X+ *pr_free =3D pr->pr_ip4;
X+ pr->pr_ip4 =3D pr_new;
X+ return 0;=09
X+ }
X+=20
X+ static int
X+ prison_add_ip6(struct in6_addr *ip, struct prison *pr, void *vpr_new,
void **pr_free)
X+ {
X+ struct in6_addr *pr_new =3D vpr_new;
X+ struct in6_addr *wrk_new;
X+=20
X+ wrk_new =3D pr_new;
X+ if (pr->pr_ip6s > 0)
X+ {
X+ struct in6_addr *pr_old =3D pr->pr_ip6;
X+ for (;pr_old < &(pr->pr_ip6[pr->pr_ip6s]) ; ++pr_old)
X+ {
X+ if (IN6_ARE_ADDR_EQUAL(pr_old, ip))
X+ {
X+ *pr_free =3D pr_new;
X+ return 0;
X+ }
X+ *wrk_new++ =3D *pr_old;
X+ }=20
X+ }
X+ *wrk_new =3D *ip;
X+ ++(pr->pr_ip6s);
X+ if (pr->pr_ip6)
X+ *pr_free =3D pr->pr_ip6;
X+ pr->pr_ip6 =3D pr_new;
X+ return 0;=09
X+ }
X+=20
X+ static int
X+ prison_del_ip4(struct in_addr *ip, struct prison *pr, void *vpr_new, =
void
**pr_free)
X+ {
X+ struct in_addr *pr_new =3D vpr_new;
X+ struct in_addr *wrk_new;
X+ int errno =3D ENOENT;
X+=20
X+ wrk_new =3D pr_new;
X+ if (pr->pr_ip4s > 0)
X+ {
X+ struct in_addr *pr_old =3D pr->pr_ip4;
X+ for (;pr_old < &(pr->pr_ip4[pr->pr_ip4s]) ; ++pr_old)
X+ {
X+ if (pr_old->s_addr !=3D ip->s_addr)
X+ {
X+ if (wrk_new) { /* remove only if one or more
elements remaining */
X+ *wrk_new++ =3D *pr_old;
X+ }
X+ }
X+ else
X+ {
X+ errno =3D 0; /* found element to delete */
X+ }
X+ }=20
X+ }
X+ if (errno =3D=3D 0)
X+ {
X+ --(pr->pr_ip4s);
X+ /* attach new array */
X+ if (pr->pr_ip4)
X+ *pr_free =3D pr->pr_ip4;
X+ pr->pr_ip4 =3D pr_new;
X+ }
X+ return errno;=09
X+ }
X+=20
X+ static int
X+ prison_del_ip6(struct in6_addr *ip, struct prison *pr, void *vpr_new,
void **pr_free)
X+ {
X+ struct in6_addr *pr_new =3D vpr_new;
X+ struct in6_addr *wrk_new;
X+ int errno =3D ENOENT;
X+=20
X+ wrk_new =3D pr_new;
X+ if (pr->pr_ip6s > 0)
X+ {
X+ struct in6_addr *pr_old =3D pr->pr_ip6;
X+ for (;pr_old < &(pr->pr_ip6[pr->pr_ip6s]) ; ++pr_old)
X+ {
X+ if (!IN6_ARE_ADDR_EQUAL(pr_old, ip))
X+ {
X+ if (wrk_new) { /* remove only if one or more
elements remaining */
X+ *wrk_new++ =3D *pr_old;
X+ }
X+ }
X+ else
X+ {
X+ errno =3D 0; /* found element to delete */
X+ }
X+ }=20
X+ }
X+ if (errno =3D=3D 0)
X+ {
X+ --(pr->pr_ip6s);
X+ /* attach new array */
X+ if (pr->pr_ip6)
X+ *pr_free =3D pr->pr_ip6;
X+ pr->pr_ip6 =3D pr_new;
X+ }
X+ return errno;=09
X+ }
X+=20
X+=20
X+ /*
X * Return 1 if the passed credential is in a jail, otherwise 0.
X */
X int
X***************
X*** 452,486 ****
X struct xprison *xp, *sxp;
X struct prison *pr;
X int count, error;
X =20
X mtx_assert(&Giant, MA_OWNED);
X if (jailed(req->td->td_ucred))
X return (0);
X retry:
X mtx_lock(&allprison_mtx);
X! count =3D prisoncount;
X mtx_unlock(&allprison_mtx);
X =20
X if (count =3D=3D 0)
X return (0);
X =20
X sxp =3D xp =3D malloc(sizeof(*xp) * count, M_TEMP, M_WAITOK | =
M_ZERO);
X mtx_lock(&allprison_mtx);
X! if (count !=3D prisoncount) {
X mtx_unlock(&allprison_mtx);
X free(sxp, M_TEMP);
X goto retry;
X }
X =09
X LIST_FOREACH(pr, &allprison, pr_list) {
X! mtx_lock(&pr->pr_mtx);
X! xp->pr_version =3D XPRISON_VERSION;
X! xp->pr_id =3D pr->pr_id;
X! strlcpy(xp->pr_path, pr->pr_path, sizeof(xp->pr_path));
X! strlcpy(xp->pr_host, pr->pr_host, sizeof(xp->pr_host));
X! xp->pr_ip =3D pr->pr_ip;
X! mtx_unlock(&pr->pr_mtx);
X! xp++;
X }
X mtx_unlock(&allprison_mtx);
X =20
X--- 848,914 ----
X struct xprison *xp, *sxp;
X struct prison *pr;
X int count, error;
X+ int prcount;
X =20
X mtx_assert(&Giant, MA_OWNED);
X if (jailed(req->td->td_ucred))
X return (0);
X retry:
X mtx_lock(&allprison_mtx);
X! count =3D 0;
X! prcount =3D 0;
X! LIST_FOREACH(pr, &allprison, pr_list) {
X! ++prcount;
X! if (pr->pr_ip4s || pr->pr_ip6s) {
X! count +=3D max(pr->pr_ip4s, pr->pr_ip6s);
X! }=09
X! else {
X! ++count;
X! }
X! }
X mtx_unlock(&allprison_mtx);
X =20
X if (count =3D=3D 0)
X return (0);
X =20
X+ /*printf("jls:count=3D%d:%d\n", count, prcount);*/
X sxp =3D xp =3D malloc(sizeof(*xp) * count, M_TEMP, M_WAITOK | =
M_ZERO);
X mtx_lock(&allprison_mtx);
X! if (prcount !=3D prisoncount) {
X mtx_unlock(&allprison_mtx);
X free(sxp, M_TEMP);
X goto retry;
X }
X =09
X LIST_FOREACH(pr, &allprison, pr_list) {
X! int id =3D 0;
X! int i;
X! int maxcnt =3D max(pr->pr_ip4s, pr->pr_ip6s);
X! /*printf("jls:maxcnt=3D%d\n", maxcnt);*/
X! for (i =3D 0; i < (maxcnt ? maxcnt : 1) ; ++i)
X! {=09
X! /*printf("jls:-0-:%d:%d\n", i, maxcnt);*/
X! mtx_lock(&pr->pr_mtx);
X! xp->pr_version =3D XPRISON_VERSION;
X! xp->pr_id =3D pr->pr_id;
X! strlcpy(xp->pr_path, pr->pr_path,
sizeof(xp->pr_path));
X! strlcpy(xp->pr_host, pr->pr_host,
sizeof(xp->pr_host));
X! if (i < pr->pr_ip4s) {
X! xp->pr4_id =3D id;
X! xp->pr4_num =3D pr->pr_ip4[i];
X! }
X! else
X! xp->pr4_id =3D -1;
X! if (i < pr->pr_ip6s) {
X! xp->pr6_id =3D id;
X! xp->pr6_num =3D pr->pr_ip6[i];
X! }
X! else
X! xp->pr6_id =3D -1;
X! ++id;
X! mtx_unlock(&pr->pr_mtx);
X! xp++;
X! }
X }
X mtx_unlock(&allprison_mtx);
X =20
XIndex: sys/net/rtsock.c
X=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
XRCS file: /usr/freebsd.cvs/src/sys/net/rtsock.c,v
Xretrieving revision 1.113.2.3
Xdiff -c -r1.113.2.3 rtsock.c
X*** sys/net/rtsock.c 15 Sep 2004 15:14:18 -0000 1.113.2.3
X--- sys/net/rtsock.c 24 Nov 2004 23:41:10 -0000
X***************
X*** 329,335 ****
X int len, error =3D 0;
X struct ifnet *ifp =3D NULL;
X struct ifaddr *ifa =3D NULL;
X! struct sockaddr_in jail;
X =20
X #define senderr(e) { error =3D e; goto flush;}
X if (m =3D=3D NULL || ((m->m_len < sizeof(long)) &&
X--- 329,336 ----
X int len, error =3D 0;
X struct ifnet *ifp =3D NULL;
X struct ifaddr *ifa =3D NULL;
X! struct sockaddr_in jail4;
X! struct sockaddr_in6 jail6;
X =20
X #define senderr(e) { error =3D e; goto flush;}
X if (m =3D=3D NULL || ((m->m_len < sizeof(long)) &&
X***************
X*** 444,456 ****
X info.rti_info[RTAX_IFP] =3D
X
ifaddr_byindex(ifp->if_index)->ifa_addr;
X if (jailed(so->so_cred)) {
X! bzero(&jail, sizeof(jail));
X! jail.sin_family =3D PF_INET;
X! jail.sin_len =3D sizeof(jail);
X! jail.sin_addr.s_addr =3D
X!
htonl(prison_getip(so->so_cred));
X! info.rti_info[RTAX_IFA] =3D
X! (struct sockaddr
*)&jail;
X } else
X info.rti_info[RTAX_IFA] =3D
X rt->rt_ifa->ifa_addr;
X--- 445,476 ----
X info.rti_info[RTAX_IFP] =3D
X
ifaddr_byindex(ifp->if_index)->ifa_addr;
X if (jailed(so->so_cred)) {
X! if
(rt->rt_ifa->ifa_addr->sa_family =3D=3D PF_INET) {
X! bzero(&jail4,
sizeof(jail4));
X! jail4.sin_family =3D
PF_INET;
X! jail4.sin_len =3D
sizeof(jail4);
X! error =3D
prison_first_ip4(so->so_cred,=20
X!
&jail4.sin_addr);=20
X! if (error)
X!
senderr(error);
X!
info.rti_info[RTAX_IFA] =3D
X! (struct sockaddr
*)&jail4;
X! }
X! else if
(rt->rt_ifa->ifa_addr->sa_family =3D=3D PF_INET6) {
X! bzero(&jail6,
sizeof(jail6));
X! jail6.sin6_family =3D
PF_INET6;
X! jail6.sin6_len =3D
sizeof(jail6);
X! error =3D
prison_first_ip6(so->so_cred,=20
X!
&jail6.sin6_addr);=20
X! if (error)
X!
senderr(error);
X!
info.rti_info[RTAX_IFA] =3D
X! (struct sockaddr
*)&jail6;
X! }
X! else {
X!
info.rti_info[RTAX_IFA] =3D
X!
rt->rt_ifa->ifa_addr;
X! }
X } else
X info.rti_info[RTAX_IFA] =3D
X rt->rt_ifa->ifa_addr;
XIndex: sys/netinet/in_pcb.c
X=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
XRCS file: /usr/freebsd.cvs/src/sys/netinet/in_pcb.c,v
Xretrieving revision 1.153.2.1.2.1
Xdiff -c -r1.153.2.1.2.1 in_pcb.c
X*** sys/netinet/in_pcb.c 21 Oct 2004 09:30:47 -0000
1.153.2.1.2.1
X--- sys/netinet/in_pcb.c 24 Nov 2004 23:41:10 -0000
X***************
X*** 290,296 ****
X return (EAFNOSUPPORT);
X #endif
X if (sin->sin_addr.s_addr !=3D INADDR_ANY)
X! if (prison_ip(cred, 0, &sin->sin_addr.s_addr))
X return(EINVAL);
X if (sin->sin_port !=3D *lportp) {
X /* Don't allow the port to change. */
X--- 290,296 ----
X return (EAFNOSUPPORT);
X #endif
X if (sin->sin_addr.s_addr !=3D INADDR_ANY)
X! if (prison_redirect_ip4(cred, &sin->sin_addr))=20
X return(EINVAL);
X if (sin->sin_port !=3D *lportp) {
X /* Don't allow the port to change. */
X***************
X*** 346,352 ****
X t->inp_socket->so_cred->cr_uid))
X return (EADDRINUSE);
X }
X! if (prison && prison_ip(cred, 0,
&sin->sin_addr.s_addr))
X return (EADDRNOTAVAIL);
X t =3D in_pcblookup_local(pcbinfo, sin->sin_addr,
X lport, prison ? 0 : wild);
X--- 346,352 ----
X t->inp_socket->so_cred->cr_uid))
X return (EADDRINUSE);
X }
X! if (prison && prison_redirect_ip4(cred,
&sin->sin_addr))=20
X return (EADDRNOTAVAIL);
X t =3D in_pcblookup_local(pcbinfo, sin->sin_addr,
X lport, prison ? 0 : wild);
X***************
X*** 375,381 ****
X int count;
X =20
X if (laddr.s_addr !=3D INADDR_ANY)
X! if (prison_ip(cred, 0, &laddr.s_addr))
X return (EINVAL);
X =20
X if (inp->inp_flags & INP_HIGHPORT) {
X--- 375,381 ----
X int count;
X =20
X if (laddr.s_addr !=3D INADDR_ANY)
X! if (prison_redirect_ip4(cred, &laddr))=20
X return (EINVAL);
X =20
X if (inp->inp_flags & INP_HIGHPORT) {
X***************
X*** 438,444 ****
X wild));
X }
X }
X! if (prison_ip(cred, 0, &laddr.s_addr))
X return (EINVAL);
X *laddrp =3D laddr.s_addr;
X *lportp =3D lport;
X--- 438,444 ----
X wild));
X }
X }
X! if (prison_redirect_ip4(cred, &laddr))=20
X return (EINVAL);
X *laddrp =3D laddr.s_addr;
X *lportp =3D lport;
X***************
X*** 551,557 ****
X socred =3D inp->inp_socket->so_cred;
X if (laddr.s_addr =3D=3D INADDR_ANY && jailed(socred)) {
X bzero(&sa, sizeof(sa));
X! sa.sin_addr.s_addr =3D htonl(prison_getip(socred));
X sa.sin_len =3D sizeof(sa);
X sa.sin_family =3D AF_INET;
X error =3D in_pcbbind_setup(inp, (struct sockaddr *)&sa,
X--- 551,559 ----
X socred =3D inp->inp_socket->so_cred;
X if (laddr.s_addr =3D=3D INADDR_ANY && jailed(socred)) {
X bzero(&sa, sizeof(sa));
X! error =3D prison_first_ip4(socred, &sa.sin_addr);
X! if (error)
X! return (error);
X sa.sin_len =3D sizeof(sa);
X sa.sin_family =3D AF_INET;
X error =3D in_pcbbind_setup(inp, (struct sockaddr *)&sa,
XIndex: sys/netinet/raw_ip.c
X=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
XRCS file: /usr/freebsd.cvs/src/sys/netinet/raw_ip.c,v
Xretrieving revision 1.142.2.2
Xdiff -c -r1.142.2.2 raw_ip.c
X*** sys/netinet/raw_ip.c 14 Oct 2004 11:45:26 -0000 1.142.2.2
X--- sys/netinet/raw_ip.c 24 Nov 2004 23:41:10 -0000
X***************
X*** 212,220 ****
X if (inp->inp_faddr.s_addr &&
X inp->inp_faddr.s_addr !=3D ip->ip_src.s_addr)
X goto docontinue;
X if (jailed(inp->inp_socket->so_cred))
X! if (htonl(prison_getip(inp->inp_socket->so_cred)) !=3D
X! ip->ip_dst.s_addr)
X goto docontinue;
X if (last) {
X struct mbuf *n;
X--- 212,220 ----
X if (inp->inp_faddr.s_addr &&
X inp->inp_faddr.s_addr !=3D ip->ip_src.s_addr)
X goto docontinue;
X+ =09
X if (jailed(inp->inp_socket->so_cred))
X! if (prison_match_ip4(inp->inp_socket->so_cred,
&(ip->ip_dst)))=20
X goto docontinue;
X if (last) {
X struct mbuf *n;
X***************
X*** 271,278 ****
X ip->ip_p =3D inp->inp_ip_p;
X ip->ip_len =3D m->m_pkthdr.len;
X if (jailed(inp->inp_socket->so_cred))
X! ip->ip_src.s_addr =3D
X! htonl(prison_getip(inp->inp_socket->so_cred));
X else
X ip->ip_src =3D inp->inp_laddr;
X ip->ip_dst.s_addr =3D dst;
X--- 271,286 ----
X ip->ip_p =3D inp->inp_ip_p;
X ip->ip_len =3D m->m_pkthdr.len;
X if (jailed(inp->inp_socket->so_cred))
X! {
X! /* fallback to first ip */
X! if (prison_match_ip4(inp->inp_socket->so_cred,
&inp->inp_laddr)) {
X! if ((error =3D
prison_first_ip4(inp->inp_socket->so_cred,=20
X! &ip->ip_src))
!=3D 0)
X! return error;
X! }
X! else
X! ip->ip_src =3D inp->inp_laddr;
X! }
X else
X ip->ip_src =3D inp->inp_laddr;
X ip->ip_dst.s_addr =3D dst;
X***************
X*** 285,292 ****
X INP_LOCK(inp);
X ip =3D mtod(m, struct ip *);
X if (jailed(inp->inp_socket->so_cred)) {
X! if (ip->ip_src.s_addr !=3D
X! htonl(prison_getip(inp->inp_socket->so_cred))) {
X INP_UNLOCK(inp);
X m_freem(m);
X return (EPERM);
X--- 293,299 ----
X INP_LOCK(inp);
X ip =3D mtod(m, struct ip *);
X if (jailed(inp->inp_socket->so_cred)) {
X! if (prison_match_ip4(inp->inp_socket->so_cred,
&ip->ip_src)) {
X INP_UNLOCK(inp);
X m_freem(m);
X return (EPERM);
X***************
X*** 684,693 ****
X return EINVAL;
X =20
X if (jailed(td->td_ucred)) {
X if (addr->sin_addr.s_addr =3D=3D INADDR_ANY)
X! addr->sin_addr.s_addr =3D
X! htonl(prison_getip(td->td_ucred));
X! if (htonl(prison_getip(td->td_ucred)) !=3D
addr->sin_addr.s_addr)
X return (EADDRNOTAVAIL);
X }
X =20
X--- 691,701 ----
X return EINVAL;
X =20
X if (jailed(td->td_ucred)) {
X+ int error;
X if (addr->sin_addr.s_addr =3D=3D INADDR_ANY)
X! if ((error =3D prison_first_ip4(td->td_ucred,
&addr->sin_addr)) !=3D 0)
X! return error;
X! if (prison_match_ip4(td->td_ucred, &addr->sin_addr))=20
X return (EADDRNOTAVAIL);
X }
X =20
XIndex: sys/netinet/tcp_usrreq.c
X=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
XRCS file: /usr/freebsd.cvs/src/sys/netinet/tcp_usrreq.c,v
Xretrieving revision 1.107
Xdiff -c -r1.107 tcp_usrreq.c
X*** sys/netinet/tcp_usrreq.c 16 Aug 2004 18:32:07 -0000 1.107
X--- sys/netinet/tcp_usrreq.c 24 Nov 2004 23:41:10 -0000
X***************
X*** 356,362 ****
X && IN_MULTICAST(ntohl(sinp->sin_addr.s_addr)))
X return (EAFNOSUPPORT);
X if (td && jailed(td->td_ucred))
X! prison_remote_ip(td->td_ucred, 0, &sinp->sin_addr.s_addr);
X =20
X COMMON_START();
X if ((error =3D tcp_connect(tp, nam, td)) !=3D 0)
X--- 356,362 ----
X && IN_MULTICAST(ntohl(sinp->sin_addr.s_addr)))
X return (EAFNOSUPPORT);
X if (td && jailed(td->td_ucred))
X! prison_remote_ip4(td->td_ucred, &sinp->sin_addr);=20
X =20
X COMMON_START();
X if ((error =3D tcp_connect(tp, nam, td)) !=3D 0)
X***************
X*** 385,390 ****
X--- 385,393 ----
X && IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr))
X return (EAFNOSUPPORT);
X =20
X+ if (td && jailed(td->td_ucred))
X+ prison_remote_ip6(td->td_ucred, &sin6p->sin6_addr);=20
X+=20
X COMMON_START();
X if (IN6_IS_ADDR_V4MAPPED(&sin6p->sin6_addr)) {
X struct sockaddr_in sin;
XIndex: sys/netinet/udp_usrreq.c
X=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
XRCS file: /usr/freebsd.cvs/src/sys/netinet/udp_usrreq.c,v
Xretrieving revision 1.162.2.3
Xdiff -c -r1.162.2.3 udp_usrreq.c
X*** sys/netinet/udp_usrreq.c 14 Oct 2004 11:49:25 -0000 1.162.2.3
X--- sys/netinet/udp_usrreq.c 24 Nov 2004 23:41:10 -0000
X***************
X*** 822,828 ****
X if (addr) {
X sin =3D (struct sockaddr_in *)addr;
X if (td && jailed(td->td_ucred))
X! prison_remote_ip(td->td_ucred, 0,
&sin->sin_addr.s_addr);
X if (inp->inp_faddr.s_addr !=3D INADDR_ANY) {
X error =3D EISCONN;
X goto release;
X--- 822,828 ----
X if (addr) {
X sin =3D (struct sockaddr_in *)addr;
X if (td && jailed(td->td_ucred))
X! prison_remote_ip4(td->td_ucred, &sin->sin_addr);=20
X if (inp->inp_faddr.s_addr !=3D INADDR_ANY) {
X error =3D EISCONN;
X goto release;
X***************
X*** 1029,1035 ****
X s =3D splnet();
X sin =3D (struct sockaddr_in *)nam;
X if (td && jailed(td->td_ucred))
X! prison_remote_ip(td->td_ucred, 0, &sin->sin_addr.s_addr);
X error =3D in_pcbconnect(inp, nam, td->td_ucred);
X splx(s);
X if (error =3D=3D 0)
X--- 1029,1035 ----
X s =3D splnet();
X sin =3D (struct sockaddr_in *)nam;
X if (td && jailed(td->td_ucred))
X! prison_remote_ip4(td->td_ucred, &sin->sin_addr);
X error =3D in_pcbconnect(inp, nam, td->td_ucred);
X splx(s);
X if (error =3D=3D 0)
XIndex: sys/netinet6/in6_pcb.c
X=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
XRCS file: /usr/freebsd.cvs/src/sys/netinet6/in6_pcb.c,v
Xretrieving revision 1.59.2.1.2.1
Xdiff -c -r1.59.2.1.2.1 in6_pcb.c
X*** sys/netinet6/in6_pcb.c 21 Oct 2004 09:30:47 -0000 1.59.2.1.2.1
X--- sys/netinet6/in6_pcb.c 24 Nov 2004 23:41:10 -0000
X***************
X*** 127,132 ****
X--- 127,133 ----
X struct sockaddr_in6 *sin6 =3D (struct sockaddr_in6 *)NULL;
X struct inpcbinfo *pcbinfo =3D inp->inp_pcbinfo;
X u_short lport =3D 0;
X+ int prison =3D 0;
X int wild =3D 0, reuseport =3D (so->so_options & SO_REUSEPORT);
X =20
X INP_INFO_WLOCK_ASSERT(pcbinfo);
X***************
X*** 148,153 ****
X--- 149,158 ----
X if (nam->sa_family !=3D AF_INET6)
X return (EAFNOSUPPORT);
X =20
X+ if (!IN6_ARE_ADDR_EQUAL(&in6addr_any, &sin6->sin6_addr))=20
X+ if (prison_redirect_ip6(cred, &sin6->sin6_addr))=20
X+ return (EINVAL);
X+=20
X /* KAME hack: embed scopeid */
X if (in6_embedscope(&sin6->sin6_addr, sin6, inp, NULL) !=3D 0)
X return EINVAL;
X***************
X*** 191,202 ****
X if (ntohs(lport) < IPV6PORT_RESERVED &&
X suser_cred(cred, SUSER_ALLOWJAIL))
X return (EACCES);
X if (so->so_cred->cr_uid !=3D 0 &&
X !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
X t =3D in6_pcblookup_local(pcbinfo,
X &sin6->sin6_addr, lport,
X! INPLOOKUP_WILDCARD);
X! if (t &&
X ((t->inp_vflag & INP_TIMEWAIT) =3D=3D 0) &&
X (so->so_type !=3D SOCK_STREAM ||
X
IN6_IS_ADDR_UNSPECIFIED(&t->in6p_faddr)) &&
X--- 196,215 ----
X if (ntohs(lport) < IPV6PORT_RESERVED &&
X suser_cred(cred, SUSER_ALLOWJAIL))
X return (EACCES);
X+ prison =3D jailed(cred);=20
X if (so->so_cred->cr_uid !=3D 0 &&
X !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
X t =3D in6_pcblookup_local(pcbinfo,
X &sin6->sin6_addr, lport,
X! prison ? 0 : INPLOOKUP_WILDCARD);
X! if (t && (t->inp_vflag & INP_TIMEWAIT)) {
X! if
((!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
X!
!IN6_IS_ADDR_UNSPECIFIED(&t->in6p_laddr) ||
X! !(intotw(t)->tw_so_options &
SO_REUSEPORT))
X! && so->so_cred->cr_uid !=3D=20
X! intotw(t)->tw_cred->cr_uid)
X! return (EADDRINUSE);
X! } else if (t &&
X ((t->inp_vflag & INP_TIMEWAIT) =3D=3D 0) &&
X (so->so_type !=3D SOCK_STREAM ||
X
IN6_IS_ADDR_UNSPECIFIED(&t->in6p_faddr)) &&
X***************
X*** 225,232 ****
X return (EADDRINUSE);
X }
X }
X t =3D in6_pcblookup_local(pcbinfo, &sin6->sin6_addr,
X! lport, wild);
X if (t && (reuseport & ((t->inp_vflag & INP_TIMEWAIT)
?
X intotw(t)->tw_so_options :=20
X t->inp_socket->so_options)) =3D=3D 0)
X--- 238,247 ----
X return (EADDRINUSE);
X }
X }
X+ if (prison && prison_redirect_ip6(cred,
&sin6->sin6_addr))
X+ return (EADDRNOTAVAIL);
X t =3D in6_pcblookup_local(pcbinfo, &sin6->sin6_addr,
X! lport, prison ? 0 : wild);
X if (t && (reuseport & ((t->inp_vflag & INP_TIMEWAIT)
?
X intotw(t)->tw_so_options :=20
X t->inp_socket->so_options)) =3D=3D 0)
XIndex: sys/netinet6/raw_ip6.c
X=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
XRCS file: /usr/freebsd.cvs/src/sys/netinet6/raw_ip6.c,v
Xretrieving revision 1.45.2.1
Xdiff -c -r1.45.2.1 raw_ip6.c
X*** sys/netinet6/raw_ip6.c 2 Sep 2004 21:18:09 -0000 1.45.2.1
X--- sys/netinet6/raw_ip6.c 24 Nov 2004 23:41:10 -0000
X***************
X*** 68,73 ****
X--- 68,74 ----
X #include <sys/lock.h>
X #include <sys/malloc.h>
X #include <sys/mbuf.h>
X+ #include <sys/jail.h>
X #include <sys/proc.h>
X #include <sys/protosw.h>
X #include <sys/signalvar.h>
X***************
X*** 174,179 ****
X--- 175,185 ----
X goto docontinue;
X }
X }
X+=20
X+ if (jailed(in6p->in6p_socket->so_cred))
X+ if (prison_match_ip6(in6p->in6p_socket->so_cred,
&(ip6->ip6_dst)))
X+ continue;
X+=20
X if (last) {
X struct mbuf *n =3D m_copy(m, 0, (int)M_COPYALL);
X =20
X***************
X*** 433,439 ****
X error =3D EADDRNOTAVAIL;
X goto bad;
X }
X! ip6->ip6_src =3D *in6a;
X ip6->ip6_flow =3D (ip6->ip6_flow & ~IPV6_FLOWINFO_MASK) |
X (in6p->in6p_flowinfo & IPV6_FLOWINFO_MASK);
X ip6->ip6_vfc =3D (ip6->ip6_vfc & ~IPV6_VERSION_MASK) |
X--- 439,458 ----
X error =3D EADDRNOTAVAIL;
X goto bad;
X }
X! if (jailed(in6p->in6p_socket->so_cred))
X! {
X! /* fallback to first ip */
X! if (prison_match_ip6(in6p->in6p_socket->so_cred, in6a)) {
X! if ((error =3D
prison_first_ip6(in6p->in6p_socket->so_cred,=20
X! &ip6->ip6_src)) !=3D 0)
X! return error;
X! }
X! else
X! ip6->ip6_src =3D *in6a;
X! }
X! else
X! ip6->ip6_src =3D *in6a;
X!=20
X ip6->ip6_flow =3D (ip6->ip6_flow & ~IPV6_FLOWINFO_MASK) |
X (in6p->in6p_flowinfo & IPV6_FLOWINFO_MASK);
X ip6->ip6_vfc =3D (ip6->ip6_vfc & ~IPV6_VERSION_MASK) |
X***************
X*** 578,583 ****
X--- 597,606 ----
X INP_INFO_WUNLOCK(&ripcbinfo);
X return error;
X }
X+ if (td && jailed(td->td_ucred) && !jail_allow_raw_sockets) {
X+ return (EPERM);
X+ }
X+=20
X error =3D soreserve(so, rip_sendspace, rip_recvspace);
X if (error) {
X INP_INFO_WUNLOCK(&ripcbinfo);
X***************
X*** 655,660 ****
X--- 678,693 ----
X =20
X if (nam->sa_len !=3D sizeof(*addr))
X return EINVAL;
X+=20
X+ if (jailed(td->td_ucred)) {
X+ if (IN6_ARE_ADDR_EQUAL(&(addr->sin6_addr), &in6addr_any)) {
X+ int error;
X+ if ((error =3D prison_first_ip6(td->td_ucred,
&addr->sin6_addr)) !=3D 0)
X+ return error;
X+ }
X+ if (prison_match_ip6(td->td_ucred, &addr->sin6_addr))=20
X+ return (EADDRNOTAVAIL);
X+ }
X if (TAILQ_EMPTY(&ifnet) || addr->sin6_family !=3D AF_INET6)
X return EADDRNOTAVAIL;
X #ifdef ENABLE_DEFAULT_SCOPE
XIndex: sys/netinet6/udp6_output.c
X=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
XRCS file: /usr/freebsd.cvs/src/sys/netinet6/udp6_output.c,v
Xretrieving revision 1.18
Xdiff -c -r1.18 udp6_output.c
X*** sys/netinet6/udp6_output.c 7 Apr 2004 20:46:16 -0000 1.18
X--- sys/netinet6/udp6_output.c 24 Nov 2004 23:41:10 -0000
X***************
X*** 67,72 ****
X--- 67,73 ----
X =20
X #include <sys/param.h>
X #include <sys/proc.h>
X+ #include <sys/jail.h>
X #include <sys/malloc.h>
X #include <sys/mbuf.h>
X #include <sys/protosw.h>
X***************
X*** 166,171 ****
X--- 167,174 ----
X error =3D EISCONN;
X goto release;
X }
X+ if (td && jailed(td->td_ucred))
X+ prison_remote_ip6(td->td_ucred, &sin6->sin6_addr);=20
X =20
X /* protect *sin6 from overwrites */
X tmp =3D *sin6;
XIndex: sys/netinet6/udp6_usrreq.c
X=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
XRCS file: /usr/freebsd.cvs/src/sys/netinet6/udp6_usrreq.c,v
Xretrieving revision 1.51
Xdiff -c -r1.51 udp6_usrreq.c
X*** sys/netinet6/udp6_usrreq.c 6 Aug 2004 03:45:45 -0000 1.51
X--- sys/netinet6/udp6_usrreq.c 24 Nov 2004 23:41:10 -0000
X***************
X*** 67,72 ****
X--- 67,73 ----
X =20
X #include <sys/param.h>
X #include <sys/errno.h>
X+ #include <sys/jail.h>
X #include <sys/kernel.h>
X #include <sys/lock.h>
X #include <sys/mbuf.h>
X***************
X*** 604,609 ****
X--- 605,611 ----
X {
X struct inpcb *inp;
X int s, error;
X+ struct sockaddr_in6 *sin6_p;
X =20
X INP_INFO_WLOCK(&udbinfo);
X inp =3D sotoinpcb(so);
X***************
X*** 614,621 ****
X INP_LOCK(inp);
X =20
X if ((inp->inp_flags & IN6P_IPV6_V6ONLY) =3D=3D 0) {
X- struct sockaddr_in6 *sin6_p;
X-=20
X sin6_p =3D (struct sockaddr_in6 *)nam;
X if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
X struct sockaddr_in sin;
X--- 616,621 ----
X***************
X*** 640,645 ****
X--- 640,649 ----
X goto out;
X }
X s =3D splnet();
X+ sin6_p =3D (struct sockaddr_in6 *)nam;
X+ if (td && jailed(td->td_ucred))
X+ prison_remote_ip6(td->td_ucred, &sin6_p->sin6_addr);=20
X+=20
X error =3D in6_pcbconnect(inp, nam, td->td_ucred);
X splx(s);
X if (error =3D=3D 0) {
XIndex: sys/nfsclient/nfs_vfsops.c
X=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
XRCS file: /usr/freebsd.cvs/src/sys/nfsclient/nfs_vfsops.c,v
Xretrieving revision 1.158
Xdiff -c -r1.158 nfs_vfsops.c
X*** sys/nfsclient/nfs_vfsops.c 30 Jul 2004 22:08:52 -0000 1.158
X--- sys/nfsclient/nfs_vfsops.c 24 Nov 2004 23:41:10 -0000
X***************
X*** 507,512 ****
X--- 507,513 ----
X mp->mnt_kern_flag =3D 0;
X mp->mnt_flag =3D mountflag;
X nam =3D sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
X+ args->flags|=3DNFSMNT_NOLOCKD;
X if ((error =3D mountnfs(args, mp, nam, which, path, vpp,
X td->td_ucred)) !=3D 0) {
X printf("nfs_mountroot: mount %s on %s: %d", path, which,
error);
XIndex: sys/sys/jail.h
X=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
XRCS file: /usr/freebsd.cvs/src/sys/sys/jail.h,v
Xretrieving revision 1.21
Xdiff -c -r1.21 jail.h
X*** sys/sys/jail.h 26 Apr 2004 19:46:52 -0000 1.21
X--- sys/sys/jail.h 24 Nov 2004 23:41:10 -0000
X***************
X*** 6,23 ****
X * this stuff is worth it, you can buy me a beer in return.
Poul-Henning Kamp
X *
-------------------------------------------------------------------------=
---
X *
X! * $FreeBSD$
X *
X */
X =20
X #ifndef _SYS_JAIL_H_
X #define _SYS_JAIL_H_
X =20
X struct jail {
X! u_int32_t version;
X! char *path;
X! char *hostname;
X! u_int32_t ip_number;
X };
X =20
X struct xprison {
X--- 6,64 ----
X * this stuff is worth it, you can buy me a beer in return.
Poul-Henning Kamp
X *
-------------------------------------------------------------------------=
---
X *
X! * $FreeBSD: src/sys/sys/jail.h,v 1.18 2003/04/09 02:55:18 mike Exp $
X *
X */
X =20
X #ifndef _SYS_JAIL_H_
X #define _SYS_JAIL_H_
X =20
X+ #include <netinet/in.h>
X+=20
X+ /*
X+ * to safe a system call i reuse the jail systemcall to=20
X+ * to modify a jail. I will enable the ability to add
X+ * and remove ip4/6 numbers to a jail.
X+ * To get rid of it i playing around with version and=20
X+ * function numbers.
X+ * A jail id is only create on setup path and hostname
X+ * these values are inmutable. The function number is
X+ * CREATEJAIL
X+ */
X struct jail {
X! u_int32_t version;
X! union {
X! struct v1_s {
X! char *path;
X! char *hostname;
X! u_int32_t ip_number;
X! } v1;
X! struct v2_s {
X! u_int32_t function;
X! #define CREATEJAIL 1
X! #define ADDIP4 2
X! #define DELIP4 3
X! #define ADDIP6 4
X! #define DELIP6 5
X! union
X! {
X! struct=20
X! {
X! char *path;
X! char *hostname;
X! } createjail;
X! struct=20
X! {
X! int id;
X! union=20
X! {
X! struct in_addr ip4_num;
X! struct in6_addr ip6_num;
X! } v4_6;
X! } add_del;
X! } u;
X! } v2;
X! } u;
X };
X =20
X struct xprison {
X***************
X*** 25,33 ****
X int pr_id;
X char pr_path[MAXPATHLEN];
X char pr_host[MAXHOSTNAMELEN];
X! u_int32_t pr_ip;
X };
X! #define XPRISON_VERSION 1
X =20
X #ifndef _KERNEL
X =20
X--- 66,77 ----
X int pr_id;
X char pr_path[MAXPATHLEN];
X char pr_host[MAXHOSTNAMELEN];
X! int pr4_id;
X! struct in_addr pr4_num; /* null is empty */
X! int pr6_id;
X! struct in6_addr pr6_num; /* null is empty */
X };
X! #define XPRISON_VERSION 6
X =20
X #ifndef _KERNEL
X =20
X***************
X*** 37,45 ****
X #else /* _KERNEL */
X =20
X #include <sys/queue.h>
X #include <sys/_lock.h>
X #include <sys/_mutex.h>
X- #include <sys/_task.h>
X =20
X #define JAIL_MAX 999999
X =20
X--- 81,89 ----
X #else /* _KERNEL */
X =20
X #include <sys/queue.h>
X+ #include <sys/_task.h>
X #include <sys/_lock.h>
X #include <sys/_mutex.h>
X =20
X #define JAIL_MAX 999999
X =20
X***************
X*** 55,64 ****
X * Lock key:
X * (a) allprison_mutex
X * (p) locked by pr_mutex
X * (c) set only during creation before the structure is shared, no
mutex
X * required to read
X- * (d) set only during destruction of jail, no mutex needed
X */
X struct prison {
X LIST_ENTRY(prison) pr_list; /* (a) all prisons
*/
X int pr_id; /* (c) prison id */
X--- 99,110 ----
X * Lock key:
X * (a) allprison_mutex
X * (p) locked by pr_mutex
X+ * (d) set only during destruction of jail, no mutex needed
X * (c) set only during creation before the structure is shared, no
mutex
X * required to read
X */
X+=20
X+ struct mtx;
X struct prison {
X LIST_ENTRY(prison) pr_list; /* (a) all prisons
*/
X int pr_id; /* (c) prison id */
X***************
X*** 66,75 ****
X char pr_path[MAXPATHLEN]; /* (c) chroot path
*/
X struct vnode *pr_root; /* (c) vnode to rdir
*/
X char pr_host[MAXHOSTNAMELEN]; /* (p) jail hostname
*/
X! u_int32_t pr_ip; /* (c) ip addr host
*/
X void *pr_linux; /* (p) linux abi */
X int pr_securelevel; /* (p) securelevel
*/
X- struct task pr_task; /* (d) destroy task
*/
X struct mtx pr_mtx;
X };
X =20
X--- 112,124 ----
X char pr_path[MAXPATHLEN]; /* (c) chroot path
*/
X struct vnode *pr_root; /* (c) vnode to rdir
*/
X char pr_host[MAXHOSTNAMELEN]; /* (p) jail hostname
*/
X! int pr_ip4s; /* (p) ipv4 addr
count */
X! struct in_addr *pr_ip4; /* (p) ipv4 addr
host */
X! int pr_ip6s; /* (p) ipv6 addr
count */
X! struct in6_addr *pr_ip6; /* (p) ipv6 addr
host */
X! struct task pr_task; /* (d) =
destroy
task */
X void *pr_linux; /* (p) linux abi */
X int pr_securelevel; /* (p) securelevel
*/
X struct mtx pr_mtx;
X };
X =20
X***************
X*** 78,88 ****
X *
X * XXX MIB entries will need to be protected by a mutex.
X */
X extern int jail_set_hostname_allowed;
X extern int jail_socket_unixiproute_only;
X extern int jail_sysvipc_allowed;
X- extern int jail_getfsstat_jailrootonly;
X- extern int jail_allow_raw_sockets;
X =20
X LIST_HEAD(prisonlist, prison);
X extern struct prisonlist allprison;
X--- 127,137 ----
X *
X * XXX MIB entries will need to be protected by a mutex.
X */
X+ extern int jail_getfsstat_jailrootonly;
X+ extern int jail_allow_raw_sockets;
X extern int jail_set_hostname_allowed;
X extern int jail_socket_unixiproute_only;
X extern int jail_sysvipc_allowed;
X =20
X LIST_HEAD(prisonlist, prison);
X extern struct prisonlist allprison;
X***************
X*** 91,108 ****
X * Kernel support functions for jail().
X */
X struct ucred;
X- struct mount;
X struct sockaddr;
X int jailed(struct ucred *cred);
X void getcredhostname(struct ucred *cred, char *, size_t);
X- int prison_check(struct ucred *cred1, struct ucred *cred2);
X int prison_check_mount(struct ucred *cred, struct mount *mp);
X void prison_free(struct prison *pr);
X! u_int32_t prison_getip(struct ucred *cred);
X void prison_hold(struct prison *pr);
X int prison_if(struct ucred *cred, struct sockaddr *sa);
X! int prison_ip(struct ucred *cred, int flag, u_int32_t *ip);
X! void prison_remote_ip(struct ucred *cred, int flags, u_int32_t *ip);
X =20
X #endif /* !_KERNEL */
X #endif /* !_SYS_JAIL_H_ */
X--- 140,163 ----
X * Kernel support functions for jail().
X */
X struct ucred;
X struct sockaddr;
X+ struct mount;
X int jailed(struct ucred *cred);
X void getcredhostname(struct ucred *cred, char *, size_t);
X int prison_check_mount(struct ucred *cred, struct mount *mp);
X+ int prison_check(struct ucred *cred1, struct ucred *cred2);
X void prison_free(struct prison *pr);
X! int prison_first_ip6(struct ucred *cred, struct in6_addr *out);=20
X! int prison_first_ip4(struct ucred *cred, struct in_addr *out);=20
X! int prison_match_ip4(struct ucred *cred, struct in_addr *in);=20
X! int prison_match_ip6(struct ucred *cred, struct in6_addr *in);=20
X void prison_hold(struct prison *pr);
X int prison_if(struct ucred *cred, struct sockaddr *sa);
X! int prison_redirect_ip4(struct ucred *cred, struct in_addr *ip);
X! int prison_redirect_ip6(struct ucred *cred, struct in6_addr *ip);
X! void prison_remote_ip4(struct ucred *cred, struct in_addr *ip);
X! void prison_remote_ip6(struct ucred *cred, struct in6_addr *ip);
X!=20
X =20
X #endif /* !_KERNEL */
X #endif /* !_SYS_JAIL_H_ */
END-of-ipv6.jail.patch
exit
More information about the freebsd-bugs
mailing list