Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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()

+30 -24
-8
security/keys/gc.c
··· 155 155 156 156 security_key_free(key); 157 157 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 - 166 158 atomic_dec(&key->user->nkeys); 167 159 if (state != KEY_IS_UNINSTANTIATED) 168 160 atomic_dec(&key->user->nikeys);
+24 -11
security/keys/key.c
··· 230 230 struct key *key; 231 231 size_t desclen, quotalen; 232 232 int ret; 233 + unsigned long irqflags; 233 234 234 235 key = ERR_PTR(-EINVAL); 235 236 if (!desc || !*desc) ··· 260 259 unsigned maxbytes = uid_eq(uid, GLOBAL_ROOT_UID) ? 261 260 key_quota_root_maxbytes : key_quota_maxbytes; 262 261 263 - spin_lock(&user->lock); 262 + spin_lock_irqsave(&user->lock, irqflags); 264 263 if (!(flags & KEY_ALLOC_QUOTA_OVERRUN)) { 265 264 if (user->qnkeys + 1 > maxkeys || 266 265 user->qnbytes + quotalen > maxbytes || ··· 270 269 271 270 user->qnkeys++; 272 271 user->qnbytes += quotalen; 273 - spin_unlock(&user->lock); 272 + spin_unlock_irqrestore(&user->lock, irqflags); 274 273 } 275 274 276 275 /* allocate and initialise the key and its description */ ··· 328 327 kfree(key->description); 329 328 kmem_cache_free(key_jar, key); 330 329 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) { 331 - spin_lock(&user->lock); 330 + spin_lock_irqsave(&user->lock, irqflags); 332 331 user->qnkeys--; 333 332 user->qnbytes -= quotalen; 334 - spin_unlock(&user->lock); 333 + spin_unlock_irqrestore(&user->lock, irqflags); 335 334 } 336 335 key_user_put(user); 337 336 key = ERR_PTR(ret); ··· 341 340 kmem_cache_free(key_jar, key); 342 341 no_memory_2: 343 342 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) { 344 - spin_lock(&user->lock); 343 + spin_lock_irqsave(&user->lock, irqflags); 345 344 user->qnkeys--; 346 345 user->qnbytes -= quotalen; 347 - spin_unlock(&user->lock); 346 + spin_unlock_irqrestore(&user->lock, irqflags); 348 347 } 349 348 key_user_put(user); 350 349 no_memory_1: ··· 352 351 goto error; 353 352 354 353 no_quota: 355 - spin_unlock(&user->lock); 354 + spin_unlock_irqrestore(&user->lock, irqflags); 356 355 key_user_put(user); 357 356 key = ERR_PTR(-EDQUOT); 358 357 goto error; ··· 381 380 if (delta != 0 && test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) { 382 381 unsigned maxbytes = uid_eq(key->user->uid, GLOBAL_ROOT_UID) ? 383 382 key_quota_root_maxbytes : key_quota_maxbytes; 383 + unsigned long flags; 384 384 385 - spin_lock(&key->user->lock); 385 + spin_lock_irqsave(&key->user->lock, flags); 386 386 387 387 if (delta > 0 && 388 388 (key->user->qnbytes + delta > maxbytes || ··· 394 392 key->user->qnbytes += delta; 395 393 key->quotalen += delta; 396 394 } 397 - spin_unlock(&key->user->lock); 395 + spin_unlock_irqrestore(&key->user->lock, flags); 398 396 } 399 397 400 398 /* change the recorded data length if that didn't generate an error */ ··· 465 463 if (authkey) 466 464 key_invalidate(authkey); 467 465 468 - key_set_expiry(key, prep->expiry); 466 + if (prep->expiry != TIME64_MAX) 467 + key_set_expiry(key, prep->expiry); 469 468 } 470 469 } 471 470 ··· 648 645 if (key) { 649 646 key_check(key); 650 647 651 - if (refcount_dec_and_test(&key->usage)) 648 + if (refcount_dec_and_test(&key->usage)) { 649 + unsigned long flags; 650 + 651 + /* deal with the user's key tracking and quota */ 652 + if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) { 653 + spin_lock_irqsave(&key->user->lock, flags); 654 + key->user->qnkeys--; 655 + key->user->qnbytes -= key->quotalen; 656 + spin_unlock_irqrestore(&key->user->lock, flags); 657 + } 652 658 schedule_work(&key_gc_work); 659 + } 653 660 } 654 661 } 655 662 EXPORT_SYMBOL(key_put);
+6 -5
security/keys/keyctl.c
··· 954 954 long ret; 955 955 kuid_t uid; 956 956 kgid_t gid; 957 + unsigned long flags; 957 958 958 959 uid = make_kuid(current_user_ns(), user); 959 960 gid = make_kgid(current_user_ns(), group); ··· 1011 1010 unsigned maxbytes = uid_eq(uid, GLOBAL_ROOT_UID) ? 1012 1011 key_quota_root_maxbytes : key_quota_maxbytes; 1013 1012 1014 - spin_lock(&newowner->lock); 1013 + spin_lock_irqsave(&newowner->lock, flags); 1015 1014 if (newowner->qnkeys + 1 > maxkeys || 1016 1015 newowner->qnbytes + key->quotalen > maxbytes || 1017 1016 newowner->qnbytes + key->quotalen < ··· 1020 1019 1021 1020 newowner->qnkeys++; 1022 1021 newowner->qnbytes += key->quotalen; 1023 - spin_unlock(&newowner->lock); 1022 + spin_unlock_irqrestore(&newowner->lock, flags); 1024 1023 1025 - spin_lock(&key->user->lock); 1024 + spin_lock_irqsave(&key->user->lock, flags); 1026 1025 key->user->qnkeys--; 1027 1026 key->user->qnbytes -= key->quotalen; 1028 - spin_unlock(&key->user->lock); 1027 + spin_unlock_irqrestore(&key->user->lock, flags); 1029 1028 } 1030 1029 1031 1030 atomic_dec(&key->user->nkeys); ··· 1057 1056 return ret; 1058 1057 1059 1058 quota_overrun: 1060 - spin_unlock(&newowner->lock); 1059 + spin_unlock_irqrestore(&newowner->lock, flags); 1061 1060 zapowner = newowner; 1062 1061 ret = -EDQUOT; 1063 1062 goto error_put;