vfs-7.4-rc1.keyring

Please consider pulling these changes from the signed vfs-7.4-rc1.keyring tag.
 
 Thanks!
 Christian
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCatyIKQAKCRCRxhvAZXjc
 ogjWAQD1no3bS2OTeI91M1KGxwm4XoqBwg5DaRtW9SG1I284CgEA/lRwCMBT6Op7
 on+ebYhp9krrycMx5n1xGDhL0lm+zg4=
 =5miC
 -----END PGP SIGNATURE-----

Merge tag 'vfs-7.4-rc1.keyring' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull vfs keyring updates from Christian Brauner:
 "The kernel has two keyrings that userspace fills with X.509
  certificates at boot: .fs-verity for fs-verity built-in signatures
  and .dm-verity for dm-verity root hash signatures.

  Neither is linked into any process keyring. Hence, request_key() and
  KEYCTL_SEARCH can't find them. The only way for userspace to identify
  them is to read their serial number out of /proc/keys. That is not
  just a large file often the names can also be reused and appear
  multiple times which allows forging these keyrings.

  This adds two fixed special key ids, KEY_SPEC_DM_VERITY_KEYRING and
  KEY_SPEC_FS_VERITY_KEYRING next to KEY_SPEC_BPF_KEYRING. The latter
  went in through bpf-next this merge window.

  lookup_user_key() resolves the fixed key ids to the two keyrings. So
  userspace can add a dm-verity (fixed keyring id: -10) certificate with

	keyctl padd asymmetric "" -10 < cert.der

  and seal the keyring with

	keyctl restrict_keyring -10

  without looking anything up first"

* tag 'vfs-7.4-rc1.keyring' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
  Documentation: keys: document IDs added since KEY_SPEC_REQKEY_AUTH_KEY
  keys: add KEY_SPEC_FS_VERITY_KEYRING
  keys: add KEY_SPEC_DM_VERITY_KEYRING
This commit is contained in:
Linus Torvalds 2026-10-27 08:01:30 -10:00
commit 62c4575285
6 changed files with 80 additions and 0 deletions

View File

@ -372,6 +372,19 @@ process making the call::
KEY_SPEC_GROUP_KEYRING -6 GID-specific keyring
KEY_SPEC_REQKEY_AUTH_KEY -7 assumed request_key()
authorisation key
KEY_SPEC_REQUESTOR_KEYRING -8 request_key() destination
keyring
There are also values that refer to a specific kernel keyring rather than to
anything belonging to the caller. These keyrings are not linked into any
keyring, so a search cannot reach them and the ID is the only way to name
one::
CONSTANT VALUE KEY REFERENCED
============================== ====== ===========================
KEY_SPEC_BPF_KEYRING -9 the ".bpf" keyring
KEY_SPEC_DM_VERITY_KEYRING -10 the ".dm-verity" keyring
KEY_SPEC_FS_VERITY_KEYRING -11 the ".fs-verity" keyring
The main syscalls are:

View File

@ -189,11 +189,14 @@ int __init dm_verity_verify_sig_init(void)
keyring_restrict(make_key_ref(dm_verity_keyring, true), NULL, NULL))
panic("dm-verity can't seal keyring\n");
key_register_dm_verity_keyring(dm_verity_keyring);
return 0;
}
void dm_verity_verify_sig_exit(void)
{
key_register_dm_verity_keyring(NULL);
key_revoke(dm_verity_keyring);
key_put(dm_verity_keyring);
}

View File

@ -135,4 +135,6 @@ void __init fsverity_init_signature(void)
KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
if (IS_ERR(fsverity_keyring))
panic("failed to allocate \".fs-verity\" keyring");
key_register_fs_verity_keyring(fsverity_keyring);
}

View File

@ -446,6 +446,8 @@ extern int keyring_restrict(key_ref_t keyring, const char *type,
const char *restriction);
extern void key_register_bpf_keyring(struct key *keyring);
extern void key_register_dm_verity_keyring(struct key *keyring);
extern void key_register_fs_verity_keyring(struct key *keyring);
extern struct key *key_lookup(key_serial_t id);

View File

@ -25,6 +25,8 @@
#define KEY_SPEC_REQKEY_AUTH_KEY -7 /* - key ID for assumed request_key auth key */
#define KEY_SPEC_REQUESTOR_KEYRING -8 /* - key ID for request_key() dest keyring */
#define KEY_SPEC_BPF_KEYRING -9 /* - key ID for the BPF-specific keyring */
#define KEY_SPEC_DM_VERITY_KEYRING -10 /* - key ID for the .dm-verity keyring */
#define KEY_SPEC_FS_VERITY_KEYRING -11 /* - key ID for the .fs-verity keyring */
/* request-key default keyrings */
#define KEY_REQKEY_DEFL_NO_CHANGE -1

View File

@ -25,6 +25,13 @@ static DEFINE_MUTEX(key_session_mutex);
/* BPF keyring reachable through KEY_SPEC_BPF_KEYRING */
static struct key *bpf_keyring __ro_after_init;
/* dm-verity keyring reachable through KEY_SPEC_DM_VERITY_KEYRING */
static struct key *dm_verity_keyring;
static DEFINE_SPINLOCK(dm_verity_keyring_lock);
/* fs-verity keyring reachable through KEY_SPEC_FS_VERITY_KEYRING */
static struct key *fs_verity_keyring __ro_after_init;
/* The root user's tracking struct */
struct key_user root_key_user = {
.usage = REFCOUNT_INIT(3),
@ -606,6 +613,38 @@ void key_register_bpf_keyring(struct key *keyring)
bpf_keyring = keyring;
}
/**
* key_register_dm_verity_keyring - Publish the keyring for KEY_SPEC_DM_VERITY_KEYRING
* @keyring: The keyring to publish, or NULL to withdraw it
*
* Make @keyring reachable by userspace through the KEY_SPEC_DM_VERITY_KEYRING
* special key ID, so that provisioning it does not require scraping its
* serial out of /proc/keys first. dm-verity can be unloaded as a module
* and the keyring deregistered, as such serialize access with
* dm_verity_keyring_lock.
*/
void key_register_dm_verity_keyring(struct key *keyring)
{
spin_lock(&dm_verity_keyring_lock);
dm_verity_keyring = keyring;
spin_unlock(&dm_verity_keyring_lock);
}
EXPORT_SYMBOL_GPL(key_register_dm_verity_keyring);
/**
* key_register_fs_verity_keyring - Publish the keyring for KEY_SPEC_FS_VERITY_KEYRING
* @keyring: The keyring to publish
*
* Make @keyring reachable by userspace through the KEY_SPEC_FS_VERITY_KEYRING
* special key ID, so that provisioning it does not require scraping its
* serial out of /proc/keys first. Called once, from an initcall, and never
* undone.
*/
void key_register_fs_verity_keyring(struct key *keyring)
{
fs_verity_keyring = keyring;
}
/*
* Look up a key ID given us by userspace with a given permissions mask to get
* the key it refers to.
@ -765,6 +804,25 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
key_ref = make_key_ref(key, 0);
break;
case KEY_SPEC_DM_VERITY_KEYRING:
spin_lock(&dm_verity_keyring_lock);
key = dm_verity_keyring;
if (key)
__key_get(key);
spin_unlock(&dm_verity_keyring_lock);
if (!key)
goto error;
key_ref = make_key_ref(key, 0);
break;
case KEY_SPEC_FS_VERITY_KEYRING:
key = fs_verity_keyring;
if (!key)
goto error;
__key_get(key);
key_ref = make_key_ref(key, 0);
break;
default:
key_ref = ERR_PTR(-EINVAL);
if (id < 1)