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

Configure Feed

Select the types of activity you want to include in your feed.

dm-verity: add dm-verity keyring

Add a dedicated ".dm-verity" keyring for root hash signature
verification, similar to the ".fs-verity" keyring used by fs-verity.

By default the keyring is unused retaining the exact same old behavior.
For systems that provision additional keys only intended for dm-verity
images during boot, the dm_verity.keyring_unsealed=1 kernel parameter
leaves the keyring open.

We want to use this in systemd as a way add keys during boot that are
only used for creating dm-verity devices for later mounting and nothing
else. The discoverable disk image (DDI) spec at [1] heavily relies on
dm-verity and we would like to expand this even more. This will allow us
to do that in a fully backward compatible way.

Once provisioning is complete, userspace restricts and activates it for
dm-verity verification. If userspace fully seals the keyring then it
gains the guarantee that no new keys can be added.

Link: https://uapi-group.org/specifications/specs/discoverable_partitions_specification [1]
Co-developed-by: Aleksa Sarai <cyphar@cyphar.com>
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>

authored by

Christian Brauner and committed by
Mikulas Patocka
033724b1 fb8a6c18

+89 -1
+7
Documentation/admin-guide/kernel-parameters.txt
··· 1370 1370 For details see: 1371 1371 Documentation/admin-guide/hw-vuln/reg-file-data-sampling.rst 1372 1372 1373 + dm_verity.keyring_unsealed= 1374 + [KNL] When set to 1, leave the dm-verity keyring 1375 + unsealed after initialization so userspace can 1376 + provision keys. Once the keyring is restricted 1377 + it becomes active and is searched during signature 1378 + verification. 1379 + 1373 1380 driver_async_probe= [KNL] 1374 1381 List of driver names to be probed asynchronously. * 1375 1382 matches with all driver names. If * is specified, the
+25 -1
drivers/md/dm-verity-target.c
··· 1802 1802 .preresume = verity_preresume, 1803 1803 #endif /* CONFIG_SECURITY */ 1804 1804 }; 1805 - module_dm(verity); 1805 + 1806 + static int __init dm_verity_init(void) 1807 + { 1808 + int r; 1809 + 1810 + r = dm_verity_verify_sig_init(); 1811 + if (r) 1812 + return r; 1813 + 1814 + r = dm_register_target(&verity_target); 1815 + if (r) { 1816 + dm_verity_verify_sig_exit(); 1817 + return r; 1818 + } 1819 + 1820 + return 0; 1821 + } 1822 + module_init(dm_verity_init); 1823 + 1824 + static void __exit dm_verity_exit(void) 1825 + { 1826 + dm_unregister_target(&verity_target); 1827 + dm_verity_verify_sig_exit(); 1828 + } 1829 + module_exit(dm_verity_exit); 1806 1830 1807 1831 /* 1808 1832 * Check whether a DM target is a verity target.
+45
drivers/md/dm-verity-verify-sig.c
··· 7 7 */ 8 8 #include <linux/device-mapper.h> 9 9 #include <linux/verification.h> 10 + #include <linux/key.h> 10 11 #include <keys/user-type.h> 11 12 #include <linux/module.h> 12 13 #include "dm-verity.h" 13 14 #include "dm-verity-verify-sig.h" 14 15 15 16 #define DM_VERITY_VERIFY_ERR(s) DM_VERITY_ROOT_HASH_VERIFICATION " " s 17 + 18 + static struct key *dm_verity_keyring; 19 + 20 + static bool dm_verity_keyring_unsealed __ro_after_init; 21 + module_param_named(keyring_unsealed, dm_verity_keyring_unsealed, bool, 0444); 22 + MODULE_PARM_DESC(keyring_unsealed, "Leave the dm-verity keyring unsealed"); 16 23 17 24 static bool require_signatures; 18 25 module_param(require_signatures, bool, 0444); ··· 150 143 VERIFYING_UNSPECIFIED_SIGNATURE, NULL, NULL); 151 144 #endif 152 145 146 + if (ret != -ENOKEY && ret != -EKEYREJECTED) 147 + return ret; 148 + 149 + if (dm_verity_keyring->keys.nr_leaves_on_tree && 150 + dm_verity_keyring->restrict_link) 151 + ret = verify_pkcs7_signature(root_hash, root_hash_len, 152 + sig_data, sig_len, 153 + dm_verity_keyring, 154 + VERIFYING_UNSPECIFIED_SIGNATURE, 155 + NULL, NULL); 156 + 153 157 return ret; 154 158 } 155 159 ··· 169 151 kfree(sig_opts->sig); 170 152 sig_opts->sig = NULL; 171 153 sig_opts->sig_size = 0; 154 + } 155 + 156 + int __init dm_verity_verify_sig_init(void) 157 + { 158 + dm_verity_keyring = keyring_alloc(".dm-verity", 159 + GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, 160 + current_cred(), 161 + KEY_POS_SEARCH | 162 + KEY_USR_VIEW | KEY_USR_READ | 163 + KEY_USR_WRITE | KEY_USR_SEARCH | 164 + KEY_USR_SETATTR, 165 + KEY_ALLOC_NOT_IN_QUOTA, 166 + NULL, NULL); 167 + if (IS_ERR(dm_verity_keyring)) 168 + panic("dm-verity can't allocate keyring\n"); 169 + 170 + if (!dm_verity_keyring_unsealed && 171 + keyring_restrict(make_key_ref(dm_verity_keyring, true), NULL, NULL)) 172 + panic("dm-verity can't seal keyring\n"); 173 + 174 + return 0; 175 + } 176 + 177 + void __exit dm_verity_verify_sig_exit(void) 178 + { 179 + key_revoke(dm_verity_keyring); 180 + key_put(dm_verity_keyring); 172 181 }
+12
drivers/md/dm-verity-verify-sig.h
··· 30 30 31 31 void verity_verify_sig_opts_cleanup(struct dm_verity_sig_opts *sig_opts); 32 32 33 + int __init dm_verity_verify_sig_init(void); 34 + void __exit dm_verity_verify_sig_exit(void); 35 + 33 36 #else 34 37 35 38 #define DM_VERITY_ROOT_HASH_VERIFICATION_OPTS 0 ··· 56 53 } 57 54 58 55 static inline void verity_verify_sig_opts_cleanup(struct dm_verity_sig_opts *sig_opts) 56 + { 57 + } 58 + 59 + static inline int dm_verity_verify_sig_init(void) 60 + { 61 + return 0; 62 + } 63 + 64 + static inline void dm_verity_verify_sig_exit(void) 59 65 { 60 66 } 61 67