diff options
author | Christophe JAILLET <christophe.jaillet@wanadoo.fr> | 2017-05-05 21:08:44 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-05-18 17:01:46 +0200 |
commit | 9434cec130a941e8a0698d598dfa5499dbdeb949 (patch) | |
tree | 144ae9078e32df6662652778621ae439c3677ad0 /drivers/firmware | |
parent | b299cde245b0b76c977f4291162cf668e087b408 (diff) | |
download | op-kernel-dev-9434cec130a941e8a0698d598dfa5499dbdeb949.zip op-kernel-dev-9434cec130a941e8a0698d598dfa5499dbdeb949.tar.gz |
firmware: Google VPD: Fix memory allocation error handling
This patch fixes several issues:
- if the 1st 'kzalloc' fails, we dereference a NULL pointer
- if the 2nd 'kzalloc' fails, there is a memory leak
- if 'sysfs_create_bin_file' fails there is also a memory leak
Fix it by adding a test after the first memory allocation and some error
handling paths to correctly free memory if needed.
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/google/vpd.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/drivers/firmware/google/vpd.c b/drivers/firmware/google/vpd.c index 3ce8131..1e7860f 100644 --- a/drivers/firmware/google/vpd.c +++ b/drivers/firmware/google/vpd.c @@ -116,9 +116,13 @@ static int vpd_section_attrib_add(const u8 *key, s32 key_len, return VPD_OK; info = kzalloc(sizeof(*info), GFP_KERNEL); - info->key = kzalloc(key_len + 1, GFP_KERNEL); - if (!info->key) + if (!info) return -ENOMEM; + info->key = kzalloc(key_len + 1, GFP_KERNEL); + if (!info->key) { + ret = -ENOMEM; + goto free_info; + } memcpy(info->key, key, key_len); @@ -135,12 +139,17 @@ static int vpd_section_attrib_add(const u8 *key, s32 key_len, list_add_tail(&info->list, &sec->attribs); ret = sysfs_create_bin_file(sec->kobj, &info->bin_attr); - if (ret) { - kfree(info->key); - return ret; - } + if (ret) + goto free_info_key; return 0; + +free_info_key: + kfree(info->key); +free_info: + kfree(info); + + return ret; } static void vpd_section_attrib_destroy(struct vpd_section *sec) |