From: Bruno Pena <brunompena@gmail.com>
Date: Sat, 9 Nov 2019 14:23:58 +0000 (+0100)
Subject: kernel: mtd: Make subpartitions inherit parent's access mode
X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=de80424f706682e8bba27c60bcd2a9c1b4a5e875;p=openwrt%2Fstaging%2Fneocturne.git

kernel: mtd: Make subpartitions inherit parent's access mode

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>
---

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
index 0000000000..dbbe68ff4a
--- /dev/null
+++ b/target/linux/generic/hack-4.14/401-inherit-parent-partition-access-mode.patch
@@ -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
index 0000000000..61dd0369a6
--- /dev/null
+++ b/target/linux/generic/hack-4.19/401-inherit-parent-partition-access-mode.patch
@@ -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);