diff options
author | H Hartley Sweeten <hartleys@visionengravers.com> | 2009-10-19 13:31:46 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2009-10-19 20:36:04 -0400 |
commit | 4b56ffcacee937a85bf39e14872dd141e23ee85f (patch) | |
tree | da435281a3b348c2ed89d1f473bd0f78a1761069 /drivers/mtd/maps | |
parent | 2d098a725333990d265dfe4754d1b63032c35afb (diff) |
mtd: Fix kernel NULL pointer dereference in physmap.c
During the probe for physmap platform flash devices there are a
number error exit conditions that all do a goto err_out which
then calls physmap_flash_remove(). In that function one of the
cleanup steps is:
#ifdef CONFIG_MTD_CONCAT
if (info->cmtd != info->mtd[0])
mtd_concat_destroy(info->cmtd);
#endif
This test will succeed since info->cmtd == NULL and info->mtd[0] is
valid.
Fix this by exiting the remove function when info->cmtd == NULL.
Also, cleanup the #ifdef CONFIG_MTD_PARTITIONS stuff by using
mtd_has_partitions().
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/maps')
-rw-r--r-- | drivers/mtd/maps/physmap.c | 49 |
1 files changed, 25 insertions, 24 deletions
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index 380648e9051a..65f52d4804a2 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c | |||
@@ -44,22 +44,23 @@ static int physmap_flash_remove(struct platform_device *dev) | |||
44 | return 0; | 44 | return 0; |
45 | platform_set_drvdata(dev, NULL); | 45 | platform_set_drvdata(dev, NULL); |
46 | 46 | ||
47 | if (info->cmtd == NULL) | ||
48 | return 0; | ||
49 | |||
47 | physmap_data = dev->dev.platform_data; | 50 | physmap_data = dev->dev.platform_data; |
48 | 51 | ||
49 | if (info->cmtd) { | 52 | if (mtd_has_partitions()) { |
50 | #ifdef CONFIG_MTD_PARTITIONS | 53 | if (info->nr_parts || physmap_data->nr_parts) { |
51 | if (info->nr_parts || physmap_data->nr_parts) | ||
52 | del_mtd_partitions(info->cmtd); | 54 | del_mtd_partitions(info->cmtd); |
53 | else | 55 | |
56 | if (info->nr_parts) | ||
57 | kfree(info->parts); | ||
58 | } else { | ||
54 | del_mtd_device(info->cmtd); | 59 | del_mtd_device(info->cmtd); |
55 | #else | 60 | } |
61 | } else { | ||
56 | del_mtd_device(info->cmtd); | 62 | del_mtd_device(info->cmtd); |
57 | #endif | ||
58 | } | 63 | } |
59 | #ifdef CONFIG_MTD_PARTITIONS | ||
60 | if (info->nr_parts) | ||
61 | kfree(info->parts); | ||
62 | #endif | ||
63 | 64 | ||
64 | #ifdef CONFIG_MTD_CONCAT | 65 | #ifdef CONFIG_MTD_CONCAT |
65 | if (info->cmtd != info->mtd[0]) | 66 | if (info->cmtd != info->mtd[0]) |
@@ -169,22 +170,22 @@ static int physmap_flash_probe(struct platform_device *dev) | |||
169 | if (err) | 170 | if (err) |
170 | goto err_out; | 171 | goto err_out; |
171 | 172 | ||
172 | #ifdef CONFIG_MTD_PARTITIONS | 173 | if (mtd_has_partitions()) { |
173 | err = parse_mtd_partitions(info->cmtd, part_probe_types, | 174 | err = parse_mtd_partitions(info->cmtd, part_probe_types, |
174 | &info->parts, 0); | 175 | &info->parts, 0); |
175 | if (err > 0) { | 176 | if (err > 0) { |
176 | add_mtd_partitions(info->cmtd, info->parts, err); | 177 | add_mtd_partitions(info->cmtd, info->parts, err); |
177 | info->nr_parts = err; | 178 | info->nr_parts = err; |
178 | return 0; | 179 | return 0; |
179 | } | 180 | } |
180 | 181 | ||
181 | if (physmap_data->nr_parts) { | 182 | if (physmap_data->nr_parts) { |
182 | printk(KERN_NOTICE "Using physmap partition information\n"); | 183 | printk(KERN_NOTICE "Using physmap partition information\n"); |
183 | add_mtd_partitions(info->cmtd, physmap_data->parts, | 184 | add_mtd_partitions(info->cmtd, physmap_data->parts, |
184 | physmap_data->nr_parts); | 185 | physmap_data->nr_parts); |
185 | return 0; | 186 | return 0; |
187 | } | ||
186 | } | 188 | } |
187 | #endif | ||
188 | 189 | ||
189 | add_mtd_device(info->cmtd); | 190 | add_mtd_device(info->cmtd); |
190 | return 0; | 191 | return 0; |