Skip to content

Commit 2b6f009

Browse files
committed
mtd: Check add_mtd_device() ret code
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: Boris Brezillon <bbrezillon@kernel.org>
1 parent 19e16fb commit 2b6f009

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

drivers/mtd/mtdcore.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
extern struct mutex mtd_table_mutex;
88

99
struct mtd_info *__mtd_next_device(int i);
10-
int add_mtd_device(struct mtd_info *mtd);
10+
int __must_check add_mtd_device(struct mtd_info *mtd);
1111
int del_mtd_device(struct mtd_info *mtd);
1212
int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
1313
int del_mtd_partitions(struct mtd_info *);

drivers/mtd/mtdpart.c

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -618,10 +618,22 @@ int mtd_add_partition(struct mtd_info *parent, const char *name,
618618
list_add(&new->list, &mtd_partitions);
619619
mutex_unlock(&mtd_partitions_mutex);
620620

621-
add_mtd_device(&new->mtd);
621+
ret = add_mtd_device(&new->mtd);
622+
if (ret)
623+
goto err_remove_part;
622624

623625
mtd_add_partition_attrs(new);
624626

627+
return 0;
628+
629+
err_remove_part:
630+
mutex_lock(&mtd_partitions_mutex);
631+
list_del(&new->list);
632+
mutex_unlock(&mtd_partitions_mutex);
633+
634+
free_partition(new);
635+
pr_info("%s:%i\n", __func__, __LINE__);
636+
625637
return ret;
626638
}
627639
EXPORT_SYMBOL_GPL(mtd_add_partition);
@@ -712,22 +724,31 @@ int add_mtd_partitions(struct mtd_info *master,
712724
{
713725
struct mtd_part *slave;
714726
uint64_t cur_offset = 0;
715-
int i;
727+
int i, ret;
716728

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

719731
for (i = 0; i < nbparts; i++) {
720732
slave = allocate_partition(master, parts + i, i, cur_offset);
721733
if (IS_ERR(slave)) {
722-
del_mtd_partitions(master);
723-
return PTR_ERR(slave);
734+
ret = PTR_ERR(slave);
735+
goto err_del_partitions;
724736
}
725737

726738
mutex_lock(&mtd_partitions_mutex);
727739
list_add(&slave->list, &mtd_partitions);
728740
mutex_unlock(&mtd_partitions_mutex);
729741

730-
add_mtd_device(&slave->mtd);
742+
ret = add_mtd_device(&slave->mtd);
743+
if (ret) {
744+
mutex_lock(&mtd_partitions_mutex);
745+
list_del(&slave->list);
746+
mutex_unlock(&mtd_partitions_mutex);
747+
748+
free_partition(slave);
749+
goto err_del_partitions;
750+
}
751+
731752
mtd_add_partition_attrs(slave);
732753
/* Look for subpartitions */
733754
parse_mtd_partitions(&slave->mtd, parts[i].types, NULL);
@@ -736,6 +757,11 @@ int add_mtd_partitions(struct mtd_info *master,
736757
}
737758

738759
return 0;
760+
761+
err_del_partitions:
762+
del_mtd_partitions(master);
763+
764+
return ret;
739765
}
740766

741767
static DEFINE_SPINLOCK(part_parser_lock);

0 commit comments

Comments
 (0)