DF-2868 / fix.diff
--- sys/kern/kern_ktrace.c 2026-06-29 12:51:19.000000000 +0000 +++ /tmp/opencode/v26/fixtree/sys/kern/kern_ktrace.c 2026-10-24 16:33:07.877714441 +0000 @@ -668,20 +668,34 @@ ktrcanset(struct thread *calltd, struct proc *targetp) { struct ucred *caller = calltd->td_ucred; - struct ucred *target = targetp->p_ucred; + struct ucred *target; + int rv; - if (!PRISON_CHECK(caller, target)) + /* + * DF-2868: p_ucred is only stable under p_token; hold a + * reference while checking instead of racing cratom_proc. + */ + lwkt_gettoken_shared(&targetp->p_token); + target = targetp->p_ucred; + if (target) + target = crhold(target); + lwkt_reltoken(&targetp->p_token); + if (target == NULL) return (0); - if ((caller->cr_uid == target->cr_ruid && - target->cr_ruid == target->cr_svuid && - caller->cr_rgid == target->cr_rgid && /* XXX */ - target->cr_rgid == target->cr_svgid && - (targetp->p_traceflag & KTRFAC_ROOT) == 0 && - (targetp->p_flags & P_SUGID) == 0) || - caller->cr_uid == 0) - return (1); - return (0); + rv = 0; + if (PRISON_CHECK(caller, target) && + ((caller->cr_uid == target->cr_ruid && + target->cr_ruid == target->cr_svuid && + caller->cr_rgid == target->cr_rgid && /* XXX */ + target->cr_rgid == target->cr_svgid && + (targetp->p_traceflag & KTRFAC_ROOT) == 0 && + (targetp->p_flags & P_SUGID) == 0) || + caller->cr_uid == 0)) + rv = 1; + crfree(target); + + return (rv); } #endif /* KTRACE */ |