summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_jail.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2001-02-21 06:39:57 +0000
committerrwatson <rwatson@FreeBSD.org>2001-02-21 06:39:57 +0000
commitab5676fc870d2d819cf41120313443182db079cf (patch)
tree3ed13007d645ee25bab52d52b6aba08f7f0bcf1e /sys/kern/kern_jail.c
parent17bdecb1829f632354d48f743f10ff707edded9c (diff)
downloadFreeBSD-src-ab5676fc870d2d819cf41120313443182db079cf.zip
FreeBSD-src-ab5676fc870d2d819cf41120313443182db079cf.tar.gz
o Move per-process jail pointer (p->pr_prison) to inside of the subject
credential structure, ucred (cr->cr_prison). o Allow jail inheritence to be a function of credential inheritence. o Abstract prison structure reference counting behind pr_hold() and pr_free(), invoked by the similarly named credential reference management functions, removing this code from per-ABI fork/exit code. o Modify various jail() functions to use struct ucred arguments instead of struct proc arguments. o Introduce jailed() function to determine if a credential is jailed, rather than directly checking pointers all over the place. o Convert PRISON_CHECK() macro to prison_check() function. o Move jail() function prototypes to jail.h. o Emulate the P_JAILED flag in fill_kinfo_proc() and no longer set the flag in the process flags field itself. o Eliminate that "const" qualifier from suser/p_can/etc to reflect mutex use. Notes: o Some further cleanup of the linux/jail code is still required. o It's now possible to consider resolving some of the process vs credential based permission checking confusion in the socket code. o Mutex protection of struct prison is still not present, and is required to protect the reference count plus some fields in the structure. Reviewed by: freebsd-arch Obtained from: TrustedBSD Project
Diffstat (limited to 'sys/kern/kern_jail.c')
-rw-r--r--sys/kern/kern_jail.c85
1 files changed, 67 insertions, 18 deletions
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 97bb2bb..c417667 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -46,16 +46,17 @@ SYSCTL_INT(_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW,
int
jail(p, uap)
- struct proc *p;
- struct jail_args /* {
- syscallarg(struct jail *) jail;
- } */ *uap;
+ struct proc *p;
+ struct jail_args /* {
+ syscallarg(struct jail *) jail;
+ } */ *uap;
{
int error;
struct prison *pr;
struct jail j;
struct chroot_args ca;
+ /* Implicitly fail if already in jail. */
error = suser(p);
if (error)
return (error);
@@ -75,9 +76,9 @@ jail(p, uap)
if (error)
goto bail;
- pr->pr_ref++;
- p->p_prison = pr;
- p->p_flag |= P_JAILED;
+ p->p_ucred = crcopy(p->p_ucred);
+ p->p_ucred->cr_prison = pr;
+ pr->pr_ref = 1;
return (0);
bail:
@@ -85,12 +86,31 @@ bail:
return (error);
}
+void
+prison_free(struct prison *pr)
+{
+
+ pr->pr_ref--;
+ if (pr->pr_ref == 0) {
+ if (pr->pr_linux != NULL)
+ FREE(pr->pr_linux, M_PRISON);
+ FREE(pr, M_PRISON);
+ }
+}
+
+void
+prison_hold(struct prison *pr)
+{
+
+ pr->pr_ref++;
+}
+
int
-prison_ip(struct proc *p, int flag, u_int32_t *ip)
+prison_ip(struct ucred *cred, int flag, u_int32_t *ip)
{
u_int32_t tmp;
- if (!p->p_prison)
+ if (!jailed(cred))
return (0);
if (flag)
tmp = *ip;
@@ -98,22 +118,22 @@ prison_ip(struct proc *p, int flag, u_int32_t *ip)
tmp = ntohl(*ip);
if (tmp == INADDR_ANY) {
if (flag)
- *ip = p->p_prison->pr_ip;
+ *ip = cred->cr_prison->pr_ip;
else
- *ip = htonl(p->p_prison->pr_ip);
+ *ip = htonl(cred->cr_prison->pr_ip);
return (0);
}
- if (p->p_prison->pr_ip != tmp)
+ if (cred->cr_prison->pr_ip != tmp)
return (1);
return (0);
}
void
-prison_remote_ip(struct proc *p, int flag, u_int32_t *ip)
+prison_remote_ip(struct ucred *cred, int flag, u_int32_t *ip)
{
u_int32_t tmp;
- if (!p || !p->p_prison)
+ if (!jailed(cred))
return;
if (flag)
tmp = *ip;
@@ -121,16 +141,16 @@ prison_remote_ip(struct proc *p, int flag, u_int32_t *ip)
tmp = ntohl(*ip);
if (tmp == 0x7f000001) {
if (flag)
- *ip = p->p_prison->pr_ip;
+ *ip = cred->cr_prison->pr_ip;
else
- *ip = htonl(p->p_prison->pr_ip);
+ *ip = htonl(cred->cr_prison->pr_ip);
return;
}
return;
}
int
-prison_if(struct proc *p, struct sockaddr *sa)
+prison_if(struct ucred *cred, struct sockaddr *sa)
{
struct sockaddr_in *sai = (struct sockaddr_in*) sa;
int ok;
@@ -139,9 +159,38 @@ prison_if(struct proc *p, struct sockaddr *sa)
ok = 1;
else if (sai->sin_family != AF_INET)
ok = 0;
- else if (p->p_prison->pr_ip != ntohl(sai->sin_addr.s_addr))
+ else if (cred->cr_prison->pr_ip != ntohl(sai->sin_addr.s_addr))
ok = 1;
else
ok = 0;
return (ok);
}
+
+/*
+ * Return 0 if jails permit p1 to frob p2, otherwise ESRCH.
+ */
+int
+prison_check(cred1, cred2)
+ struct ucred *cred1, *cred2;
+{
+
+ if (jailed(cred1)) {
+ if (!jailed(cred2))
+ return (ESRCH);
+ if (cred2->cr_prison != cred1->cr_prison)
+ return (ESRCH);
+ }
+
+ return (0);
+}
+
+/*
+ * Return 1 if the passed credential is in a jail, otherwise 0.
+ */
+int
+jailed(cred)
+ struct ucred *cred;
+{
+
+ return (cred->cr_prison != NULL);
+}
OpenPOWER on IntegriCloud