diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2016-01-26 14:49:22 +0000 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2016-01-26 18:13:33 +0000 |
commit | 9a4e7849b5e4e8742d71fa90fbf0722dd0710a56 (patch) | |
tree | 5388d90ba2bac34c530999d4e11e3f40c380281d /drivers/base/component.c | |
parent | ce657b1cddf1f88c56ae683efa7130341c92808b (diff) | |
download | lwn-9a4e7849b5e4e8742d71fa90fbf0722dd0710a56.tar.gz lwn-9a4e7849b5e4e8742d71fa90fbf0722dd0710a56.zip |
component: fix crash on x86_64 with hda audio drivers
Maarten reports that the addition of releasing match data to the
component helper results in a general protection fault on x86_64.
This is caused by the devm resources being freed in reverse order
to their allocation, which caused a use-after-free of the match
array.
Switch the match array to be a more conventional kmalloc/kfree()
affair, explicitly freeing it along with the parent match data
structure.
Reported-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Fixes: ce657b1cddf1 ("component: add support for releasing match data")
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/base/component.c')
-rw-r--r-- | drivers/base/component.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/base/component.c b/drivers/base/component.c index 89f5cf68d80a..05cd26c02449 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c @@ -206,6 +206,8 @@ static void component_match_release(struct device *master, if (mc->release) mc->release(master, mc->data); } + + kfree(match->compare); } static void devm_component_match_release(struct device *dev, void *res) @@ -221,14 +223,14 @@ static int component_match_realloc(struct device *dev, if (match->alloc == num) return 0; - new = devm_kmalloc_array(dev, num, sizeof(*new), GFP_KERNEL); + new = kmalloc_array(num, sizeof(*new), GFP_KERNEL); if (!new) return -ENOMEM; if (match->compare) { memcpy(new, match->compare, sizeof(*new) * min(match->num, num)); - devm_kfree(dev, match->compare); + kfree(match->compare); } match->compare = new; match->alloc = num; |