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.

certs: Make blacklist_vet_description() more strict

Before exposing this new key type to user space, make sure that only
meaningful blacklisted hashes are accepted. This is also checked for
builtin blacklisted hashes, but a following commit make sure that the
user will notice (at built time) and will fix the configuration if it
already included errors.

Check that a blacklist key description starts with a valid prefix and
then a valid hexadecimal string.

Cc: David Howells <dhowells@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Eric Snowberg <eric.snowberg@oracle.com>
Signed-off-by: Mickaël Salaün <mic@linux.microsoft.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20210712170313.884724-4-mic@digikod.net
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>

authored by

Mickaël Salaün and committed by
Jarkko Sakkinen
bf21dc59 141e5239

+35 -9
+35 -9
certs/blacklist.c
··· 19 19 #include "blacklist.h" 20 20 #include "common.h" 21 21 22 + /* 23 + * According to crypto/asymmetric_keys/x509_cert_parser.c:x509_note_pkey_algo(), 24 + * the size of the currently longest supported hash algorithm is 512 bits, 25 + * which translates into 128 hex characters. 26 + */ 27 + #define MAX_HASH_LEN 128 28 + 29 + static const char tbs_prefix[] = "tbs"; 30 + static const char bin_prefix[] = "bin"; 31 + 22 32 static struct key *blacklist_keyring; 23 33 24 34 #ifdef CONFIG_SYSTEM_REVOCATION_LIST ··· 42 32 */ 43 33 static int blacklist_vet_description(const char *desc) 44 34 { 45 - int n = 0; 35 + int i, prefix_len, tbs_step = 0, bin_step = 0; 46 36 47 - if (*desc == ':') 48 - return -EINVAL; 49 - for (; *desc; desc++) 50 - if (*desc == ':') 51 - goto found_colon; 37 + /* The following algorithm only works if prefix lengths match. */ 38 + BUILD_BUG_ON(sizeof(tbs_prefix) != sizeof(bin_prefix)); 39 + prefix_len = sizeof(tbs_prefix) - 1; 40 + for (i = 0; *desc; desc++, i++) { 41 + if (*desc == ':') { 42 + if (tbs_step == prefix_len) 43 + goto found_colon; 44 + if (bin_step == prefix_len) 45 + goto found_colon; 46 + return -EINVAL; 47 + } 48 + if (i >= prefix_len) 49 + return -EINVAL; 50 + if (*desc == tbs_prefix[i]) 51 + tbs_step++; 52 + if (*desc == bin_prefix[i]) 53 + bin_step++; 54 + } 52 55 return -EINVAL; 53 56 54 57 found_colon: 55 58 desc++; 56 - for (; *desc; desc++) { 59 + for (i = 0; *desc && i < MAX_HASH_LEN; desc++, i++) { 57 60 if (!isxdigit(*desc) || isupper(*desc)) 58 61 return -EINVAL; 59 - n++; 60 62 } 63 + if (*desc) 64 + /* The hash is greater than MAX_HASH_LEN. */ 65 + return -ENOPKG; 61 66 62 - if (n == 0 || n & 1) 67 + /* Checks for an even number of hexadecimal characters. */ 68 + if (i == 0 || i & 1) 63 69 return -EINVAL; 64 70 return 0; 65 71 }