Skip to content

Commit 49dffdf

Browse files
vcgomesamir73il
authored andcommitted
cred: Add a light version of override/revert_creds()
Add a light version of override/revert_creds(), this should only be used when the credentials in question will outlive the critical section and the critical section doesn't change the ->usage of the credentials. Suggested-by: Christian Brauner <[email protected]> Signed-off-by: Vinicius Costa Gomes <[email protected]> Signed-off-by: Amir Goldstein <[email protected]>
1 parent 48b5062 commit 49dffdf

File tree

2 files changed

+21
-3
lines changed

2 files changed

+21
-3
lines changed

include/linux/cred.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,24 @@ static inline bool cap_ambient_invariant_ok(const struct cred *cred)
172172
cred->cap_inheritable));
173173
}
174174

175+
/*
176+
* Override creds without bumping reference count. Caller must ensure
177+
* reference remains valid or has taken reference. Almost always not the
178+
* interface you want. Use override_creds()/revert_creds() instead.
179+
*/
180+
static inline const struct cred *override_creds_light(const struct cred *override_cred)
181+
{
182+
const struct cred *old = current->cred;
183+
184+
rcu_assign_pointer(current->cred, override_cred);
185+
return old;
186+
}
187+
188+
static inline void revert_creds_light(const struct cred *revert_cred)
189+
{
190+
rcu_assign_pointer(current->cred, revert_cred);
191+
}
192+
175193
/**
176194
* get_new_cred_many - Get references on a new set of credentials
177195
* @cred: The new credentials to reference

kernel/cred.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ EXPORT_SYMBOL(abort_creds);
485485
*/
486486
const struct cred *override_creds(const struct cred *new)
487487
{
488-
const struct cred *old = current->cred;
488+
const struct cred *old;
489489

490490
kdebug("override_creds(%p{%ld})", new,
491491
atomic_long_read(&new->usage));
@@ -499,7 +499,7 @@ const struct cred *override_creds(const struct cred *new)
499499
* visible to other threads under RCU.
500500
*/
501501
get_new_cred((struct cred *)new);
502-
rcu_assign_pointer(current->cred, new);
502+
old = override_creds_light(new);
503503

504504
kdebug("override_creds() = %p{%ld}", old,
505505
atomic_long_read(&old->usage));
@@ -521,7 +521,7 @@ void revert_creds(const struct cred *old)
521521
kdebug("revert_creds(%p{%ld})", old,
522522
atomic_long_read(&old->usage));
523523

524-
rcu_assign_pointer(current->cred, old);
524+
revert_creds_light(old);
525525
put_cred(override);
526526
}
527527
EXPORT_SYMBOL(revert_creds);

0 commit comments

Comments
 (0)