Revert "kern: RACCT: Keep process credentials alive via references"
The change causes a panic on boot with INVARIANTS kernels. Revert for
now.
This reverts commit a5d1a0c9bf.
Reported by: syzbot+74624c6fcbb384ea0113@syzkaller.appspotmail.com
This commit is contained in:
@@ -3043,19 +3043,14 @@ do_jail_attach(struct thread *td, struct prison *pr, int drflags)
|
||||
PROC_LOCK(p);
|
||||
oldcred = crcopysafe(p, newcred);
|
||||
newcred->cr_prison = pr;
|
||||
proc_set_cred(p, newcred);
|
||||
setsugid(p);
|
||||
#ifdef RACCT
|
||||
racct_proc_ucred_changed(p, oldcred, newcred);
|
||||
#endif
|
||||
#ifdef RCTL
|
||||
crhold(newcred);
|
||||
#endif
|
||||
/*
|
||||
* Takes over 'newcred''s reference, so 'newcred' must not be used
|
||||
* besides this point except on RCTL where we took an additional
|
||||
* reference above.
|
||||
*/
|
||||
proc_set_cred(p, newcred);
|
||||
setsugid(p);
|
||||
PROC_UNLOCK(p);
|
||||
#ifdef RCTL
|
||||
rctl_proc_ucred_changed(p, newcred);
|
||||
|
||||
@@ -222,18 +222,13 @@ sys_setloginclass(struct thread *td, struct setloginclass_args *uap)
|
||||
PROC_LOCK(p);
|
||||
oldcred = crcopysafe(p, newcred);
|
||||
newcred->cr_loginclass = newlc;
|
||||
proc_set_cred(p, newcred);
|
||||
#ifdef RACCT
|
||||
racct_proc_ucred_changed(p, oldcred, newcred);
|
||||
#endif
|
||||
#ifdef RCTL
|
||||
crhold(newcred);
|
||||
#endif
|
||||
/*
|
||||
* Takes over 'newcred''s reference, so 'newcred' must not be used
|
||||
* besides this point except on RCTL where we took an additional
|
||||
* reference above.
|
||||
*/
|
||||
proc_set_cred(p, newcred);
|
||||
PROC_UNLOCK(p);
|
||||
#ifdef RCTL
|
||||
rctl_proc_ucred_changed(p, newcred);
|
||||
|
||||
+15
-39
@@ -832,31 +832,22 @@ kern_setcred(struct thread *const td, const u_int flags,
|
||||
if (error != 0)
|
||||
goto unlock_finish;
|
||||
|
||||
#ifdef RACCT
|
||||
/*
|
||||
* Hold a reference to 'new_cred', as we need to call some functions on
|
||||
* it after proc_set_cred_enforce_proc_lim().
|
||||
* Set the new credentials, noting that they have changed.
|
||||
*/
|
||||
crhold(new_cred);
|
||||
#endif
|
||||
|
||||
/* Set the new credentials. */
|
||||
cred_set = proc_set_cred_enforce_proc_lim(p, new_cred);
|
||||
if (cred_set) {
|
||||
setsugid(p);
|
||||
to_free_cred = old_cred;
|
||||
#ifdef RACCT
|
||||
/* Adjust RACCT counters. */
|
||||
racct_proc_ucred_changed(p, old_cred, new_cred);
|
||||
#endif
|
||||
to_free_cred = old_cred;
|
||||
MPASS(error == 0);
|
||||
} else {
|
||||
#ifdef RACCT
|
||||
/* Matches the crhold() just before the containing 'if'. */
|
||||
crfree(new_cred);
|
||||
#ifdef RCTL
|
||||
crhold(new_cred);
|
||||
#endif
|
||||
MPASS(error == 0);
|
||||
} else
|
||||
error = EAGAIN;
|
||||
}
|
||||
|
||||
unlock_finish:
|
||||
PROC_UNLOCK(p);
|
||||
@@ -866,12 +857,10 @@ kern_setcred(struct thread *const td, const u_int flags,
|
||||
* finishing operations.
|
||||
*/
|
||||
|
||||
#ifdef RACCT
|
||||
if (cred_set) {
|
||||
#ifdef RCTL
|
||||
if (cred_set) {
|
||||
rctl_proc_ucred_changed(p, new_cred);
|
||||
#endif
|
||||
/* Paired with the crhold() above. */
|
||||
/* Paired with the crhold() just above. */
|
||||
crfree(new_cred);
|
||||
}
|
||||
#endif
|
||||
@@ -1002,19 +991,16 @@ sys_setuid(struct thread *td, struct setuid_args *uap)
|
||||
change_euid(newcred, uip);
|
||||
setsugid(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* This also transfers the proc count to the new user.
|
||||
*/
|
||||
proc_set_cred(p, newcred);
|
||||
#ifdef RACCT
|
||||
racct_proc_ucred_changed(p, oldcred, newcred);
|
||||
#endif
|
||||
#ifdef RCTL
|
||||
crhold(newcred);
|
||||
#endif
|
||||
/*
|
||||
* Takes over 'newcred''s reference, so 'newcred' must not be used
|
||||
* besides this point except on RCTL where we took an additional
|
||||
* reference above.
|
||||
*/
|
||||
proc_set_cred(p, newcred);
|
||||
PROC_UNLOCK(p);
|
||||
#ifdef RCTL
|
||||
rctl_proc_ucred_changed(p, newcred);
|
||||
@@ -1418,18 +1404,13 @@ sys_setreuid(struct thread *td, struct setreuid_args *uap)
|
||||
change_svuid(newcred, newcred->cr_uid);
|
||||
setsugid(p);
|
||||
}
|
||||
proc_set_cred(p, newcred);
|
||||
#ifdef RACCT
|
||||
racct_proc_ucred_changed(p, oldcred, newcred);
|
||||
#endif
|
||||
#ifdef RCTL
|
||||
crhold(newcred);
|
||||
#endif
|
||||
/*
|
||||
* Takes over 'newcred''s reference, so 'newcred' must not be used
|
||||
* besides this point except on RCTL where we took an additional
|
||||
* reference above.
|
||||
*/
|
||||
proc_set_cred(p, newcred);
|
||||
PROC_UNLOCK(p);
|
||||
#ifdef RCTL
|
||||
rctl_proc_ucred_changed(p, newcred);
|
||||
@@ -1571,18 +1552,13 @@ sys_setresuid(struct thread *td, struct setresuid_args *uap)
|
||||
change_svuid(newcred, suid);
|
||||
setsugid(p);
|
||||
}
|
||||
proc_set_cred(p, newcred);
|
||||
#ifdef RACCT
|
||||
racct_proc_ucred_changed(p, oldcred, newcred);
|
||||
#endif
|
||||
#ifdef RCTL
|
||||
crhold(newcred);
|
||||
#endif
|
||||
/*
|
||||
* Takes over 'newcred''s reference, so 'newcred' must not be used
|
||||
* besides this point except on RCTL where we took an additional
|
||||
* reference above.
|
||||
*/
|
||||
proc_set_cred(p, newcred);
|
||||
PROC_UNLOCK(p);
|
||||
#ifdef RCTL
|
||||
rctl_proc_ucred_changed(p, newcred);
|
||||
@@ -2807,7 +2783,7 @@ cru2xt(struct thread *td, struct xucred *xcr)
|
||||
* 'enforce_proc_lim' being true and if no new process can be accounted to the
|
||||
* new real UID because of the current limit (see the inner comment for more
|
||||
* details) and the caller does not have privilege (PRIV_PROC_LIMIT) to override
|
||||
* that. In this case, the reference to 'newcred' is not taken over.
|
||||
* that.
|
||||
*/
|
||||
static bool
|
||||
_proc_set_cred(struct proc *p, struct ucred *newcred, bool enforce_proc_lim)
|
||||
|
||||
@@ -949,10 +949,8 @@ racct_proc_exit(struct proc *p)
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to signal credentials change, to move resource utilisation
|
||||
* between raccts. Must be called with the proc lock held, in the same span as
|
||||
* the credentials change itself (i.e., without the proc lock being unlocked
|
||||
* between the two), but the order does not matter.
|
||||
* Called after credentials change, to move resource utilisation
|
||||
* between raccts.
|
||||
*/
|
||||
void
|
||||
racct_proc_ucred_changed(struct proc *p, struct ucred *oldcred,
|
||||
|
||||
Reference in New Issue
Block a user