Skip to content

Commit 25c7364

Browse files
committed
Merge tag 'keys-next-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd
Pull keys updates from Jarkko Sakkinen: - do not overwrite the key expiration once it is set - move key quota updates earlier into key_put(), instead of updating them in key_gc_unused_keys() * tag 'keys-next-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd: keys: Fix overwrite of key expiration on instantiation keys: update key quotas in key_put()
2 parents b192391 + 9da27fb commit 25c7364

File tree

3 files changed

+30
-24
lines changed

3 files changed

+30
-24
lines changed

security/keys/gc.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -155,14 +155,6 @@ static noinline void key_gc_unused_keys(struct list_head *keys)
155155

156156
security_key_free(key);
157157

158-
/* deal with the user's key tracking and quota */
159-
if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
160-
spin_lock(&key->user->lock);
161-
key->user->qnkeys--;
162-
key->user->qnbytes -= key->quotalen;
163-
spin_unlock(&key->user->lock);
164-
}
165-
166158
atomic_dec(&key->user->nkeys);
167159
if (state != KEY_IS_UNINSTANTIATED)
168160
atomic_dec(&key->user->nikeys);

security/keys/key.c

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
230230
struct key *key;
231231
size_t desclen, quotalen;
232232
int ret;
233+
unsigned long irqflags;
233234

234235
key = ERR_PTR(-EINVAL);
235236
if (!desc || !*desc)
@@ -259,7 +260,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
259260
unsigned maxbytes = uid_eq(uid, GLOBAL_ROOT_UID) ?
260261
key_quota_root_maxbytes : key_quota_maxbytes;
261262

262-
spin_lock(&user->lock);
263+
spin_lock_irqsave(&user->lock, irqflags);
263264
if (!(flags & KEY_ALLOC_QUOTA_OVERRUN)) {
264265
if (user->qnkeys + 1 > maxkeys ||
265266
user->qnbytes + quotalen > maxbytes ||
@@ -269,7 +270,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
269270

270271
user->qnkeys++;
271272
user->qnbytes += quotalen;
272-
spin_unlock(&user->lock);
273+
spin_unlock_irqrestore(&user->lock, irqflags);
273274
}
274275

275276
/* allocate and initialise the key and its description */
@@ -327,10 +328,10 @@ struct key *key_alloc(struct key_type *type, const char *desc,
327328
kfree(key->description);
328329
kmem_cache_free(key_jar, key);
329330
if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) {
330-
spin_lock(&user->lock);
331+
spin_lock_irqsave(&user->lock, irqflags);
331332
user->qnkeys--;
332333
user->qnbytes -= quotalen;
333-
spin_unlock(&user->lock);
334+
spin_unlock_irqrestore(&user->lock, irqflags);
334335
}
335336
key_user_put(user);
336337
key = ERR_PTR(ret);
@@ -340,18 +341,18 @@ struct key *key_alloc(struct key_type *type, const char *desc,
340341
kmem_cache_free(key_jar, key);
341342
no_memory_2:
342343
if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) {
343-
spin_lock(&user->lock);
344+
spin_lock_irqsave(&user->lock, irqflags);
344345
user->qnkeys--;
345346
user->qnbytes -= quotalen;
346-
spin_unlock(&user->lock);
347+
spin_unlock_irqrestore(&user->lock, irqflags);
347348
}
348349
key_user_put(user);
349350
no_memory_1:
350351
key = ERR_PTR(-ENOMEM);
351352
goto error;
352353

353354
no_quota:
354-
spin_unlock(&user->lock);
355+
spin_unlock_irqrestore(&user->lock, irqflags);
355356
key_user_put(user);
356357
key = ERR_PTR(-EDQUOT);
357358
goto error;
@@ -380,8 +381,9 @@ int key_payload_reserve(struct key *key, size_t datalen)
380381
if (delta != 0 && test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
381382
unsigned maxbytes = uid_eq(key->user->uid, GLOBAL_ROOT_UID) ?
382383
key_quota_root_maxbytes : key_quota_maxbytes;
384+
unsigned long flags;
383385

384-
spin_lock(&key->user->lock);
386+
spin_lock_irqsave(&key->user->lock, flags);
385387

386388
if (delta > 0 &&
387389
(key->user->qnbytes + delta > maxbytes ||
@@ -392,7 +394,7 @@ int key_payload_reserve(struct key *key, size_t datalen)
392394
key->user->qnbytes += delta;
393395
key->quotalen += delta;
394396
}
395-
spin_unlock(&key->user->lock);
397+
spin_unlock_irqrestore(&key->user->lock, flags);
396398
}
397399

398400
/* change the recorded data length if that didn't generate an error */
@@ -463,7 +465,8 @@ static int __key_instantiate_and_link(struct key *key,
463465
if (authkey)
464466
key_invalidate(authkey);
465467

466-
key_set_expiry(key, prep->expiry);
468+
if (prep->expiry != TIME64_MAX)
469+
key_set_expiry(key, prep->expiry);
467470
}
468471
}
469472

@@ -645,8 +648,18 @@ void key_put(struct key *key)
645648
if (key) {
646649
key_check(key);
647650

648-
if (refcount_dec_and_test(&key->usage))
651+
if (refcount_dec_and_test(&key->usage)) {
652+
unsigned long flags;
653+
654+
/* deal with the user's key tracking and quota */
655+
if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
656+
spin_lock_irqsave(&key->user->lock, flags);
657+
key->user->qnkeys--;
658+
key->user->qnbytes -= key->quotalen;
659+
spin_unlock_irqrestore(&key->user->lock, flags);
660+
}
649661
schedule_work(&key_gc_work);
662+
}
650663
}
651664
}
652665
EXPORT_SYMBOL(key_put);

security/keys/keyctl.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,7 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group)
954954
long ret;
955955
kuid_t uid;
956956
kgid_t gid;
957+
unsigned long flags;
957958

958959
uid = make_kuid(current_user_ns(), user);
959960
gid = make_kgid(current_user_ns(), group);
@@ -1010,7 +1011,7 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group)
10101011
unsigned maxbytes = uid_eq(uid, GLOBAL_ROOT_UID) ?
10111012
key_quota_root_maxbytes : key_quota_maxbytes;
10121013

1013-
spin_lock(&newowner->lock);
1014+
spin_lock_irqsave(&newowner->lock, flags);
10141015
if (newowner->qnkeys + 1 > maxkeys ||
10151016
newowner->qnbytes + key->quotalen > maxbytes ||
10161017
newowner->qnbytes + key->quotalen <
@@ -1019,12 +1020,12 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group)
10191020

10201021
newowner->qnkeys++;
10211022
newowner->qnbytes += key->quotalen;
1022-
spin_unlock(&newowner->lock);
1023+
spin_unlock_irqrestore(&newowner->lock, flags);
10231024

1024-
spin_lock(&key->user->lock);
1025+
spin_lock_irqsave(&key->user->lock, flags);
10251026
key->user->qnkeys--;
10261027
key->user->qnbytes -= key->quotalen;
1027-
spin_unlock(&key->user->lock);
1028+
spin_unlock_irqrestore(&key->user->lock, flags);
10281029
}
10291030

10301031
atomic_dec(&key->user->nkeys);
@@ -1056,7 +1057,7 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group)
10561057
return ret;
10571058

10581059
quota_overrun:
1059-
spin_unlock(&newowner->lock);
1060+
spin_unlock_irqrestore(&newowner->lock, flags);
10601061
zapowner = newowner;
10611062
ret = -EDQUOT;
10621063
goto error_put;

0 commit comments

Comments
 (0)