diff options
author | Mateusz Guzik <mjguzik@gmail.com> | 2023-09-09 21:19:32 +0200 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2023-09-21 19:29:30 -0400 |
commit | 41e845628511878d6e89e2a9249c095e72aab7eb (patch) | |
tree | 4c23b005302b82e9987a21af0391c7ab3a32f623 /kernel/cred.c | |
parent | 20a2aa47097aae7016209c4dbe392b3b25e0d883 (diff) |
cred: add get_cred_many and put_cred_many
Some of the frequent consumers of get_cred and put_cred operate on 2
references on the same creds back-to-back.
Switch them to doing the work in one go instead.
Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
[PM: removed changelog from commit description]
Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'kernel/cred.c')
-rw-r--r-- | kernel/cred.c | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/kernel/cred.c b/kernel/cred.c index 98cb4eca23fb..9398e534b997 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -162,23 +162,29 @@ EXPORT_SYMBOL(__put_cred); */ void exit_creds(struct task_struct *tsk) { - struct cred *cred; + struct cred *real_cred, *cred; kdebug("exit_creds(%u,%p,%p,{%d,%d})", tsk->pid, tsk->real_cred, tsk->cred, atomic_read(&tsk->cred->usage), read_cred_subscribers(tsk->cred)); - cred = (struct cred *) tsk->real_cred; + real_cred = (struct cred *) tsk->real_cred; tsk->real_cred = NULL; - validate_creds(cred); - alter_cred_subscribers(cred, -1); - put_cred(cred); cred = (struct cred *) tsk->cred; tsk->cred = NULL; + validate_creds(cred); - alter_cred_subscribers(cred, -1); - put_cred(cred); + if (real_cred == cred) { + alter_cred_subscribers(cred, -2); + put_cred_many(cred, 2); + } else { + validate_creds(real_cred); + alter_cred_subscribers(real_cred, -1); + put_cred(real_cred); + alter_cred_subscribers(cred, -1); + put_cred(cred); + } #ifdef CONFIG_KEYS_REQUEST_CACHE key_put(tsk->cached_requested_key); @@ -355,8 +361,7 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) #endif clone_flags & CLONE_THREAD ) { - p->real_cred = get_cred(p->cred); - get_cred(p->cred); + p->real_cred = get_cred_many(p->cred, 2); alter_cred_subscribers(p->cred, 2); kdebug("share_creds(%p{%d,%d})", p->cred, atomic_read(&p->cred->usage), @@ -520,8 +525,7 @@ int commit_creds(struct cred *new) proc_id_connector(task, PROC_EVENT_GID); /* release the old obj and subj refs both */ - put_cred(old); - put_cred(old); + put_cred_many(old, 2); return 0; } EXPORT_SYMBOL(commit_creds); |