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

Commit 5c4c8e4f authored by Boris Brezillon's avatar Boris Brezillon Committed by Greg Kroah-Hartman
Browse files

mtd: Check add_mtd_device() ret code



[ Upstream commit 2b6f0090a3335b7bdd03ca520c35591159463041 ]

add_mtd_device() can fail. We should always check its return value
and gracefully handle the failure case. Fix the call sites where this
not done (in mtdpart.c) and add a __must_check attribute to the
prototype to avoid this kind of mistakes.

Signed-off-by: default avatarBoris Brezillon <bbrezillon@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 6a471a26
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
extern struct mutex mtd_table_mutex;

struct mtd_info *__mtd_next_device(int i);
int add_mtd_device(struct mtd_info *mtd);
int __must_check add_mtd_device(struct mtd_info *mtd);
int del_mtd_device(struct mtd_info *mtd);
int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
int del_mtd_partitions(struct mtd_info *);
+31 −5
Original line number Diff line number Diff line
@@ -612,10 +612,22 @@ int mtd_add_partition(struct mtd_info *parent, const char *name,
	list_add(&new->list, &mtd_partitions);
	mutex_unlock(&mtd_partitions_mutex);

	add_mtd_device(&new->mtd);
	ret = add_mtd_device(&new->mtd);
	if (ret)
		goto err_remove_part;

	mtd_add_partition_attrs(new);

	return 0;

err_remove_part:
	mutex_lock(&mtd_partitions_mutex);
	list_del(&new->list);
	mutex_unlock(&mtd_partitions_mutex);

	free_partition(new);
	pr_info("%s:%i\n", __func__, __LINE__);

	return ret;
}
EXPORT_SYMBOL_GPL(mtd_add_partition);
@@ -706,22 +718,31 @@ int add_mtd_partitions(struct mtd_info *master,
{
	struct mtd_part *slave;
	uint64_t cur_offset = 0;
	int i;
	int i, ret;

	printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);

	for (i = 0; i < nbparts; i++) {
		slave = allocate_partition(master, parts + i, i, cur_offset);
		if (IS_ERR(slave)) {
			del_mtd_partitions(master);
			return PTR_ERR(slave);
			ret = PTR_ERR(slave);
			goto err_del_partitions;
		}

		mutex_lock(&mtd_partitions_mutex);
		list_add(&slave->list, &mtd_partitions);
		mutex_unlock(&mtd_partitions_mutex);

		add_mtd_device(&slave->mtd);
		ret = add_mtd_device(&slave->mtd);
		if (ret) {
			mutex_lock(&mtd_partitions_mutex);
			list_del(&slave->list);
			mutex_unlock(&mtd_partitions_mutex);

			free_partition(slave);
			goto err_del_partitions;
		}

		mtd_add_partition_attrs(slave);
		/* Look for subpartitions */
		parse_mtd_partitions(&slave->mtd, parts[i].types, NULL);
@@ -730,6 +751,11 @@ int add_mtd_partitions(struct mtd_info *master,
	}

	return 0;

err_del_partitions:
	del_mtd_partitions(master);

	return ret;
}

static DEFINE_SPINLOCK(part_parser_lock);