diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/device_cgroup.c | 3 | ||||
-rw-r--r-- | security/integrity/digsig_asymmetric.c | 14 | ||||
-rw-r--r-- | security/integrity/platform_certs/load_uefi.c | 85 | ||||
-rw-r--r-- | security/keys/compat.c | 37 | ||||
-rw-r--r-- | security/keys/internal.h | 5 | ||||
-rw-r--r-- | security/keys/keyctl.c | 2 |
6 files changed, 82 insertions, 64 deletions
diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 43ab0ad45c1b..04375df52fc9 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c @@ -354,7 +354,8 @@ static bool match_exception_partial(struct list_head *exceptions, short type, { struct dev_exception_item *ex; - list_for_each_entry_rcu(ex, exceptions, list) { + list_for_each_entry_rcu(ex, exceptions, list, + lockdep_is_held(&devcgroup_mutex)) { if ((type & DEVCG_DEV_BLOCK) && !(ex->type & DEVCG_DEV_BLOCK)) continue; if ((type & DEVCG_DEV_CHAR) && !(ex->type & DEVCG_DEV_CHAR)) diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c index cfa4127d0518..b86a4a8f61ab 100644 --- a/security/integrity/digsig_asymmetric.c +++ b/security/integrity/digsig_asymmetric.c @@ -99,14 +99,22 @@ int asymmetric_verify(struct key *keyring, const char *sig, memset(&pks, 0, sizeof(pks)); pks.hash_algo = hash_algo_name[hdr->hash_algo]; - if (hdr->hash_algo == HASH_ALGO_STREEBOG_256 || - hdr->hash_algo == HASH_ALGO_STREEBOG_512) { + switch (hdr->hash_algo) { + case HASH_ALGO_STREEBOG_256: + case HASH_ALGO_STREEBOG_512: /* EC-RDSA and Streebog should go together. */ pks.pkey_algo = "ecrdsa"; pks.encoding = "raw"; - } else { + break; + case HASH_ALGO_SM3_256: + /* SM2 and SM3 should go together. */ + pks.pkey_algo = "sm2"; + pks.encoding = "raw"; + break; + default: pks.pkey_algo = "rsa"; pks.encoding = "pkcs1"; + break; } pks.digest = (u8 *)data; pks.digest_size = datalen; diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c index 253fb9a7fc98..ee4b4c666854 100644 --- a/security/integrity/platform_certs/load_uefi.c +++ b/security/integrity/platform_certs/load_uefi.c @@ -66,6 +66,65 @@ static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, } /* + * load_moklist_certs() - Load MokList certs + * + * Load the certs contained in the UEFI MokListRT database into the + * platform trusted keyring. + * + * This routine checks the EFI MOK config table first. If and only if + * that fails, this routine uses the MokListRT ordinary UEFI variable. + * + * Return: Status + */ +static int __init load_moklist_certs(void) +{ + struct efi_mokvar_table_entry *mokvar_entry; + efi_guid_t mok_var = EFI_SHIM_LOCK_GUID; + void *mok; + unsigned long moksize; + efi_status_t status; + int rc; + + /* First try to load certs from the EFI MOKvar config table. + * It's not an error if the MOKvar config table doesn't exist + * or the MokListRT entry is not found in it. + */ + mokvar_entry = efi_mokvar_entry_find("MokListRT"); + if (mokvar_entry) { + rc = parse_efi_signature_list("UEFI:MokListRT (MOKvar table)", + mokvar_entry->data, + mokvar_entry->data_size, + get_handler_for_db); + /* All done if that worked. */ + if (!rc) + return rc; + + pr_err("Couldn't parse MokListRT signatures from EFI MOKvar config table: %d\n", + rc); + } + + /* Get MokListRT. It might not exist, so it isn't an error + * if we can't get it. + */ + mok = get_cert_list(L"MokListRT", &mok_var, &moksize, &status); + if (mok) { + rc = parse_efi_signature_list("UEFI:MokListRT", + mok, moksize, get_handler_for_db); + kfree(mok); + if (rc) + pr_err("Couldn't parse MokListRT signatures: %d\n", rc); + return rc; + } + if (status == EFI_NOT_FOUND) + pr_debug("MokListRT variable wasn't found\n"); + else + pr_info("Couldn't get UEFI MokListRT\n"); + return 0; +} + +/* + * load_uefi_certs() - Load certs from UEFI sources + * * Load the certs contained in the UEFI databases into the platform trusted * keyring and the UEFI blacklisted X.509 cert SHA256 hashes into the blacklist * keyring. @@ -73,17 +132,16 @@ static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, static int __init load_uefi_certs(void) { efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID; - efi_guid_t mok_var = EFI_SHIM_LOCK_GUID; - void *db = NULL, *dbx = NULL, *mok = NULL; - unsigned long dbsize = 0, dbxsize = 0, moksize = 0; + void *db = NULL, *dbx = NULL; + unsigned long dbsize = 0, dbxsize = 0; efi_status_t status; int rc = 0; if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) return false; - /* Get db, MokListRT, and dbx. They might not exist, so it isn't - * an error if we can't get them. + /* Get db and dbx. They might not exist, so it isn't an error + * if we can't get them. */ if (!uefi_check_ignore_db()) { db = get_cert_list(L"db", &secure_var, &dbsize, &status); @@ -102,20 +160,6 @@ static int __init load_uefi_certs(void) } } - mok = get_cert_list(L"MokListRT", &mok_var, &moksize, &status); - if (!mok) { - if (status == EFI_NOT_FOUND) - pr_debug("MokListRT variable wasn't found\n"); - else - pr_info("Couldn't get UEFI MokListRT\n"); - } else { - rc = parse_efi_signature_list("UEFI:MokListRT", - mok, moksize, get_handler_for_db); - if (rc) - pr_err("Couldn't parse MokListRT signatures: %d\n", rc); - kfree(mok); - } - dbx = get_cert_list(L"dbx", &secure_var, &dbxsize, &status); if (!dbx) { if (status == EFI_NOT_FOUND) @@ -131,6 +175,9 @@ static int __init load_uefi_certs(void) kfree(dbx); } + /* Load the MokListRT certs */ + rc = load_moklist_certs(); + return rc; } late_initcall(load_uefi_certs); diff --git a/security/keys/compat.c b/security/keys/compat.c index 6ee9d8f6a4a5..1545efdca562 100644 --- a/security/keys/compat.c +++ b/security/keys/compat.c @@ -12,39 +12,6 @@ #include "internal.h" /* - * Instantiate a key with the specified compatibility multipart payload and - * link the key into the destination keyring if one is given. - * - * The caller must have the appropriate instantiation permit set for this to - * work (see keyctl_assume_authority). No other permissions are required. - * - * If successful, 0 will be returned. - */ -static long compat_keyctl_instantiate_key_iov( - key_serial_t id, - const struct compat_iovec __user *_payload_iov, - unsigned ioc, - key_serial_t ringid) -{ - struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; - struct iov_iter from; - long ret; - - if (!_payload_iov) - ioc = 0; - - ret = compat_import_iovec(WRITE, _payload_iov, ioc, - ARRAY_SIZE(iovstack), &iov, - &from); - if (ret < 0) - return ret; - - ret = keyctl_instantiate_key_common(id, &from, ringid); - kfree(iov); - return ret; -} - -/* * The key control system call, 32-bit compatibility version for 64-bit archs */ COMPAT_SYSCALL_DEFINE5(keyctl, u32, option, @@ -114,8 +81,8 @@ COMPAT_SYSCALL_DEFINE5(keyctl, u32, option, return keyctl_reject_key(arg2, arg3, arg4, arg5); case KEYCTL_INSTANTIATE_IOV: - return compat_keyctl_instantiate_key_iov( - arg2, compat_ptr(arg3), arg4, arg5); + return keyctl_instantiate_key_iov(arg2, compat_ptr(arg3), arg4, + arg5); case KEYCTL_INVALIDATE: return keyctl_invalidate_key(arg2); diff --git a/security/keys/internal.h b/security/keys/internal.h index 338a526cbfa5..9b9cf3b6fcbb 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h @@ -262,11 +262,6 @@ extern long keyctl_instantiate_key_iov(key_serial_t, const struct iovec __user *, unsigned, key_serial_t); extern long keyctl_invalidate_key(key_serial_t); - -struct iov_iter; -extern long keyctl_instantiate_key_common(key_serial_t, - struct iov_iter *, - key_serial_t); extern long keyctl_restrict_keyring(key_serial_t id, const char __user *_type, const char __user *_restriction); diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 9febd37a168f..e26bbccda7cc 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -1164,7 +1164,7 @@ static int keyctl_change_reqkey_auth(struct key *key) * * If successful, 0 will be returned. */ -long keyctl_instantiate_key_common(key_serial_t id, +static long keyctl_instantiate_key_common(key_serial_t id, struct iov_iter *from, key_serial_t ringid) { |