diff options
author | rwatson <rwatson@FreeBSD.org> | 2001-02-21 06:39:57 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2001-02-21 06:39:57 +0000 |
commit | ab5676fc870d2d819cf41120313443182db079cf (patch) | |
tree | 3ed13007d645ee25bab52d52b6aba08f7f0bcf1e /sys/kern/kern_jail.c | |
parent | 17bdecb1829f632354d48f743f10ff707edded9c (diff) | |
download | FreeBSD-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.c | 85 |
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); +} |