| From f2b3dee484f9cee967a54ef05a66866282337519 Mon Sep 17 00:00:00 2001 |
| From: Mimi Zohar <zohar@linux.vnet.ibm.com> |
| Date: Wed, 11 Feb 2015 07:33:34 -0500 |
| Subject: KEYS: fix "ca_keys=" partial key matching |
| |
| From: Mimi Zohar <zohar@linux.vnet.ibm.com> |
| |
| commit f2b3dee484f9cee967a54ef05a66866282337519 upstream. |
| |
| The call to asymmetric_key_hex_to_key_id() from ca_keys_setup() |
| silently fails with -ENOMEM. Instead of dynamically allocating |
| memory from a __setup function, this patch defines a variable |
| and calls __asymmetric_key_hex_to_key_id(), a new helper function, |
| directly. |
| |
| This bug was introduced by 'commit 46963b774d44 ("KEYS: Overhaul |
| key identification when searching for asymmetric keys")'. |
| |
| Changelog: |
| - for clarification, rename hexlen to asciihexlen in |
| asymmetric_key_hex_to_key_id() |
| - add size argument to __asymmetric_key_hex_to_key_id() - David Howells |
| - inline __asymmetric_key_hex_to_key_id() - David Howells |
| - remove duplicate strlen() calls |
| |
| Acked-by: David Howells <dhowells@redhat.com> |
| Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| crypto/asymmetric_keys/asymmetric_keys.h | 3 +++ |
| crypto/asymmetric_keys/asymmetric_type.c | 20 ++++++++++++++------ |
| crypto/asymmetric_keys/x509_public_key.c | 23 ++++++++++++++++++----- |
| 3 files changed, 35 insertions(+), 11 deletions(-) |
| |
| --- a/crypto/asymmetric_keys/asymmetric_keys.h |
| +++ b/crypto/asymmetric_keys/asymmetric_keys.h |
| @@ -11,6 +11,9 @@ |
| |
| extern struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id); |
| |
| +extern int __asymmetric_key_hex_to_key_id(const char *id, |
| + struct asymmetric_key_id *match_id, |
| + size_t hexlen); |
| static inline |
| const struct asymmetric_key_ids *asymmetric_key_ids(const struct key *key) |
| { |
| --- a/crypto/asymmetric_keys/asymmetric_type.c |
| +++ b/crypto/asymmetric_keys/asymmetric_type.c |
| @@ -104,6 +104,15 @@ static bool asymmetric_match_key_ids( |
| return false; |
| } |
| |
| +/* helper function can be called directly with pre-allocated memory */ |
| +inline int __asymmetric_key_hex_to_key_id(const char *id, |
| + struct asymmetric_key_id *match_id, |
| + size_t hexlen) |
| +{ |
| + match_id->len = hexlen; |
| + return hex2bin(match_id->data, id, hexlen); |
| +} |
| + |
| /** |
| * asymmetric_key_hex_to_key_id - Convert a hex string into a key ID. |
| * @id: The ID as a hex string. |
| @@ -111,21 +120,20 @@ static bool asymmetric_match_key_ids( |
| struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id) |
| { |
| struct asymmetric_key_id *match_id; |
| - size_t hexlen; |
| + size_t asciihexlen; |
| int ret; |
| |
| if (!*id) |
| return ERR_PTR(-EINVAL); |
| - hexlen = strlen(id); |
| - if (hexlen & 1) |
| + asciihexlen = strlen(id); |
| + if (asciihexlen & 1) |
| return ERR_PTR(-EINVAL); |
| |
| - match_id = kmalloc(sizeof(struct asymmetric_key_id) + hexlen / 2, |
| + match_id = kmalloc(sizeof(struct asymmetric_key_id) + asciihexlen / 2, |
| GFP_KERNEL); |
| if (!match_id) |
| return ERR_PTR(-ENOMEM); |
| - match_id->len = hexlen / 2; |
| - ret = hex2bin(match_id->data, id, hexlen / 2); |
| + ret = __asymmetric_key_hex_to_key_id(id, match_id, asciihexlen / 2); |
| if (ret < 0) { |
| kfree(match_id); |
| return ERR_PTR(-EINVAL); |
| --- a/crypto/asymmetric_keys/x509_public_key.c |
| +++ b/crypto/asymmetric_keys/x509_public_key.c |
| @@ -28,17 +28,30 @@ static bool use_builtin_keys; |
| static struct asymmetric_key_id *ca_keyid; |
| |
| #ifndef MODULE |
| +static struct { |
| + struct asymmetric_key_id id; |
| + unsigned char data[10]; |
| +} cakey; |
| + |
| static int __init ca_keys_setup(char *str) |
| { |
| if (!str) /* default system keyring */ |
| return 1; |
| |
| if (strncmp(str, "id:", 3) == 0) { |
| - struct asymmetric_key_id *p; |
| - p = asymmetric_key_hex_to_key_id(str + 3); |
| - if (p == ERR_PTR(-EINVAL)) |
| - pr_err("Unparsable hex string in ca_keys\n"); |
| - else if (!IS_ERR(p)) |
| + struct asymmetric_key_id *p = &cakey.id; |
| + size_t hexlen = (strlen(str) - 3) / 2; |
| + int ret; |
| + |
| + if (hexlen == 0 || hexlen > sizeof(cakey.data)) { |
| + pr_err("Missing or invalid ca_keys id\n"); |
| + return 1; |
| + } |
| + |
| + ret = __asymmetric_key_hex_to_key_id(str + 3, p, hexlen); |
| + if (ret < 0) |
| + pr_err("Unparsable ca_keys id hex string\n"); |
| + else |
| ca_keyid = p; /* owner key 'id:xxxxxx' */ |
| } else if (strcmp(str, "builtin") == 0) { |
| use_builtin_keys = true; |