diff options
author | Robert Watson <rwatson@FreeBSD.org> | 2001-07-05 17:10:46 +0000 |
---|---|---|
committer | Robert Watson <rwatson@FreeBSD.org> | 2001-07-05 17:10:46 +0000 |
commit | a0f75161f939e6bc72757d6a0db657a7b245bbf2 (patch) | |
tree | 12e1eac2ac7b907cb9e647b6cd5c337073cd615c /sys/kern | |
parent | 0b848380bb7ca163535c2003a15cc5b409bb248b (diff) |
o Replace calls to p_can(..., P_CAN_xxx) with calls to p_canxxx().
The p_can(...) construct was a premature (and, it turns out,
awkward) abstraction. The individual calls to p_canxxx() better
reflect differences between the inter-process authorization checks,
such as differing checks based on the type of signal. This has
a side effect of improving code readability.
o Replace direct credential authorization checks in ktrace() with
invocation of p_candebug(), while maintaining the special case
check of KTR_ROOT. This allows ktrace() to "play more nicely"
with new mandatory access control schemes, as well as making its
authorization checks consistent with other "debugging class"
checks.
o Eliminate "privused" construct for p_can*() calls which allowed the
caller to determine if privilege was required for successful
evaluation of the access control check. This primitive is currently
unused, and as such, serves only to complicate the API.
Approved by: ({procfs,linprocfs} changes) des
Obtained from: TrustedBSD Project
Notes
Notes:
svn path=/head/; revision=79335
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_event.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_ktrace.c | 22 | ||||
-rw-r--r-- | sys/kern/kern_proc.c | 8 | ||||
-rw-r--r-- | sys/kern/kern_prot.c | 63 | ||||
-rw-r--r-- | sys/kern/kern_resource.c | 18 | ||||
-rw-r--r-- | sys/kern/p1003_1b.c | 10 | ||||
-rw-r--r-- | sys/kern/sys_process.c | 4 |
7 files changed, 39 insertions, 88 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index d4d588ede0c0..4f8b61bcda5e 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -172,7 +172,7 @@ filt_procattach(struct knote *kn) p = pfind(kn->kn_id); if (p == NULL) return (ESRCH); - if ((error = p_can(curproc, p, P_CAN_SEE, NULL))) { + if ((error = p_cansee(curproc, p))) { PROC_UNLOCK(p); return (error); } diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index 15b51c8855d9..a37ad226e0a6 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -521,30 +521,20 @@ ktrwrite(vp, kth, uio) * more permissions than the caller. KTRFAC_ROOT signifies that * root previously set the tracing status on the target process, and * so, only root may further change it. - * - * XXX: These checks are stronger than for ptrace() - * XXX: This check should be p_can(... P_CAN_DEBUG ...); - * - * TODO: check groups. use caller effective gid. */ static int ktrcanset(callp, targetp) struct proc *callp, *targetp; { - struct ucred *callcr = callp->p_ucred; - struct ucred *targetcr = targetp->p_ucred; - if (prison_check(callcr, targetcr)) + if (targetp->p_traceflag & KTRFAC_ROOT && + suser_xxx(NULL, callp, PRISON_ROOT)) return (0); - if ((callcr->cr_uid == targetcr->cr_ruid && - targetcr->cr_ruid == targetcr->cr_svuid && - callcr->cr_rgid == targetcr->cr_rgid && /* XXX */ - targetcr->cr_rgid == targetcr->cr_svgid && - (targetp->p_traceflag & KTRFAC_ROOT) == 0) || - !suser_xxx(callcr, NULL, PRISON_ROOT)) - return (1); - return (0); + if (p_candebug(callp, targetp) != 0) + return (0); + + return (1); } #endif /* KTRACE */ diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 883e2fad2f8d..50f3446798a9 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -585,7 +585,7 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS) p = pfind((pid_t)name[0]); if (!p) return (0); - if (p_can(curproc, p, P_CAN_SEE, NULL)) { + if (p_cansee(curproc, p)) { PROC_UNLOCK(p); return (0); } @@ -616,7 +616,7 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS) /* * Show a user only appropriate processes. */ - if (p_can(curproc, p, P_CAN_SEE, NULL)) + if (p_cansee(curproc, p)) continue; /* * Skip embryonic processes. @@ -658,7 +658,7 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS) break; } - if (p_can(curproc, p, P_CAN_SEE, NULL)) + if (p_cansee(curproc, p)) continue; error = sysctl_out_proc(p, req, doingzomb); @@ -694,7 +694,7 @@ sysctl_kern_proc_args(SYSCTL_HANDLER_ARGS) if (!p) return (0); - if ((!ps_argsopen) && p_can(curproc, p, P_CAN_SEE, NULL)) { + if ((!ps_argsopen) && p_cansee(curproc, p)) { PROC_UNLOCK(p); return (0); } diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index ceb8f5a876d8..1c6ce7725cca 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -151,7 +151,7 @@ getpgid(p, uap) else { if ((pt = pfind(uap->pid)) == NULL) return ESRCH; - if ((error = p_can(p, pt, P_CAN_SEE, NULL))) { + if ((error = p_cansee(p, pt))) { PROC_UNLOCK(pt); return (error); } @@ -183,7 +183,7 @@ getsid(p, uap) else { if ((pt = pfind(uap->pid)) == NULL) return ESRCH; - if ((error = p_can(p, pt, P_CAN_SEE, NULL))) { + if ((error = p_cansee(p, pt))) { PROC_UNLOCK(pt); return (error); } @@ -370,7 +370,7 @@ setpgid(curp, uap) PROC_UNLOCK(targp); return (ESRCH); } - if ((error = p_can(curproc, targp, P_CAN_SEE, NULL))) { + if ((error = p_cansee(curproc, targp))) { PROC_UNLOCK(targp); return (error); } @@ -1086,13 +1086,10 @@ u_cansee(struct ucred *u1, struct ucred *u2) return (0); } -static int -p_cansee(struct proc *p1, struct proc *p2, int *privused) +int +p_cansee(struct proc *p1, struct proc *p2) { - /* XXX: privused is going away, so don't do that here. */ - if (privused != NULL) - *privused = 0; /* Wrap u_cansee() for all functionality. */ return (u_cansee(p1->p_ucred, p2->p_ucred)); } @@ -1167,14 +1164,11 @@ p_cansignal(struct proc *p1, struct proc *p2, int signum) return (0); } -static int -p_cansched(struct proc *p1, struct proc *p2, int *privused) +int +p_cansched(struct proc *p1, struct proc *p2) { int error; - if (privused != NULL) - *privused = 0; - if (p1 == p2) return (0); @@ -1186,31 +1180,22 @@ p_cansched(struct proc *p1, struct proc *p2, int *privused) if (p1->p_ucred->cr_uid == p2->p_ucred->cr_ruid) return (0); - if (!suser_xxx(0, p1, PRISON_ROOT)) { - if (privused != NULL) - *privused = 1; + if (!suser_xxx(0, p1, PRISON_ROOT)) return (0); - } #ifdef CAPABILITIES - if (!cap_check_xxx(0, p1, CAP_SYS_NICE, PRISON_ROOT)) { - if (privused != NULL) - *privused = 1; + if (!cap_check_xxx(0, p1, CAP_SYS_NICE, PRISON_ROOT)) return (0); - } #endif return (EPERM); } -static int -p_candebug(struct proc *p1, struct proc *p2, int *privused) +int +p_candebug(struct proc *p1, struct proc *p2) { int error; - if (privused != NULL) - *privused = 0; - if (p1 == p2) return (0); @@ -1222,12 +1207,9 @@ p_candebug(struct proc *p1, struct proc *p2, int *privused) if (p1->p_ucred->cr_uid != p2->p_ucred->cr_uid || p1->p_ucred->cr_uid != p2->p_ucred->cr_svuid || p1->p_ucred->cr_uid != p2->p_ucred->cr_ruid || - p2->p_flag & P_SUGID) { + p2->p_flag & P_SUGID) if ((error = suser_xxx(0, p1, PRISON_ROOT))) return (error); - if (privused != NULL) - *privused = 1; - } /* can't trace init when securelevel > 0 */ if (securelevel > 0 && p2->p_pid == 1) @@ -1236,27 +1218,6 @@ p_candebug(struct proc *p1, struct proc *p2, int *privused) return (0); } -int -p_can(struct proc *p1, struct proc *p2, int operation, - int *privused) -{ - - switch(operation) { - case P_CAN_SEE: - return (p_cansee(p1, p2, privused)); - - case P_CAN_SCHED: - return (p_cansched(p1, p2, privused)); - - case P_CAN_DEBUG: - return (p_candebug(p1, p2, privused)); - - default: - panic("p_can: invalid operation"); - } -} - - /* * Allocate a zeroed cred structure. */ diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c index f7503dbfde44..6e9ee8508d54 100644 --- a/sys/kern/kern_resource.c +++ b/sys/kern/kern_resource.c @@ -99,7 +99,7 @@ getpriority(curp, uap) p = pfind(uap->who); if (p == NULL) break; - if (p_can(curp, p, P_CAN_SEE, NULL) == 0) + if (p_cansee(curp, p) == 0) low = p->p_nice; PROC_UNLOCK(p); } @@ -113,7 +113,7 @@ getpriority(curp, uap) else if ((pg = pgfind(uap->who)) == NULL) break; LIST_FOREACH(p, &pg->pg_members, p_pglist) { - if (!p_can(curp, p, P_CAN_SEE, NULL) && p->p_nice < low) + if (!p_cansee(curp, p) && p->p_nice < low) low = p->p_nice; } break; @@ -124,7 +124,7 @@ getpriority(curp, uap) uap->who = curp->p_ucred->cr_uid; sx_slock(&allproc_lock); LIST_FOREACH(p, &allproc, p_list) - if (!p_can(curp, p, P_CAN_SEE, NULL) && + if (!p_cansee(curp, p) && p->p_ucred->cr_uid == uap->who && p->p_nice < low) low = p->p_nice; @@ -165,7 +165,7 @@ setpriority(curp, uap) p = pfind(uap->who); if (p == 0) break; - if (p_can(curp, p, P_CAN_SEE, NULL) == 0) + if (p_cansee(curp, p) == 0) error = donice(curp, p, uap->prio); PROC_UNLOCK(p); } @@ -180,7 +180,7 @@ setpriority(curp, uap) else if ((pg = pgfind(uap->who)) == NULL) break; LIST_FOREACH(p, &pg->pg_members, p_pglist) { - if (!p_can(curp, p, P_CAN_SEE, NULL)) { + if (!p_cansee(curp, p)) { error = donice(curp, p, uap->prio); found++; } @@ -194,7 +194,7 @@ setpriority(curp, uap) sx_slock(&allproc_lock); LIST_FOREACH(p, &allproc, p_list) if (p->p_ucred->cr_uid == uap->who && - !p_can(curp, p, P_CAN_SEE, NULL)) { + !p_cansee(curp, p)) { error = donice(curp, p, uap->prio); found++; } @@ -216,7 +216,7 @@ donice(curp, chgp, n) { int error; - if ((error = p_can(curp, chgp, P_CAN_SCHED, NULL))) + if ((error = p_cansched(curp, chgp))) return (error); if (n > PRIO_MAX) n = PRIO_MAX; @@ -263,13 +263,13 @@ rtprio(curp, uap) switch (uap->function) { case RTP_LOOKUP: - if ((error = p_can(curp, p, P_CAN_SEE, NULL))) + if ((error = p_cansee(curp, p))) break; pri_to_rtp(&p->p_pri, &rtp); error = copyout(&rtp, uap->rtp, sizeof(struct rtprio)); break; case RTP_SET: - if ((error = p_can(curp, p, P_CAN_SCHED, NULL)) || + if ((error = p_cansched(curp, p)) || (error = copyin(uap->rtp, &rtp, sizeof(struct rtprio)))) break; /* disallow setting rtprio in most cases if not superuser */ diff --git a/sys/kern/p1003_1b.c b/sys/kern/p1003_1b.c index 5b9bee025a1d..1c356e3b4531 100644 --- a/sys/kern/p1003_1b.c +++ b/sys/kern/p1003_1b.c @@ -122,7 +122,7 @@ int sched_setparam(struct proc *p, return (ESRCH); } - e = p_can(p, targetp, P_CAN_SCHED, NULL); + e = p_cansched(p, targetp); PROC_UNLOCK(targetp); if (e) return (e); @@ -148,7 +148,7 @@ int sched_getparam(struct proc *p, return (ESRCH); } - e = p_can(p, targetp, P_CAN_SEE, NULL); + e = p_cansee(p, targetp); PROC_UNLOCK(targetp); if (e) return (e); @@ -180,7 +180,7 @@ int sched_setscheduler(struct proc *p, return (ESRCH); } - e = p_can(p, targetp, P_CAN_SCHED, NULL); + e = p_cansched(p, targetp); PROC_UNLOCK(targetp); if (e) return (e); @@ -205,7 +205,7 @@ int sched_getscheduler(struct proc *p, return (ESRCH); } - e = p_can(p, targetp, P_CAN_SEE, NULL); + e = p_cansee(p, targetp); PROC_UNLOCK(targetp); if (e) return (e); @@ -246,7 +246,7 @@ int sched_rr_get_interval(struct proc *p, return (ESRCH); } - e = p_can(p, targetp, P_CAN_SEE, NULL); + e = p_cansee(p, targetp); PROC_UNLOCK(targetp); if (e) return (e); diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index 799608d489e9..66d7e675b33a 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -220,7 +220,7 @@ ptrace(curp, uap) if ((p = pfind(uap->pid)) == NULL) return ESRCH; } - if (p_can(curp, p, P_CAN_SEE, NULL)) { + if (p_cansee(curp, p)) { PROC_UNLOCK(p); return (ESRCH); } @@ -246,7 +246,7 @@ ptrace(curp, uap) return EBUSY; } - if ((error = p_can(curp, p, P_CAN_DEBUG, NULL))) { + if ((error = p_candebug(curp, p))) { PROC_UNLOCK(p); return error; } |