Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e480814f authored by Atsushi Nemoto's avatar Atsushi Nemoto Committed by David Woodhouse
Browse files

[MTD] [MAPS] physmap: fix wrong free and del_mtd_{partition,device}



commit 176bf2e0 ("physmap: fix leak of
memory returned by parse_mtd_partitions") deals with a memory leak and
frees the pointer array of mtd_partition after the call to
add_mtd_partitions().  the problem is that mtd_table[x]->name still points
to the freed memory.

Aldo physmap_flash_remove() should call del_mtd_partitions() or
del_mtd_device() only once.

Signed-off-by: default avatarAtsushi Nemoto <anemo@mba.ocn.ne.jp>
Reported-by: default avatarMatthias Kaehlcke <matthias@kaehlcke.net>
Tested-by: default avatarMatthias Kaehlcke <matthias@kaehlcke.net>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent 3afd522d
Loading
Loading
Loading
Loading
+19 −19
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ struct physmap_flash_info {
	struct map_info		map[MAX_RESOURCES];
#ifdef CONFIG_MTD_PARTITIONS
	int			nr_parts;
	struct mtd_partition	*parts;
#endif
};

@@ -45,26 +46,27 @@ static int physmap_flash_remove(struct platform_device *dev)

	physmap_data = dev->dev.platform_data;

#ifdef CONFIG_MTD_CONCAT
	if (info->cmtd != info->mtd[0]) {
#ifdef CONFIG_MTD_PARTITIONS
	if (info->nr_parts) {
		del_mtd_partitions(info->cmtd);
		kfree(info->parts);
	} else if (physmap_data->nr_parts)
		del_mtd_partitions(info->cmtd);
	else
		del_mtd_device(info->cmtd);
#else
	del_mtd_device(info->cmtd);
#endif

#ifdef CONFIG_MTD_CONCAT
	if (info->cmtd != info->mtd[0])
		mtd_concat_destroy(info->cmtd);
	}
#endif

	for (i = 0; i < MAX_RESOURCES; i++) {
		if (info->mtd[i] != NULL) {
#ifdef CONFIG_MTD_PARTITIONS
			if (info->nr_parts || physmap_data->nr_parts)
				del_mtd_partitions(info->mtd[i]);
			else
				del_mtd_device(info->mtd[i]);
#else
			del_mtd_device(info->mtd[i]);
#endif
		if (info->mtd[i] != NULL)
			map_destroy(info->mtd[i]);
	}
	}
	return 0;
}

@@ -86,9 +88,6 @@ static int physmap_flash_probe(struct platform_device *dev)
	int err = 0;
	int i;
	int devices_found = 0;
#ifdef CONFIG_MTD_PARTITIONS
	struct mtd_partition *parts;
#endif

	physmap_data = dev->dev.platform_data;
	if (physmap_data == NULL)
@@ -167,10 +166,11 @@ static int physmap_flash_probe(struct platform_device *dev)
		goto err_out;

#ifdef CONFIG_MTD_PARTITIONS
	err = parse_mtd_partitions(info->cmtd, part_probe_types, &parts, 0);
	err = parse_mtd_partitions(info->cmtd, part_probe_types,
				&info->parts, 0);
	if (err > 0) {
		add_mtd_partitions(info->cmtd, parts, err);
		kfree(parts);
		add_mtd_partitions(info->cmtd, info->parts, err);
		info->nr_parts = err;
		return 0;
	}