kern/69064: No multiple ip4/6's could assigned to a jail.
Meno Abels
abels at adviser.com
Sat Jul 31 01:01:17 PDT 2004
The following reply was made to PR kern/69064; it has been noted by GNATS.
From: "Meno Abels" <abels at adviser.com>
To: FreeBSD-gnats-submit at freebsd.org
Cc: Max Laier <max at love2party.net>
Subject: Re: kern/69064: No multiple ip4/6's could assigned to a jail.
Date: Sat, 31 Jul 2004 09:54:15 +0200
I chosen the wrong patch format so here it again as a unified diff.
It is a little diffrent to the last patch in fact i resolved some clashes with
other changes to -CURRENT
Meno
Index: sys/kern/kern_jail.c
===================================================================
RCS file: /usr/freebsd.cvs/src/sys/kern/kern_jail.c,v
retrieving revision 1.44
diff -u -r1.44 kern_jail.c
--- sys/kern/kern_jail.c 27 Jun 2004 09:03:21 -0000 1.44
+++ sys/kern/kern_jail.c 14 Jul 2004 19:12:39 -0000
@@ -33,8 +33,11 @@
#include <sys/vnode.h>
#include <net/if.h>
#include <netinet/in.h>
+#include <netinet6/in6_var.h>
MALLOC_DEFINE(M_PRISON, "prison", "Prison structures");
+MALLOC_DEFINE(M_PRISON_IP4, "prison", "Prison ipv4 addresses");
+MALLOC_DEFINE(M_PRISON_IP6, "prison", "Prison ipv6 addresses");
SYSCTL_DECL(_security);
SYSCTL_NODE(_security, OID_AUTO, jail, CTLFLAG_RW, 0,
@@ -75,6 +78,11 @@
static void init_prison(void *);
static void prison_complete(void *context, int pending);
+static int prison_add_ip4(struct in_addr *tmpv4, struct prison *pr, void *pr_new, void **pr_old);
+static int prison_add_ip6(struct in6_addr *tmpv4, struct prison *pr, void *pr_new, void **pr_old);
+static int prison_del_ip4(struct in_addr *tmpv4, struct prison *pr, void *pr_new, void **pr_old);
+static int prison_del_ip6(struct in6_addr *tmpv4, struct prison *pr, void *pr_new, void **pr_old);
+static int prison_check_duplicate(char *hostname, char *path);
static struct prison *prison_find(int);
static int sysctl_jail_list(SYSCTL_HANDLER_ARGS);
@@ -95,45 +103,179 @@
* struct jail *jail;
* };
*/
-int
-jail(struct thread *td, struct jail_args *uap)
+static int
+jail_createjail(struct thread *td, char *user_hostname, char *user_path, struct prison **pr)
{
+ int error;
struct nameidata nd;
- struct prison *pr, *tpr;
- struct jail j;
- struct jail_attach_args jaa;
- int error, tryprid;
- error = copyin(uap->jail, &j, sizeof(j));
+ MALLOC(*pr, struct prison *, sizeof(**pr), M_PRISON, M_WAITOK | M_ZERO);
+ mtx_init(&(*pr)->pr_mtx, "jail mutex", NULL, MTX_DEF);
+ (*pr)->pr_ref = 1;
+ error = copyinstr(user_path, &(*pr)->pr_path, sizeof((*pr)->pr_path), 0);
if (error)
- return (error);
- if (j.version != 0)
- return (EINVAL);
-
- MALLOC(pr, struct prison *, sizeof(*pr), M_PRISON, M_WAITOK | M_ZERO);
- mtx_init(&pr->pr_mtx, "jail mutex", NULL, MTX_DEF);
- pr->pr_ref = 1;
- error = copyinstr(j.path, &pr->pr_path, sizeof(pr->pr_path), 0);
+ goto e_killmtx;
+ error = copyinstr(user_hostname, &(*pr)->pr_host, sizeof((*pr)->pr_host), 0);
if (error)
goto e_killmtx;
+ if (prison_check_duplicate((*pr)->pr_host, (*pr)->pr_path)) {
+ error = EAGAIN;
+ goto e_killmtx;
+ }
+
mtx_lock(&Giant);
- NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, pr->pr_path, td);
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, (*pr)->pr_path, td);
error = namei(&nd);
if (error) {
mtx_unlock(&Giant);
goto e_killmtx;
}
- pr->pr_root = nd.ni_vp;
+ (*pr)->pr_root = nd.ni_vp;
VOP_UNLOCK(nd.ni_vp, 0, td);
NDFREE(&nd, NDF_ONLY_PNBUF);
mtx_unlock(&Giant);
- error = copyinstr(j.hostname, &pr->pr_host, sizeof(pr->pr_host), 0);
- if (error)
- goto e_dropvnref;
- pr->pr_ip = j.ip_number;
- pr->pr_linux = NULL;
- pr->pr_securelevel = securelevel;
+ (*pr)->pr_linux = NULL;
+ (*pr)->pr_securelevel = securelevel;
+ return (0);
+
+e_killmtx:
+ mtx_destroy(&(*pr)->pr_mtx);
+ FREE(*pr, M_PRISON);
+ return (error);
+
+}
+
+
+static void
+jail_dropvnref(struct prison *pr)
+{
+ mtx_lock(&Giant);
+ vrele(pr->pr_root);
+ mtx_unlock(&Giant);
+}
+
+int
+jail(struct thread *td, struct jail_args *uap)
+{
+ struct prison *pr, *tpr;
+ struct jail j;
+ struct jail_attach_args jaa;
+ int error, tryprid;
+ void *pr_new = 0;
+ void *pr_old = 0;
+
+ error = copyin(uap->jail, &j, sizeof(j));
+ if (error)
+ return (error);
+ if (j.version < XPRISON_VERSION)
+ {
+ struct in_addr tmpv4;
+
+ error = jail_createjail(td, j.u.v1.hostname, j.u.v1.path, &pr);
+ if (error) {
+ return error;
+ }
+ MALLOC(pr_new, void *, sizeof(struct in_addr)*1, M_PRISON_IP4, M_WAITOK | M_ZERO);
+ tmpv4.s_addr = htonl(j.u.v1.ip_number);
+ mtx_lock(&pr->pr_mtx);
+ error = prison_add_ip4(&tmpv4, pr, pr_new, &pr_old);
+ mtx_unlock(&pr->pr_mtx);
+ if (error) {
+ jail_dropvnref(pr);
+ }
+ }
+ else
+ {
+ if (j.u.v2.function == CREATEJAIL) {
+ error = jail_createjail(td, j.u.v2.u.createjail.hostname, j.u.v2.u.createjail.path, &pr);
+ if (error) {
+ return error;
+ }
+ }
+ else {
+ int cnt = 0;
+ struct malloc_type *alloc_type;
+retry_alloc:
+ mtx_lock(&allprison_mtx);
+ pr = prison_find(j.u.v2.u.add_del.id);
+ if (pr) {
+ cnt = (j.u.v2.function == ADDIP4 || j.u.v2.function == DELIP4) ?
+ pr->pr_ip4s : pr->pr_ip6s;
+ }
+ mtx_unlock(&pr->pr_mtx);
+ mtx_unlock(&allprison_mtx);
+ if (pr == NULL) {
+ return (EINVAL);
+ }
+ if (j.u.v2.function == ADDIP4 || j.u.v2.function == DELIP4) {
+ alloc_type=M_PRISON_IP4;
+ if (pr->pr_ip4s >= (j.u.v2.function == DELIP4 ? 2 : 0)) {
+ MALLOC(pr_new, void *,
+ sizeof(struct in_addr)*(pr->pr_ip4s+
+ (j.u.v2.function == DELIP4 ? -1 : +1)),
+ alloc_type, M_WAITOK | M_ZERO);
+ /*printf("pr_ip4s:%d\n", pr->pr_ip4s);*/
+ }
+ }
+ else {
+ alloc_type=M_PRISON_IP6;
+ if (pr->pr_ip6s >= (j.u.v2.function == DELIP6 ? 2 : 0)) {
+ MALLOC(pr_new, void *,
+ sizeof(struct in6_addr)*(pr->pr_ip6s+
+ (j.u.v2.function == DELIP6 ? -1 : +1)),
+ alloc_type, M_WAITOK | M_ZERO);
+ /*printf("pr_ip4s:%d\n", pr->pr_ip6s);*/
+ }
+ }
+ mtx_lock(&allprison_mtx);
+ pr = prison_find(j.u.v2.u.add_del.id);
+ if (pr)
+ {
+ if (cnt != ((j.u.v2.function == ADDIP4 || j.u.v2.function == DELIP4) ?
+ pr->pr_ip4s : pr->pr_ip6s))
+ {
+ /* should i sleep ? */
+ mtx_unlock(&pr->pr_mtx);
+ mtx_unlock(&allprison_mtx);
+ FREE(pr_new, alloc_type);
+ /*printf("jail retry alloc\n");*/
+ goto retry_alloc;
+ }
+ mtx_unlock(&allprison_mtx);
+ }
+ else
+ {
+ mtx_unlock(&allprison_mtx);
+ return (EINVAL);
+ }
+
+ switch (j.u.v2.function) {
+ case ADDIP4:
+ error = prison_add_ip4(&j.u.v2.u.add_del.v4_6.ip4_num, pr, pr_new, &pr_old);
+ break;
+ case ADDIP6:
+ error = prison_add_ip6(&j.u.v2.u.add_del.v4_6.ip6_num, pr, pr_new, &pr_old);
+ break;
+ case DELIP4:
+ error = prison_del_ip4(&j.u.v2.u.add_del.v4_6.ip4_num, pr, pr_new, &pr_old);
+ break;
+ case DELIP6:
+ error = prison_del_ip6(&j.u.v2.u.add_del.v4_6.ip6_num, pr, pr_new, &pr_old);
+ break;
+ default:
+ mtx_unlock(&pr->pr_mtx);
+ return EINVAL;
+ }
+ mtx_unlock(&pr->pr_mtx);
+ if (pr_old) {
+ /*printf("jail free:%p\n", pr_old);*/
+ FREE(pr_old, alloc_type);
+ }
+ return (error);
+ }
+ }
+ /* REST of Create Code */
/* Determine next pr_id and add prison to allprison list. */
mtx_lock(&allprison_mtx);
tryprid = lastprid + 1;
@@ -146,7 +288,8 @@
if (tryprid == JAIL_MAX) {
mtx_unlock(&allprison_mtx);
error = EAGAIN;
- goto e_dropvnref;
+ jail_dropvnref(pr);
+ return error;
}
goto next;
}
@@ -164,18 +307,13 @@
mtx_unlock(&pr->pr_mtx);
td->td_retval[0] = jaa.jid;
return (0);
+
e_dropprref:
mtx_lock(&allprison_mtx);
LIST_REMOVE(pr, pr_list);
prisoncount--;
mtx_unlock(&allprison_mtx);
-e_dropvnref:
- mtx_lock(&Giant);
- vrele(pr->pr_root);
- mtx_unlock(&Giant);
-e_killmtx:
- mtx_destroy(&pr->pr_mtx);
- FREE(pr, M_PRISON);
+ jail_dropvnref(pr);
return (error);
}
@@ -248,6 +386,32 @@
return (error);
}
+/* return 0 on not duplicate */
+static int
+prison_check_duplicate(char *hostname, char *path)
+{
+ struct prison *pr;
+ mtx_lock(&allprison_mtx);
+ LIST_FOREACH(pr, &allprison, pr_list) {
+ if (!strncmp(hostname, pr->pr_host, sizeof(pr->pr_host))) {
+ mtx_unlock(&allprison_mtx);
+ return 1;
+ }
+ /* this is not perfect remove of trailing / or duplicated //
+ should be done, who knows the kernel method for this-:)
+ */
+/*
+ if (!strncmp(path, pr->pr_path, sizeof(pr->pr_path))) {
+ mtx_unlock(&allprison_mtx);
+ return 1;
+ }
+*/
+ }
+ mtx_unlock(&allprison_mtx);
+ return 0;
+}
+
+
/*
* Returns a locked prison instance, or NULL on failure.
*/
@@ -299,6 +463,10 @@
mtx_unlock(&Giant);
mtx_destroy(&pr->pr_mtx);
+ if (pr->pr_ip4 != NULL)
+ FREE(pr->pr_ip4, M_PRISON_IP4);
+ if (pr->pr_ip6 != NULL)
+ FREE(pr->pr_ip6, M_PRISON_IP6);
if (pr->pr_linux != NULL)
FREE(pr->pr_linux, M_PRISON);
FREE(pr, M_PRISON);
@@ -313,59 +481,130 @@
mtx_unlock(&pr->pr_mtx);
}
-u_int32_t
-prison_getip(struct ucred *cred)
+int
+prison_first_ip4(struct ucred *cred, struct in_addr *out)
{
+ int errno = 0;
+ mtx_lock(&cred->cr_prison->pr_mtx);
+ if (cred->cr_prison->pr_ip4s)
+ *out = cred->cr_prison->pr_ip4[0];
+ else
+ errno = EADDRNOTAVAIL;
+ mtx_unlock(&cred->cr_prison->pr_mtx);
+ return errno;
+}
- return (cred->cr_prison->pr_ip);
+int
+prison_first_ip6(struct ucred *cred, struct in6_addr *out)
+{
+ int errno = 0;
+ mtx_lock(&cred->cr_prison->pr_mtx);
+ if (cred->cr_prison->pr_ip6s)
+ *out = cred->cr_prison->pr_ip6[0];
+ else
+ errno = EADDRNOTAVAIL;
+ mtx_unlock(&cred->cr_prison->pr_mtx);
+ return errno;
}
int
-prison_ip(struct ucred *cred, int flag, u_int32_t *ip)
+prison_match_ip4(struct ucred *cred, struct in_addr *ip)
{
u_int32_t tmp;
if (!jailed(cred))
return (0);
- if (flag)
- tmp = *ip;
- else
- tmp = ntohl(*ip);
- if (tmp == INADDR_ANY) {
- if (flag)
- *ip = cred->cr_prison->pr_ip;
- else
- *ip = htonl(cred->cr_prison->pr_ip);
- return (0);
- }
- if (tmp == INADDR_LOOPBACK) {
- if (flag)
- *ip = cred->cr_prison->pr_ip;
- else
- *ip = htonl(cred->cr_prison->pr_ip);
+
+ for (tmp = 0; tmp < cred->cr_prison->pr_ip4s; ++tmp)
+ {
+ if (cred->cr_prison->pr_ip4[tmp].s_addr == ip->s_addr)
+ {
+ return 0;
+ }
+ }
+ return (1);
+}
+
+int
+prison_redirect_ip4(struct ucred *cred, struct in_addr *ip)
+{
+ if (!jailed(cred))
+ return (0);
+ if (cred->cr_prison->pr_ip4s <= 0)
+ return (0);
+
+ if (ip->s_addr == htonl(INADDR_ANY)) {
+ *ip = cred->cr_prison->pr_ip4[0];
return (0);
}
- if (cred->cr_prison->pr_ip != tmp)
- return (1);
- return (0);
+ if (ip->s_addr == htonl(INADDR_LOOPBACK)) {
+ *ip = cred->cr_prison->pr_ip4[0];
+ return (0);
+ }
+ return prison_match_ip4(cred, ip);
}
-void
-prison_remote_ip(struct ucred *cred, int flag, u_int32_t *ip)
+int
+prison_match_ip6(struct ucred *cred, struct in6_addr *ip)
{
u_int32_t tmp;
if (!jailed(cred))
+ return (0);
+
+ for (tmp = 0; tmp < cred->cr_prison->pr_ip6s; ++tmp)
+ {
+ if (IN6_ARE_ADDR_EQUAL(&(cred->cr_prison->pr_ip6[tmp]), ip))
+ {
+ return 0;
+ }
+ }
+ return (1);
+}
+
+
+int
+prison_redirect_ip6(struct ucred *cred, struct in6_addr *ip)
+{
+ if (!jailed(cred))
+ return (0);
+ if (cred->cr_prison->pr_ip6s <= 0)
+ return (0);
+
+ if (IN6_ARE_ADDR_EQUAL(ip, &in6addr_any)) {
+ *ip = cred->cr_prison->pr_ip6[0];
+ return (0);
+ }
+ if (IN6_IS_ADDR_LOOPBACK(ip)) {
+ *ip = cred->cr_prison->pr_ip6[0];
+ return (0);
+ }
+ return prison_match_ip6(cred, ip);
+}
+
+void
+prison_remote_ip4(struct ucred *cred, struct in_addr *ip)
+{
+ if (!jailed(cred))
return;
- if (flag)
- tmp = *ip;
- else
- tmp = ntohl(*ip);
- if (tmp == INADDR_LOOPBACK) {
- if (flag)
- *ip = cred->cr_prison->pr_ip;
- else
- *ip = htonl(cred->cr_prison->pr_ip);
+ if (cred->cr_prison->pr_ip4s <= 0)
+ return;
+ if (ip->s_addr == INADDR_LOOPBACK) {
+ *ip = cred->cr_prison->pr_ip4[0];
+ return;
+ }
+ return;
+}
+
+void
+prison_remote_ip6(struct ucred *cred, struct in6_addr *ip)
+{
+ if (!jailed(cred))
+ return;
+ if (cred->cr_prison->pr_ip6s <= 0)
+ return;
+ if (IN6_IS_ADDR_LOOPBACK(ip)) {
+ *ip = cred->cr_prison->pr_ip6[0];
return;
}
return;
@@ -374,18 +613,43 @@
int
prison_if(struct ucred *cred, struct sockaddr *sa)
{
- struct sockaddr_in *sai;
- int ok;
+ int ok = 0;
- sai = (struct sockaddr_in *)sa;
- if ((sai->sin_family != AF_INET) && jail_socket_unixiproute_only)
+ if (!(sa->sa_family == AF_INET || sa->sa_family == AF_INET6)
+ && jail_socket_unixiproute_only)
ok = 1;
- else if (sai->sin_family != AF_INET)
- ok = 0;
- else if (cred->cr_prison->pr_ip != ntohl(sai->sin_addr.s_addr))
- ok = 1;
- else
- ok = 0;
+ else
+ {
+ if (sa->sa_family == AF_INET)
+ {
+ int tmp;
+ struct sockaddr_in *sai = (struct sockaddr_in *)sa;
+ ok = 1;
+ for (tmp = 0; tmp < cred->cr_prison->pr_ip4s; ++tmp)
+ {
+ if (cred->cr_prison->pr_ip4[tmp].s_addr == sai->sin_addr.s_addr)
+ {
+ ok = 0;
+ break;
+ }
+ }
+ }
+ else if (sa->sa_family == AF_INET6)
+ {
+ struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa;
+ int tmp;
+ ok = 1;
+ for (tmp = 0; tmp < cred->cr_prison->pr_ip6s; ++tmp)
+ {
+ if (IN6_ARE_ADDR_EQUAL(&(cred->cr_prison->pr_ip6[tmp]),
+ &(sa6->sin6_addr)))
+ {
+ ok = 0;
+ break;
+ }
+ }
+ }
+ }
return (ok);
}
@@ -407,6 +671,138 @@
}
/*
+ * assumes that mtx_lock (pr->mtx) is done
+ */
+static int
+prison_add_ip4(struct in_addr *ip, struct prison *pr, void *vpr_new, void **pr_free)
+{
+ struct in_addr *pr_new = vpr_new;
+ struct in_addr *wrk_new;
+
+ wrk_new = pr_new;
+ if (pr->pr_ip4s > 0)
+ {
+ struct in_addr *pr_old = pr->pr_ip4;
+ for (;pr_old < &(pr->pr_ip4[pr->pr_ip4s]) ; ++pr_old)
+ {
+ if (pr_old->s_addr == ip->s_addr)
+ {
+ *pr_free = pr_new;
+ return 0;
+ }
+ *wrk_new++ = *pr_old;
+ }
+ }
+ *wrk_new = *ip;
+ ++(pr->pr_ip4s);
+ if (pr->pr_ip4)
+ *pr_free = pr->pr_ip4;
+ pr->pr_ip4 = pr_new;
+ return 0;
+}
+
+static int
+prison_add_ip6(struct in6_addr *ip, struct prison *pr, void *vpr_new, void **pr_free)
+{
+ struct in6_addr *pr_new = vpr_new;
+ struct in6_addr *wrk_new;
+
+ wrk_new = pr_new;
+ if (pr->pr_ip6s > 0)
+ {
+ struct in6_addr *pr_old = pr->pr_ip6;
+ for (;pr_old < &(pr->pr_ip6[pr->pr_ip6s]) ; ++pr_old)
+ {
+ if (IN6_ARE_ADDR_EQUAL(pr_old, ip))
+ {
+ *pr_free = pr_new;
+ return 0;
+ }
+ *wrk_new++ = *pr_old;
+ }
+ }
+ *wrk_new = *ip;
+ ++(pr->pr_ip6s);
+ if (pr->pr_ip6)
+ *pr_free = pr->pr_ip6;
+ pr->pr_ip6 = pr_new;
+ return 0;
+}
+
+static int
+prison_del_ip4(struct in_addr *ip, struct prison *pr, void *vpr_new, void **pr_free)
+{
+ struct in_addr *pr_new = vpr_new;
+ struct in_addr *wrk_new;
+ int errno = ENOENT;
+
+ wrk_new = pr_new;
+ if (pr->pr_ip4s > 0)
+ {
+ struct in_addr *pr_old = pr->pr_ip4;
+ for (;pr_old < &(pr->pr_ip4[pr->pr_ip4s]) ; ++pr_old)
+ {
+ if (pr_old->s_addr != ip->s_addr)
+ {
+ if (wrk_new) { /* remove only if one or more elements remaining */
+ *wrk_new++ = *pr_old;
+ }
+ }
+ else
+ {
+ errno = 0; /* found element to delete */
+ }
+ }
+ }
+ if (errno == 0)
+ {
+ --(pr->pr_ip4s);
+ /* attach new array */
+ if (pr->pr_ip4)
+ *pr_free = pr->pr_ip4;
+ pr->pr_ip4 = pr_new;
+ }
+ return errno;
+}
+
+static int
+prison_del_ip6(struct in6_addr *ip, struct prison *pr, void *vpr_new, void **pr_free)
+{
+ struct in6_addr *pr_new = vpr_new;
+ struct in6_addr *wrk_new;
+ int errno = ENOENT;
+
+ wrk_new = pr_new;
+ if (pr->pr_ip6s > 0)
+ {
+ struct in6_addr *pr_old = pr->pr_ip6;
+ for (;pr_old < &(pr->pr_ip6[pr->pr_ip6s]) ; ++pr_old)
+ {
+ if (!IN6_ARE_ADDR_EQUAL(pr_old, ip))
+ {
+ if (wrk_new) { /* remove only if one or more elements remaining */
+ *wrk_new++ = *pr_old;
+ }
+ }
+ else
+ {
+ errno = 0; /* found element to delete */
+ }
+ }
+ }
+ if (errno == 0)
+ {
+ --(pr->pr_ip6s);
+ /* attach new array */
+ if (pr->pr_ip6)
+ *pr_free = pr->pr_ip6;
+ pr->pr_ip6 = pr_new;
+ }
+ return errno;
+}
+
+
+/*
* Return 1 if the passed credential is in a jail, otherwise 0.
*/
int
@@ -452,35 +848,67 @@
struct xprison *xp, *sxp;
struct prison *pr;
int count, error;
+ int prcount;
mtx_assert(&Giant, MA_OWNED);
if (jailed(req->td->td_ucred))
return (0);
retry:
mtx_lock(&allprison_mtx);
- count = prisoncount;
+ count = 0;
+ prcount = 0;
+ LIST_FOREACH(pr, &allprison, pr_list) {
+ ++prcount;
+ if (pr->pr_ip4s || pr->pr_ip6s) {
+ count += max(pr->pr_ip4s, pr->pr_ip6s);
+ }
+ else {
+ ++count;
+ }
+ }
mtx_unlock(&allprison_mtx);
if (count == 0)
return (0);
+ /*printf("jls:count=%d:%d\n", count, prcount);*/
sxp = xp = malloc(sizeof(*xp) * count, M_TEMP, M_WAITOK | M_ZERO);
mtx_lock(&allprison_mtx);
- if (count != prisoncount) {
+ if (prcount != prisoncount) {
mtx_unlock(&allprison_mtx);
free(sxp, M_TEMP);
goto retry;
}
LIST_FOREACH(pr, &allprison, pr_list) {
- mtx_lock(&pr->pr_mtx);
- xp->pr_version = XPRISON_VERSION;
- xp->pr_id = pr->pr_id;
- strlcpy(xp->pr_path, pr->pr_path, sizeof(xp->pr_path));
- strlcpy(xp->pr_host, pr->pr_host, sizeof(xp->pr_host));
- xp->pr_ip = pr->pr_ip;
- mtx_unlock(&pr->pr_mtx);
- xp++;
+ int id = 0;
+ int i;
+ int maxcnt = max(pr->pr_ip4s, pr->pr_ip6s);
+ /*printf("jls:maxcnt=%d\n", maxcnt);*/
+ for (i = 0; i < (maxcnt ? maxcnt : 1) ; ++i)
+ {
+ /*printf("jls:-0-:%d:%d\n", i, maxcnt);*/
+ mtx_lock(&pr->pr_mtx);
+ xp->pr_version = XPRISON_VERSION;
+ xp->pr_id = pr->pr_id;
+ strlcpy(xp->pr_path, pr->pr_path, sizeof(xp->pr_path));
+ strlcpy(xp->pr_host, pr->pr_host, sizeof(xp->pr_host));
+ if (i < pr->pr_ip4s) {
+ xp->pr4_id = id;
+ xp->pr4_num = pr->pr_ip4[i];
+ }
+ else
+ xp->pr4_id = -1;
+ if (i < pr->pr_ip6s) {
+ xp->pr6_id = id;
+ xp->pr6_num = pr->pr_ip6[i];
+ }
+ else
+ xp->pr6_id = -1;
+ ++id;
+ mtx_unlock(&pr->pr_mtx);
+ xp++;
+ }
}
mtx_unlock(&allprison_mtx);
Index: sys/net/rtsock.c
===================================================================
RCS file: /usr/freebsd.cvs/src/sys/net/rtsock.c,v
retrieving revision 1.112
diff -u -r1.112 rtsock.c
--- sys/net/rtsock.c 6 Jul 2004 03:29:41 -0000 1.112
+++ sys/net/rtsock.c 14 Jul 2004 17:52:25 -0000
@@ -322,7 +322,8 @@
int len, error = 0;
struct ifnet *ifp = NULL;
struct ifaddr *ifa = NULL;
- struct sockaddr_in jail;
+ struct sockaddr_in jail4;
+ struct sockaddr_in6 jail6;
#define senderr(e) { error = e; goto flush;}
if (m == NULL || ((m->m_len < sizeof(long)) &&
@@ -437,13 +438,32 @@
info.rti_info[RTAX_IFP] =
ifaddr_byindex(ifp->if_index)->ifa_addr;
if (jailed(so->so_cred)) {
- bzero(&jail, sizeof(jail));
- jail.sin_family = PF_INET;
- jail.sin_len = sizeof(jail);
- jail.sin_addr.s_addr =
- htonl(prison_getip(so->so_cred));
- info.rti_info[RTAX_IFA] =
- (struct sockaddr *)&jail;
+ if (rt->rt_ifa->ifa_addr->sa_family == PF_INET) {
+ bzero(&jail4, sizeof(jail4));
+ jail4.sin_family = PF_INET;
+ jail4.sin_len = sizeof(jail4);
+ error = prison_first_ip4(so->so_cred,
+ &jail4.sin_addr);
+ if (error)
+ senderr(error);
+ info.rti_info[RTAX_IFA] =
+ (struct sockaddr *)&jail4;
+ }
+ else if (rt->rt_ifa->ifa_addr->sa_family == PF_INET6) {
+ bzero(&jail6, sizeof(jail6));
+ jail6.sin6_family = PF_INET6;
+ jail6.sin6_len = sizeof(jail6);
+ error = prison_first_ip6(so->so_cred,
+ &jail6.sin6_addr);
+ if (error)
+ senderr(error);
+ info.rti_info[RTAX_IFA] =
+ (struct sockaddr *)&jail6;
+ }
+ else {
+ info.rti_info[RTAX_IFA] =
+ rt->rt_ifa->ifa_addr;
+ }
} else
info.rti_info[RTAX_IFA] =
rt->rt_ifa->ifa_addr;
Index: sys/netinet/in_pcb.c
===================================================================
RCS file: /usr/freebsd.cvs/src/sys/netinet/in_pcb.c,v
retrieving revision 1.152
diff -u -r1.152 in_pcb.c
--- sys/netinet/in_pcb.c 28 Jul 2004 13:03:07 -0000 1.152
+++ sys/netinet/in_pcb.c 30 Jul 2004 22:46:26 -0000
@@ -290,7 +290,7 @@
return (EAFNOSUPPORT);
#endif
if (sin->sin_addr.s_addr != INADDR_ANY)
- if (prison_ip(cred, 0, &sin->sin_addr.s_addr))
+ if (prison_redirect_ip4(cred, &sin->sin_addr))
return(EINVAL);
if (sin->sin_port != *lportp) {
/* Don't allow the port to change. */
@@ -346,7 +346,7 @@
t->inp_socket->so_cred->cr_uid))
return (EADDRINUSE);
}
- if (prison && prison_ip(cred, 0, &sin->sin_addr.s_addr))
+ if (prison && prison_redirect_ip4(cred, &sin->sin_addr))
return (EADDRNOTAVAIL);
t = in_pcblookup_local(pcbinfo, sin->sin_addr,
lport, prison ? 0 : wild);
@@ -375,7 +375,7 @@
int count;
if (laddr.s_addr != INADDR_ANY)
- if (prison_ip(cred, 0, &laddr.s_addr))
+ if (prison_redirect_ip4(cred, &laddr))
return (EINVAL);
if (inp->inp_flags & INP_HIGHPORT) {
@@ -438,7 +438,7 @@
wild));
}
}
- if (prison_ip(cred, 0, &laddr.s_addr))
+ if (prison_redirect_ip4(cred, &laddr))
return (EINVAL);
*laddrp = laddr.s_addr;
*lportp = lport;
@@ -545,7 +545,9 @@
socred = inp->inp_socket->so_cred;
if (laddr.s_addr == INADDR_ANY && jailed(socred)) {
bzero(&sa, sizeof(sa));
- sa.sin_addr.s_addr = htonl(prison_getip(socred));
+ error = prison_first_ip4(socred, &sa.sin_addr);
+ if (error)
+ return (error);
sa.sin_len = sizeof(sa);
sa.sin_family = AF_INET;
error = in_pcbbind_setup(inp, (struct sockaddr *)&sa,
Index: sys/netinet/raw_ip.c
===================================================================
RCS file: /usr/freebsd.cvs/src/sys/netinet/raw_ip.c,v
retrieving revision 1.137
diff -u -r1.137 raw_ip.c
--- sys/netinet/raw_ip.c 26 Jul 2004 07:24:03 -0000 1.137
+++ sys/netinet/raw_ip.c 30 Jul 2004 22:46:26 -0000
@@ -213,9 +213,9 @@
if (inp->inp_faddr.s_addr &&
inp->inp_faddr.s_addr != ip->ip_src.s_addr)
goto docontinue;
+
if (jailed(inp->inp_socket->so_cred))
- if (htonl(prison_getip(inp->inp_socket->so_cred)) !=
- ip->ip_dst.s_addr)
+ if (prison_match_ip4(inp->inp_socket->so_cred, &(ip->ip_dst)))
goto docontinue;
if (last) {
struct mbuf *n;
@@ -272,8 +272,16 @@
ip->ip_p = inp->inp_ip_p;
ip->ip_len = m->m_pkthdr.len;
if (jailed(inp->inp_socket->so_cred))
- ip->ip_src.s_addr =
- htonl(prison_getip(inp->inp_socket->so_cred));
+ {
+ /* fallback to first ip */
+ if (prison_match_ip4(inp->inp_socket->so_cred, &inp->inp_laddr)) {
+ if ((error = prison_first_ip4(inp->inp_socket->so_cred,
+ &ip->ip_src)) != 0)
+ return error;
+ }
+ else
+ ip->ip_src = inp->inp_laddr;
+ }
else
ip->ip_src = inp->inp_laddr;
ip->ip_dst.s_addr = dst;
@@ -286,8 +294,7 @@
INP_LOCK(inp);
ip = mtod(m, struct ip *);
if (jailed(inp->inp_socket->so_cred)) {
- if (ip->ip_src.s_addr !=
- htonl(prison_getip(inp->inp_socket->so_cred))) {
+ if (prison_match_ip4(inp->inp_socket->so_cred, &ip->ip_src)) {
INP_UNLOCK(inp);
m_freem(m);
return (EPERM);
@@ -658,10 +665,11 @@
return EINVAL;
if (jailed(td->td_ucred)) {
+ int error;
if (addr->sin_addr.s_addr == INADDR_ANY)
- addr->sin_addr.s_addr =
- htonl(prison_getip(td->td_ucred));
- if (htonl(prison_getip(td->td_ucred)) != addr->sin_addr.s_addr)
+ if ((error = prison_first_ip4(td->td_ucred, &addr->sin_addr)) != 0)
+ return error;
+ if (prison_match_ip4(td->td_ucred, &addr->sin_addr))
return (EADDRNOTAVAIL);
}
Index: sys/netinet/tcp_usrreq.c
===================================================================
RCS file: /usr/freebsd.cvs/src/sys/netinet/tcp_usrreq.c,v
retrieving revision 1.105
diff -u -r1.105 tcp_usrreq.c
--- sys/netinet/tcp_usrreq.c 26 Jul 2004 21:29:56 -0000 1.105
+++ sys/netinet/tcp_usrreq.c 30 Jul 2004 22:46:27 -0000
@@ -357,7 +357,7 @@
&& IN_MULTICAST(ntohl(sinp->sin_addr.s_addr)))
return (EAFNOSUPPORT);
if (td && jailed(td->td_ucred))
- prison_remote_ip(td->td_ucred, 0, &sinp->sin_addr.s_addr);
+ prison_remote_ip4(td->td_ucred, &sinp->sin_addr);
COMMON_START();
if ((error = tcp_connect(tp, nam, td)) != 0)
@@ -386,6 +386,9 @@
&& IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr))
return (EAFNOSUPPORT);
+ if (td && jailed(td->td_ucred))
+ prison_remote_ip6(td->td_ucred, &sin6p->sin6_addr);
+
COMMON_START();
if (IN6_IS_ADDR_V4MAPPED(&sin6p->sin6_addr)) {
struct sockaddr_in sin;
Index: sys/netinet/udp_usrreq.c
===================================================================
RCS file: /usr/freebsd.cvs/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.157
diff -u -r1.157 udp_usrreq.c
--- sys/netinet/udp_usrreq.c 26 Jul 2004 07:24:03 -0000 1.157
+++ sys/netinet/udp_usrreq.c 30 Jul 2004 22:46:27 -0000
@@ -806,7 +806,7 @@
if (addr) {
sin = (struct sockaddr_in *)addr;
if (td && jailed(td->td_ucred))
- prison_remote_ip(td->td_ucred, 0, &sin->sin_addr.s_addr);
+ prison_remote_ip4(td->td_ucred, &sin->sin_addr);
if (inp->inp_faddr.s_addr != INADDR_ANY) {
error = EISCONN;
goto release;
@@ -1002,7 +1002,7 @@
s = splnet();
sin = (struct sockaddr_in *)nam;
if (td && jailed(td->td_ucred))
- prison_remote_ip(td->td_ucred, 0, &sin->sin_addr.s_addr);
+ prison_remote_ip4(td->td_ucred, &sin->sin_addr);
error = in_pcbconnect(inp, nam, td->td_ucred);
splx(s);
if (error == 0)
Index: sys/netinet6/in6_pcb.c
===================================================================
RCS file: /usr/freebsd.cvs/src/sys/netinet6/in6_pcb.c,v
retrieving revision 1.57
diff -u -r1.57 in6_pcb.c
--- sys/netinet6/in6_pcb.c 28 Jul 2004 13:03:07 -0000 1.57
+++ sys/netinet6/in6_pcb.c 31 Jul 2004 07:38:54 -0000
@@ -128,6 +128,7 @@
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)NULL;
struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
u_short lport = 0;
+ int prison = 0;
int wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
INP_INFO_WLOCK_ASSERT(pcbinfo);
@@ -149,6 +150,10 @@
if (nam->sa_family != AF_INET6)
return (EAFNOSUPPORT);
+ if (!IN6_ARE_ADDR_EQUAL(&in6addr_any, &sin6->sin6_addr))
+ if (prison_redirect_ip6(cred, &sin6->sin6_addr))
+ return (EINVAL);
+
/* KAME hack: embed scopeid */
if (in6_embedscope(&sin6->sin6_addr, sin6, inp, NULL) != 0)
return EINVAL;
@@ -192,12 +197,20 @@
if (ntohs(lport) < IPV6PORT_RESERVED &&
suser_cred(cred, SUSER_ALLOWJAIL))
return (EACCES);
+ prison = jailed(cred);
if (so->so_cred->cr_uid != 0 &&
!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
t = in6_pcblookup_local(pcbinfo,
&sin6->sin6_addr, lport,
- INPLOOKUP_WILDCARD);
- if (t &&
+ prison ? 0 : INPLOOKUP_WILDCARD);
+ if (t && (t->inp_vflag & INP_TIMEWAIT)) {
+ if ((!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
+ !IN6_IS_ADDR_UNSPECIFIED(&t->in6p_laddr) ||
+ !(intotw(t)->tw_so_options & SO_REUSEPORT))
+ && so->so_cred->cr_uid !=
+ intotw(t)->tw_cred->cr_uid)
+ return (EADDRINUSE);
+ } else if (t &&
((t->inp_vflag & INP_TIMEWAIT) == 0) &&
(so->so_type != SOCK_STREAM ||
IN6_IS_ADDR_UNSPECIFIED(&t->in6p_faddr)) &&
@@ -226,8 +239,10 @@
return (EADDRINUSE);
}
}
+ if (prison && prison_redirect_ip6(cred, &sin6->sin6_addr))
+ return (EADDRNOTAVAIL);
t = in6_pcblookup_local(pcbinfo, &sin6->sin6_addr,
- lport, wild);
+ lport, prison ? 0 : wild);
if (t && (reuseport & ((t->inp_vflag & INP_TIMEWAIT) ?
intotw(t)->tw_so_options :
t->inp_socket->so_options)) == 0)
Index: sys/netinet6/raw_ip6.c
===================================================================
RCS file: /usr/freebsd.cvs/src/sys/netinet6/raw_ip6.c,v
retrieving revision 1.43
diff -u -r1.43 raw_ip6.c
--- sys/netinet6/raw_ip6.c 27 Jul 2004 23:45:19 -0000 1.43
+++ sys/netinet6/raw_ip6.c 31 Jul 2004 07:41:50 -0000
@@ -68,6 +68,7 @@
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
+#include <sys/jail.h>
#include <sys/proc.h>
#include <sys/protosw.h>
#include <sys/signalvar.h>
@@ -174,6 +175,11 @@
goto docontinue;
}
}
+
+ if (jailed(in6p->in6p_socket->so_cred))
+ if (prison_match_ip6(in6p->in6p_socket->so_cred, &(ip6->ip6_dst)))
+ continue;
+
if (last) {
struct mbuf *n = m_copy(m, 0, (int)M_COPYALL);
@@ -428,7 +434,20 @@
error = EADDRNOTAVAIL;
goto bad;
}
- ip6->ip6_src = *in6a;
+ if (jailed(in6p->in6p_socket->so_cred))
+ {
+ /* fallback to first ip */
+ if (prison_match_ip6(in6p->in6p_socket->so_cred, in6a)) {
+ if ((error = prison_first_ip6(in6p->in6p_socket->so_cred,
+ &ip6->ip6_src)) != 0)
+ return error;
+ }
+ else
+ ip6->ip6_src = *in6a;
+ }
+ else
+ ip6->ip6_src = *in6a;
+
ip6->ip6_flow = (ip6->ip6_flow & ~IPV6_FLOWINFO_MASK) |
(in6p->in6p_flowinfo & IPV6_FLOWINFO_MASK);
ip6->ip6_vfc = (ip6->ip6_vfc & ~IPV6_VERSION_MASK) |
@@ -573,6 +592,10 @@
INP_INFO_WUNLOCK(&ripcbinfo);
return error;
}
+ if (td && jailed(td->td_ucred) && !jail_allow_raw_sockets) {
+ return (EPERM);
+ }
+
error = soreserve(so, rip_sendspace, rip_recvspace);
if (error) {
INP_INFO_WUNLOCK(&ripcbinfo);
@@ -650,6 +673,16 @@
if (nam->sa_len != sizeof(*addr))
return EINVAL;
+
+ if (jailed(td->td_ucred)) {
+ if (IN6_ARE_ADDR_EQUAL(&(addr->sin6_addr), &in6addr_any)) {
+ int error;
+ if ((error = prison_first_ip6(td->td_ucred, &addr->sin6_addr)) != 0)
+ return error;
+ }
+ if (prison_match_ip6(td->td_ucred, &addr->sin6_addr))
+ return (EADDRNOTAVAIL);
+ }
if (TAILQ_EMPTY(&ifnet) || addr->sin6_family != AF_INET6)
return EADDRNOTAVAIL;
#ifdef ENABLE_DEFAULT_SCOPE
Index: sys/netinet6/udp6_output.c
===================================================================
RCS file: /usr/freebsd.cvs/src/sys/netinet6/udp6_output.c,v
retrieving revision 1.18
diff -u -r1.18 udp6_output.c
--- sys/netinet6/udp6_output.c 7 Apr 2004 20:46:16 -0000 1.18
+++ sys/netinet6/udp6_output.c 14 Jul 2004 18:48:13 -0000
@@ -67,6 +67,7 @@
#include <sys/param.h>
#include <sys/proc.h>
+#include <sys/jail.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
@@ -166,6 +167,8 @@
error = EISCONN;
goto release;
}
+ if (td && jailed(td->td_ucred))
+ prison_remote_ip6(td->td_ucred, &sin6->sin6_addr);
/* protect *sin6 from overwrites */
tmp = *sin6;
Index: sys/netinet6/udp6_usrreq.c
===================================================================
RCS file: /usr/freebsd.cvs/src/sys/netinet6/udp6_usrreq.c,v
retrieving revision 1.50
diff -u -r1.50 udp6_usrreq.c
--- sys/netinet6/udp6_usrreq.c 27 Jul 2004 23:45:19 -0000 1.50
+++ sys/netinet6/udp6_usrreq.c 30 Jul 2004 22:46:27 -0000
@@ -67,6 +67,7 @@
#include <sys/param.h>
#include <sys/errno.h>
+#include <sys/jail.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mbuf.h>
@@ -604,6 +605,7 @@
{
struct inpcb *inp;
int s, error;
+ struct sockaddr_in6 *sin6_p;
INP_INFO_WLOCK(&udbinfo);
inp = sotoinpcb(so);
@@ -614,8 +616,6 @@
INP_LOCK(inp);
if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
- struct sockaddr_in6 *sin6_p;
-
sin6_p = (struct sockaddr_in6 *)nam;
if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
struct sockaddr_in sin;
@@ -640,6 +640,10 @@
goto out;
}
s = splnet();
+ sin6_p = (struct sockaddr_in6 *)nam;
+ if (td && jailed(td->td_ucred))
+ prison_remote_ip6(td->td_ucred, &sin6_p->sin6_addr);
+
error = in6_pcbconnect(inp, nam, td->td_ucred);
splx(s);
if (error == 0) {
Index: sys/nfsclient/nfs_vfsops.c
===================================================================
RCS file: /usr/freebsd.cvs/src/sys/nfsclient/nfs_vfsops.c,v
retrieving revision 1.157
diff -u -r1.157 nfs_vfsops.c
--- sys/nfsclient/nfs_vfsops.c 28 Jul 2004 20:21:04 -0000 1.157
+++ sys/nfsclient/nfs_vfsops.c 30 Jul 2004 22:46:29 -0000
@@ -507,6 +507,7 @@
mp->mnt_kern_flag = 0;
mp->mnt_flag = mountflag;
nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
+ args->flags|=NFSMNT_NOLOCKD;
if ((error = mountnfs(args, mp, nam, which, path, vpp,
td->td_ucred)) != 0) {
printf("nfs_mountroot: mount %s on %s: %d", path, which, error);
Index: sys/sys/jail.h
===================================================================
RCS file: /usr/freebsd.cvs/src/sys/sys/jail.h,v
retrieving revision 1.21
diff -u -r1.21 jail.h
--- sys/sys/jail.h 26 Apr 2004 19:46:52 -0000 1.21
+++ sys/sys/jail.h 14 Jul 2004 18:36:05 -0000
@@ -6,18 +6,59 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $FreeBSD$
+ * $FreeBSD: src/sys/sys/jail.h,v 1.18 2003/04/09 02:55:18 mike Exp $
*
*/
#ifndef _SYS_JAIL_H_
#define _SYS_JAIL_H_
+#include <netinet/in.h>
+
+/*
+ * to safe a system call i reuse the jail systemcall to
+ * to modify a jail. I will enable the ability to add
+ * and remove ip4/6 numbers to a jail.
+ * To get rid of it i playing around with version and
+ * function numbers.
+ * A jail id is only create on setup path and hostname
+ * these values are inmutable. The function number is
+ * CREATEJAIL
+ */
struct jail {
- u_int32_t version;
- char *path;
- char *hostname;
- u_int32_t ip_number;
+ u_int32_t version;
+ union {
+ struct v1_s {
+ char *path;
+ char *hostname;
+ u_int32_t ip_number;
+ } v1;
+ struct v2_s {
+ u_int32_t function;
+ #define CREATEJAIL 1
+ #define ADDIP4 2
+ #define DELIP4 3
+ #define ADDIP6 4
+ #define DELIP6 5
+ union
+ {
+ struct
+ {
+ char *path;
+ char *hostname;
+ } createjail;
+ struct
+ {
+ int id;
+ union
+ {
+ struct in_addr ip4_num;
+ struct in6_addr ip6_num;
+ } v4_6;
+ } add_del;
+ } u;
+ } v2;
+ } u;
};
struct xprison {
@@ -25,9 +66,12 @@
int pr_id;
char pr_path[MAXPATHLEN];
char pr_host[MAXHOSTNAMELEN];
- u_int32_t pr_ip;
+ int pr4_id;
+ struct in_addr pr4_num; /* null is empty */
+ int pr6_id;
+ struct in6_addr pr6_num; /* null is empty */
};
-#define XPRISON_VERSION 1
+#define XPRISON_VERSION 6
#ifndef _KERNEL
@@ -37,9 +81,9 @@
#else /* _KERNEL */
#include <sys/queue.h>
+#include <sys/_task.h>
#include <sys/_lock.h>
#include <sys/_mutex.h>
-#include <sys/_task.h>
#define JAIL_MAX 999999
@@ -55,10 +99,12 @@
* Lock key:
* (a) allprison_mutex
* (p) locked by pr_mutex
+ * (d) set only during destruction of jail, no mutex needed
* (c) set only during creation before the structure is shared, no mutex
* required to read
- * (d) set only during destruction of jail, no mutex needed
*/
+
+struct mtx;
struct prison {
LIST_ENTRY(prison) pr_list; /* (a) all prisons */
int pr_id; /* (c) prison id */
@@ -66,10 +112,13 @@
char pr_path[MAXPATHLEN]; /* (c) chroot path */
struct vnode *pr_root; /* (c) vnode to rdir */
char pr_host[MAXHOSTNAMELEN]; /* (p) jail hostname */
- u_int32_t pr_ip; /* (c) ip addr host */
+ int pr_ip4s; /* (p) ipv4 addr count */
+ struct in_addr *pr_ip4; /* (p) ipv4 addr host */
+ int pr_ip6s; /* (p) ipv6 addr count */
+ struct in6_addr *pr_ip6; /* (p) ipv6 addr host */
+ struct task pr_task; /* (d) destroy task */
void *pr_linux; /* (p) linux abi */
int pr_securelevel; /* (p) securelevel */
- struct task pr_task; /* (d) destroy task */
struct mtx pr_mtx;
};
@@ -78,11 +127,11 @@
*
* XXX MIB entries will need to be protected by a mutex.
*/
+extern int jail_getfsstat_jailrootonly;
+extern int jail_allow_raw_sockets;
extern int jail_set_hostname_allowed;
extern int jail_socket_unixiproute_only;
extern int jail_sysvipc_allowed;
-extern int jail_getfsstat_jailrootonly;
-extern int jail_allow_raw_sockets;
LIST_HEAD(prisonlist, prison);
extern struct prisonlist allprison;
@@ -91,18 +140,24 @@
* Kernel support functions for jail().
*/
struct ucred;
-struct mount;
struct sockaddr;
+struct mount;
int jailed(struct ucred *cred);
void getcredhostname(struct ucred *cred, char *, size_t);
-int prison_check(struct ucred *cred1, struct ucred *cred2);
int prison_check_mount(struct ucred *cred, struct mount *mp);
+int prison_check(struct ucred *cred1, struct ucred *cred2);
void prison_free(struct prison *pr);
-u_int32_t prison_getip(struct ucred *cred);
+int prison_first_ip6(struct ucred *cred, struct in6_addr *out);
+int prison_first_ip4(struct ucred *cred, struct in_addr *out);
+int prison_match_ip4(struct ucred *cred, struct in_addr *in);
+int prison_match_ip6(struct ucred *cred, struct in6_addr *in);
void prison_hold(struct prison *pr);
int prison_if(struct ucred *cred, struct sockaddr *sa);
-int prison_ip(struct ucred *cred, int flag, u_int32_t *ip);
-void prison_remote_ip(struct ucred *cred, int flags, u_int32_t *ip);
+int prison_redirect_ip4(struct ucred *cred, struct in_addr *ip);
+int prison_redirect_ip6(struct ucred *cred, struct in6_addr *ip);
+void prison_remote_ip4(struct ucred *cred, struct in_addr *ip);
+void prison_remote_ip6(struct ucred *cred, struct in6_addr *ip);
+
#endif /* !_KERNEL */
#endif /* !_SYS_JAIL_H_ */
More information about the freebsd-bugs
mailing list