Skip to content

Commit ddb99e1

Browse files
ereshetovaJames Morris
authored andcommitted
security, keys: convert key_user.usage from atomic_t to refcount_t
refcount_t type and corresponding API should be used instead of atomic_t when the variable is used as a reference counter. This allows to avoid accidental refcounter overflows that might lead to use-after-free situations. Signed-off-by: Elena Reshetova <elena.reshetova@intel.com> Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com> Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: David Windsor <dwindsor@gmail.com> Acked-by: David Howells <dhowells@redhat.com> Signed-off-by: James Morris <james.l.morris@oracle.com>
1 parent fff2929 commit ddb99e1

File tree

4 files changed

+7
-6
lines changed

4 files changed

+7
-6
lines changed

security/keys/internal.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/key-type.h>
1818
#include <linux/task_work.h>
1919
#include <linux/keyctl.h>
20+
#include <linux/refcount.h>
2021

2122
struct iovec;
2223

@@ -53,7 +54,7 @@ struct key_user {
5354
struct rb_node node;
5455
struct mutex cons_lock; /* construction initiation lock */
5556
spinlock_t lock;
56-
atomic_t usage; /* for accessing qnkeys & qnbytes */
57+
refcount_t usage; /* for accessing qnkeys & qnbytes */
5758
atomic_t nkeys; /* number of keys */
5859
atomic_t nikeys; /* number of instantiated keys */
5960
kuid_t uid;

security/keys/key.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ struct key_user *key_user_lookup(kuid_t uid)
9393

9494
/* if we get here, then the user record still hadn't appeared on the
9595
* second pass - so we use the candidate record */
96-
atomic_set(&candidate->usage, 1);
96+
refcount_set(&candidate->usage, 1);
9797
atomic_set(&candidate->nkeys, 0);
9898
atomic_set(&candidate->nikeys, 0);
9999
candidate->uid = uid;
@@ -110,7 +110,7 @@ struct key_user *key_user_lookup(kuid_t uid)
110110

111111
/* okay - we found a user record for this UID */
112112
found:
113-
atomic_inc(&user->usage);
113+
refcount_inc(&user->usage);
114114
spin_unlock(&key_user_lock);
115115
kfree(candidate);
116116
out:
@@ -122,7 +122,7 @@ struct key_user *key_user_lookup(kuid_t uid)
122122
*/
123123
void key_user_put(struct key_user *user)
124124
{
125-
if (atomic_dec_and_lock(&user->usage, &key_user_lock)) {
125+
if (refcount_dec_and_lock(&user->usage, &key_user_lock)) {
126126
rb_erase(&user->node, &key_user_tree);
127127
spin_unlock(&key_user_lock);
128128

security/keys/proc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ static int proc_key_users_show(struct seq_file *m, void *v)
340340

341341
seq_printf(m, "%5u: %5d %d/%d %d/%d %d/%d\n",
342342
from_kuid_munged(seq_user_ns(m), user->uid),
343-
atomic_read(&user->usage),
343+
refcount_read(&user->usage),
344344
atomic_read(&user->nkeys),
345345
atomic_read(&user->nikeys),
346346
user->qnkeys,

security/keys/process_keys.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ static DEFINE_MUTEX(key_user_keyring_mutex);
3030

3131
/* The root user's tracking struct */
3232
struct key_user root_key_user = {
33-
.usage = ATOMIC_INIT(3),
33+
.usage = REFCOUNT_INIT(3),
3434
.cons_lock = __MUTEX_INITIALIZER(root_key_user.cons_lock),
3535
.lock = __SPIN_LOCK_UNLOCKED(root_key_user.lock),
3636
.nkeys = ATOMIC_INIT(2),

0 commit comments

Comments
 (0)