All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
Cc: linux-security-module@vger.kernel.org
Subject: Re: [PATCH] keys: Protect the read method check against type removal
Date: Sat, 17 Oct 2026 07:49:22 +0000	[thread overview]
Message-ID: <sashiko-outbox-175373@kernel.org> (raw)
In-Reply-To: <pm-key-management-objects-candidate-0010-v5-c6b7ca2813c6913e500a@gmail.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] keys: lockdep class use-after-free in keyctl_read_key() after type unload
--

commit 74db11a8500db2209c8e5cbb82e05cfc4e6396ee
Author: Cen Zhang <zzzccc427@gmail.com>

keys: Protect the read method check against type removal

This patch acquires key->sem for reading around the key->type->read check
in keyctl_read_key() so that a concurrent module unload and key garbage
collection pass cannot free the key type before the read pointer is
inspected.

> diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
> index d14ace88e529c..43a5a3c4d1352 100644
> --- a/security/keys/keyctl.c
> +++ b/security/keys/keyctl.c
> @@ -861,10 +861,13 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
>  
>  	/* the key is probably readable - now try to read it */
>  can_read_key:
> -	if (!key->type->read) {
> -		ret = -EOPNOTSUPP;
> +	down_read(&key->sem);
> +	ret = -EOPNOTSUPP;
> +	if (key->type->read)
> +		ret = 0;
> +	up_read(&key->sem);
> +	if (ret)
>  		goto key_put_out;
> -	}
>  
>  	if (!buffer || !buflen) {
>  		/* Get the key length from the read method */

[Severity: Medium]
With CONFIG_LOCKDEP enabled, can acquiring key->sem here trigger a
use-after-free on the lockdep class if the key's modular key_type has
already been unregistered and its module unloaded?

When the key is allocated in security/keys/key.c:key_alloc(), key->sem is
bound to the key type's lock_class in the module's data section:

    init_rwsem(&key->sem);
    lockdep_set_class(&key->sem, &type->lock_class);

If a reader task in keyctl_read_key() holds a reference to the key after
lookup_user_key() and is delayed before reaching can_read_key:, a
concurrent module unload can run unregister_key_type() ->
key_gc_keytype() -> key_garbage_collector() in security/keys/gc.c:

destroy_dead_key:
    spin_unlock(&key_serial_lock);
    kdebug("destroy key %d", key->serial);
    down_write(&key->sem);
    key->type = &key_type_dead;
    if (key_gc_dead_keytype->destroy)
        key_gc_dead_keytype->destroy(key);
    memset(&key->payload, KEY_DESTROY, sizeof(key->payload));
    up_write(&key->sem);

That down_write(&key->sem) populates key->sem.dep_map.class_cache[0] with
the module's lock_class, and key->type is switched to key_type_dead
without resetting the lockdep class on key->sem. Once
unregister_key_type() returns, free_module() -> lockdep_free_key_range()
-> zap_class() clears the class bit in lock_classes_in_use, sets
class->key = NULL, and queues the struct lock_class onto
free_lock_classes.

Previously, if retyping and module unload finished before can_read_key:,
keyctl_read_key() saw key_type_dead.read == NULL without taking key->sem.
With this change (or in __keyctl_read_key() if the module unloads after
can_read_key:), calling down_read(&key->sem) enters
kernel/locking/lockdep.c:__lock_acquire() with the dangling
key->sem.dep_map.class_cache[0] pointer:

    if (subclass < NR_LOCKDEP_CACHING_CLASSES)
        class = lock->class_cache[subclass];
    ...
    if (DEBUG_LOCKS_WARN_ON(!test_bit(class_idx, lock_classes_in_use)))
        return 0;

Could this hit DEBUG_LOCKS_WARN_ON(!test_bit(class_idx,
lock_classes_in_use)) or corrupt lockdep state if the lock_class entry
has been reallocated?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/pm-key-management-objects-candidate-0010-v5-c6b7ca2813c6913e500a@gmail.com?part=1

      reply	other threads:[~2026-10-17  7:49 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-17  7:30 [PATCH] keys: Protect the read method check against type removal Cen Zhang
2026-10-17  7:49 ` sashiko-bot [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=sashiko-outbox-175373@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.