? tmp Index: kern_prot.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_prot.c,v retrieving revision 1.80 diff -u -r1.80 kern_prot.c --- kern_prot.c 2001/04/12 02:38:07 1.80 +++ kern_prot.c 2001/04/12 03:42:28 @@ -1169,18 +1169,41 @@ if ((error = prison_check(p1->p_ucred, p2->p_ucred))) return (error); - /* not owned by you, has done setuid (unless you're root) */ - /* add a CAP_SYS_PTRACE here? */ - if (p1->p_cred->pc_ucred->cr_uid != p2->p_cred->p_ruid || - p1->p_cred->p_ruid != p2->p_cred->p_ruid || - p1->p_cred->p_svuid != p2->p_cred->p_ruid || - p2->p_flag & P_SUGID) { - if ((error = suser_xxx(0, p1, PRISON_ROOT))) + /* + * If the target process has had a credential change require + * privilege to debug the process. + */ + if (p2->p_flag & P_SUGID) { + if ((error = suser_xxx(NULL, p1, PRISON_ROOT))) return (error); - if (privused != NULL) - *privused = 1; } - + /* + * The target process credentials must be a subset of the current + * process credentials. For now, we evaluate only based on uid's, + * but in the future will take into account gig's as well. + */ + /* Object euid must be present in subject's uid set. */ + if (p1->p_ucred->cr_uid != p2->p_ucred->cr_uid && + p1->p_cred->p_ruid != p2->p_ucred->cr_uid && + p1->p_cred->p_svuid != p2->p_ucred->cr_uid) { + if ((error = suser_xxx(NULL, p1, PRISON_ROOT))) + return (error); + } + /* Object ruid must be present in subject's uid set. */ + if (p1->p_ucred->cr_uid != p2->p_cred->p_ruid && + p1->p_cred->p_ruid != p2->p_cred->p_ruid && + p1->p_cred->p_svuid != p2->p_cred->p_ruid) { + if ((error = suser_xxx(NULL, p1, PRISON_ROOT))) + return (error); + } + /* Object svuid must be present in subject's uid set. */ + if (p1->p_ucred->cr_uid != p2->p_cred->p_svuid && + p1->p_cred->p_ruid != p2->p_cred->p_svuid && + p1->p_cred->p_svuid != p2->p_cred->p_svuid) { + if ((error = suser_xxx(NULL, p1, PRISON_ROOT))) + return (error); + } + /* can't trace init when securelevel > 0 */ if (securelevel > 0 && p2->p_pid == 1) return (EPERM);