From 7f9f45b9bfef2ce8706f25c46dcbd109e4181164 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 11 Oct 2021 09:30:25 +0200 Subject: devfs: Do not create overlapping partitions Until now it has been possible to create overlapping partitions. Go away from that and allow to create partitions only in unallocated areas of a device. This lowers the risk of having inconsistent partitioning and increases the chance that inconsistent partitioning is recognized by the user. We had explicit overlap checking for the environment partition which becomes unnecessary with this change and is removed. Signed-off-by: Sascha Hauer Link: https://lore.barebox.org/20211011073025.4187545-1-s.hauer@pengutronix.de Signed-off-by: Sascha Hauer --- fs/devfs-core.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'fs') diff --git a/fs/devfs-core.c b/fs/devfs-core.c index 30ad0e0508..3715e543e6 100644 --- a/fs/devfs-core.c +++ b/fs/devfs-core.c @@ -301,6 +301,37 @@ int devfs_remove(struct cdev *cdev) return 0; } +static bool region_overlap(loff_t starta, loff_t lena, + loff_t startb, loff_t lenb) +{ + if (starta + lena <= startb) + return 0; + if (startb + lenb <= starta) + return 0; + return 1; +} + +static int check_overlap(struct cdev *cdev, const char *name, loff_t offset, loff_t size) +{ + struct cdev *cpart; + + list_for_each_entry(cpart, &cdev->partitions, partition_entry) { + if (region_overlap(cpart->offset, cpart->size, + offset, size)) + goto conflict; + } + + return 0; + +conflict: + pr_err("New partition %s (0x%08llx-0x%08llx) on %s " + "overlaps with partition %s (0x%08llx-0x%08llx), not creating it\n", + name, offset, offset + size - 1, cpart->name, + cpart->name, cpart->offset, cpart->offset + cpart->size - 1); + + return -EINVAL; +} + static struct cdev *__devfs_add_partition(struct cdev *cdev, const struct devfs_partition *partinfo, loff_t *end) { @@ -336,6 +367,9 @@ static struct cdev *__devfs_add_partition(struct cdev *cdev, return ERR_PTR(-EINVAL); } + if (check_overlap(cdev, partinfo->name, offset, size)) + return ERR_PTR(-EINVAL); + if (IS_ENABLED(CONFIG_MTD) && cdev->mtd) { struct mtd_info *mtd; -- cgit v1.2.3