KEYS: Fix key_reject_and_link() race with keyring restriction

The restrict_link check in key_reject_and_link() is done before taking
the keyring semaphore, racing with a concurrent keyring_restrict()
that installs the restriction while holding the semaphore in write
mode.

Move the check to after __key_link_lock(), so it is done under the
semaphore, matching the pattern used in __key_create_or_update().

Cc: stable@vger.kernel.org
Fixes: 5ac7eace2d ("KEYS: Add a facility to restrict new links into a keyring")
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Adrian Martinez <adrimg3196@gmail.com>
Link: https://lore.kernel.org/r/CACO1+RT+m==BY+ZPkE+fo536D0qu3wog4xE1dfuXQ56g+=Qv=A@mail.gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
This commit is contained in:
Adrian Martinez 2026-10-10 23:40:00 +03:00 committed by Jarkko Sakkinen
parent 11077cbcc2
commit 0b157166e6

View File

@ -588,11 +588,18 @@ int key_reject_and_link(struct key *key,
ret = -EBUSY;
if (keyring) {
if (keyring->restrict_link)
return -EPERM;
link_ret = __key_link_lock(keyring, &key->index_key);
if (link_ret == 0) {
/*
* Check the restriction under the keyring semaphore.
* keyring_restrict() installs it while holding the
* semaphore, so testing it beforehand races with a
* concurrent restriction install.
*/
if (keyring->restrict_link) {
__key_link_end(keyring, &key->index_key, edit);
return -EPERM;
}
link_ret = __key_link_begin(keyring, &key->index_key, &edit);
if (link_ret < 0)
__key_link_end(keyring, &key->index_key, edit);