summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2016-01-26 14:49:22 +0000
committerRussell King <rmk+kernel@arm.linux.org.uk>2016-01-26 18:13:33 +0000
commit9a4e7849b5e4e8742d71fa90fbf0722dd0710a56 (patch)
tree5388d90ba2bac34c530999d4e11e3f40c380281d /drivers
parentce657b1cddf1f88c56ae683efa7130341c92808b (diff)
downloadlinux-9a4e7849b5e4e8742d71fa90fbf0722dd0710a56.tar.gz
linux-9a4e7849b5e4e8742d71fa90fbf0722dd0710a56.tar.bz2
linux-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')
-rw-r--r--drivers/base/component.c6
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;