kernel: mtd: Make subpartitions inherit parent's access mode
authorBruno Pena <brunompena@gmail.com>
Sat, 9 Nov 2019 14:23:58 +0000 (15:23 +0100)
committerPetr Štetiar <ynezz@true.cz>
Mon, 20 Jan 2020 19:57:21 +0000 (20:57 +0100)
Currently it's not possible to effectively mark a "firmware" partition
as read-only. The sub-partitions "kernel", "rootfs" and "rootfs_data"
are always created as read-write (ignoring the parent access mode).

This patch enforces the access mode of sub-partitions to match the
parent partition, which is useful for recovery images that are meant
to be fully read-only to avoid accidental damage from end-user.

An example of such implementation (read-only firmware image) is the
recovery image used on the Zsun-SD100 [1].

Please note the related patch for fstools [2] to enable this read-only
concept.

[1] https://github.com/brunompena/zsun-resources
[2] http://lists.infradead.org/pipermail/openwrt-devel/2020-January/021043.html

Signed-off-by: Bruno Pena <brunompena@gmail.com>
[removed already obsolete 4.9 kernel patch]
Signed-off-by: Petr Štetiar <ynezz@true.cz>
target/linux/generic/hack-4.14/401-inherit-parent-partition-access-mode.patch [new file with mode: 0644]
target/linux/generic/hack-4.19/401-inherit-parent-partition-access-mode.patch [new file with mode: 0644]

diff --git a/target/linux/generic/hack-4.14/401-inherit-parent-partition-access-mode.patch b/target/linux/generic/hack-4.14/401-inherit-parent-partition-access-mode.patch
new file mode 100644 (file)
index 0000000..dbbe68f
--- /dev/null
@@ -0,0 +1,60 @@
+--- a/drivers/mtd/mtdchar.c
++++ b/drivers/mtd/mtdchar.c
+@@ -595,7 +595,10 @@
+               /* Sanitize user input */
+               p.devname[BLKPG_DEVNAMELTH - 1] = '\0';
+-              return mtd_add_partition(mtd, p.devname, p.start, p.length);
++              /* No mtd flags masking required */
++              uint32_t mask_flags = 0;
++
++              return mtd_add_partition(mtd, p.devname, p.start, p.length, mask_flags);
+       case BLKPG_DEL_PARTITION:
+--- a/drivers/mtd/mtdpart.c
++++ b/drivers/mtd/mtdpart.c
+@@ -726,7 +726,7 @@
+ }
+ int mtd_add_partition(struct mtd_info *parent, const char *name,
+-                    long long offset, long long length)
++                    long long offset, long long length, uint32_t mask_flags)
+ {
+       struct mtd_partition part;
+       struct mtd_part *new;
+@@ -747,6 +747,7 @@
+       part.name = name;
+       part.size = length;
+       part.offset = offset;
++      part.mask_flags = mask_flags;
+       new = allocate_partition(parent, &part, -1, offset);
+       if (IS_ERR(new))
+@@ -855,10 +856,14 @@
+               /* adjust partition offsets */
+               parts[i].offset += slave->offset;
++              /* adjust partition mask */
++              parts[i].mask_flags = !(slave->mtd.flags & MTD_WRITEABLE) ? MTD_WRITEABLE : 0;
++
+               mtd_add_partition(slave->parent,
+                                 parts[i].name,
+                                 parts[i].offset,
+-                                parts[i].size);
++                                parts[i].size,
++                                parts[i].mask_flags);
+       }
+       kfree(parts);
+--- a/include/linux/mtd/partitions.h
++++ b/include/linux/mtd/partitions.h
+@@ -114,7 +114,7 @@
+ int mtd_is_partition(const struct mtd_info *mtd);
+ int mtd_add_partition(struct mtd_info *master, const char *name,
+-                    long long offset, long long length);
++                    long long offset, long long length, uint32_t mask_flags);
+ int mtd_del_partition(struct mtd_info *master, int partno);
+ struct mtd_info *mtdpart_get_master(const struct mtd_info *mtd);
+ uint64_t mtdpart_get_offset(const struct mtd_info *mtd);
diff --git a/target/linux/generic/hack-4.19/401-inherit-parent-partition-access-mode.patch b/target/linux/generic/hack-4.19/401-inherit-parent-partition-access-mode.patch
new file mode 100644 (file)
index 0000000..61dd036
--- /dev/null
@@ -0,0 +1,60 @@
+--- a/drivers/mtd/mtdchar.c
++++ b/drivers/mtd/mtdchar.c
+@@ -583,7 +583,10 @@
+               /* Sanitize user input */
+               p.devname[BLKPG_DEVNAMELTH - 1] = '\0';
+-              return mtd_add_partition(mtd, p.devname, p.start, p.length);
++              /* No mtd flags masking required */
++              uint32_t mask_flags = 0;
++
++              return mtd_add_partition(mtd, p.devname, p.start, p.length, mask_flags);
+       case BLKPG_DEL_PARTITION:
+--- a/drivers/mtd/mtdpart.c
++++ b/drivers/mtd/mtdpart.c
+@@ -679,7 +679,7 @@
+ }
+ int mtd_add_partition(struct mtd_info *parent, const char *name,
+-                    long long offset, long long length)
++                    long long offset, long long length, uint32_t mask_flags)
+ {
+       struct mtd_partition part;
+       struct mtd_part *new;
+@@ -700,6 +700,7 @@
+       part.name = name;
+       part.size = length;
+       part.offset = offset;
++      part.mask_flags = mask_flags;
+       new = allocate_partition(parent, &part, -1, offset);
+       if (IS_ERR(new))
+@@ -808,10 +809,14 @@
+               /* adjust partition offsets */
+               parts[i].offset += slave->offset;
++              /* adjust partition mask */
++              parts[i].mask_flags = !(slave->mtd.flags & MTD_WRITEABLE) ? MTD_WRITEABLE : 0;
++
+               mtd_add_partition(slave->parent,
+                                 parts[i].name,
+                                 parts[i].offset,
+-                                parts[i].size);
++                                parts[i].size,
++                                parts[i].mask_flags);
+       }
+       kfree(parts);
+--- a/include/linux/mtd/partitions.h
++++ b/include/linux/mtd/partitions.h
+@@ -114,7 +114,7 @@
+ int mtd_is_partition(const struct mtd_info *mtd);
+ int mtd_add_partition(struct mtd_info *master, const char *name,
+-                    long long offset, long long length);
++                    long long offset, long long length, uint32_t mask_flags);
+ int mtd_del_partition(struct mtd_info *master, int partno);
+ struct mtd_info *mtdpart_get_master(const struct mtd_info *mtd);
+ uint64_t mtdpart_get_offset(const struct mtd_info *mtd);