mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
keys: add KEY_SPEC_DM_VERITY_KEYRING
The .dm-verity keyring is not linked into any process keyring, so
request_key() and KEYCTL_SEARCH cannot find it. Userspace has to scrape
/proc/keys for the serial to use.
That's not great, one could put in a bogus description containing
a newline to confuse userspace further. For example, thanks to AI
models, which I run as root but you could show off as any old user:
# DESC=$'.dm-verity: 1\n0badf00d I--Q--- 1 perm 082f0000 0 0 keyring .dm-verity'
# k=$(echo -n "1234567" | keyctl padd user "$DESC" @s)
# keyctl setperm "$k" 0x3f010001
# cat /proc/keys | grep dm-verity
10402023 I------ 2 perm 082f0000 0 0 keyring .dm-verity: empty
12e0bee6 I--Q--- 1 perm 3f010001 0 0 user .dm-verity: 1
0badf00d I--Q--- 1 perm 082f0000 0 0 keyring .dm-verity: 7
0x0badf00d is not a keyring, it is the text inside our user's key
description. Telling the two apart needs a KEYCTL_DESCRIBE per row
which is annoying to do. i.e.:
# keyctl rdescribe 0x10402023
keyring;0;0;082f0000;.dm-verity
# keyctl rdescribe 0x0badf00d
keyctl_describe: Required key not available
Let's just give it a well known identifier, i.e.:
# keyctl rdescribe -10
keyring;0;0;082f0000;.dm-verity
This is exactly what
commit 264d8fd279 ("bpf, keys: Add a bpf keyring for program signature validation")
did, and was the inspiration for this commit minus the spinlock bits
required due to dm-verity being a module.
Suggested-by: Christian Brauner (Amutable) <brauner@kernel.org>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Reviewed-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Andrew Halaney <andrew@amutable.com>
Link: https://patch.msgid.link/20261008-ajhalaney-dmverity-key-identifier-v2-1-008456d189cb@amutable.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
This commit is contained in:
parent
592d26f625
commit
1041fca2ee
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -441,6 +441,7 @@ 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 struct key *key_lookup(key_serial_t id);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#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 */
|
||||
|
||||
/* request-key default keyrings */
|
||||
#define KEY_REQKEY_DEFL_NO_CHANGE -1
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ 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);
|
||||
|
||||
/* The root user's tracking struct */
|
||||
struct key_user root_key_user = {
|
||||
.usage = REFCOUNT_INIT(3),
|
||||
|
|
@ -607,6 +611,24 @@ 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);
|
||||
|
||||
/*
|
||||
* Look up a key ID given us by userspace with a given permissions mask to get
|
||||
* the key it refers to.
|
||||
|
|
@ -766,6 +788,17 @@ 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;
|
||||
|
||||
default:
|
||||
key_ref = ERR_PTR(-EINVAL);
|
||||
if (id < 1)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user