Per thread cached credentials are accessed only by curproc. Curproc doesn't modify it's 'p_ucred' directly. It allocates new copy, then modyfies newcopy and replaces the old. So 'p_ucred' is owned by curproc.
Index: sys/sys/proc.h =================================================================== RCS file: /cvs/src/sys/sys/proc.h,v retrieving revision 1.294 diff -u -p -r1.294 proc.h --- sys/sys/proc.h 6 Apr 2020 07:52:12 -0000 1.294 +++ sys/sys/proc.h 24 Apr 2020 10:12:56 -0000 @@ -392,7 +392,7 @@ struct proc { u_int p_estcpu; /* [s] Time averaged val of p_cpticks */ int p_pledge_syscall; /* Cache of current syscall */ - struct ucred *p_ucred; /* cached credentials */ + struct ucred *p_ucred; /* [o] cached credentials */ struct sigaltstack p_sigstk; /* sp & on stack state variable */ u_long p_prof_addr; /* tmp storage for profiling addr until AST */