mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH master 1/3] cdev: return error code from cdev_close
@ 2024-05-15  8:05 Ahmad Fatoum
  2024-05-15  8:05 ` [PATCH master 2/3] fs: devfs: restore cdev reference count maintenance Ahmad Fatoum
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Ahmad Fatoum @ 2024-05-15  8:05 UTC (permalink / raw)
  To: barebox; +Cc: uol, ske, Ahmad Fatoum

cdev_operations::close can fail and thus cdev_close should pass along
the error code to the users instead of discarding it.

Do that, so users like devfs close() can start propagating this error.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 fs/devfs-core.c  | 11 ++++++++---
 include/driver.h |  2 +-
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/fs/devfs-core.c b/fs/devfs-core.c
index 376c62be9eab..21e5c2dc969a 100644
--- a/fs/devfs-core.c
+++ b/fs/devfs-core.c
@@ -224,12 +224,17 @@ struct cdev *cdev_open_by_name(const char *name, unsigned long flags)
 	return cdev;
 }
 
-void cdev_close(struct cdev *cdev)
+int cdev_close(struct cdev *cdev)
 {
-	if (cdev->ops->close)
-		cdev->ops->close(cdev);
+	if (cdev->ops->close) {
+		int ret = cdev->ops->close(cdev);
+		if (ret)
+			return ret;
+	}
 
 	cdev->open--;
+
+	return 0;
 }
 
 ssize_t cdev_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags)
diff --git a/include/driver.h b/include/driver.h
index 5a3e46e99e14..3401ab4f07f4 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -529,7 +529,7 @@ struct cdev *cdev_create_loop(const char *path, ulong flags, loff_t offset);
 void cdev_remove_loop(struct cdev *cdev);
 int cdev_open(struct cdev *, unsigned long flags);
 int cdev_fdopen(struct cdev *cdev, unsigned long flags);
-void cdev_close(struct cdev *cdev);
+int cdev_close(struct cdev *cdev);
 int cdev_flush(struct cdev *cdev);
 ssize_t cdev_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags);
 ssize_t cdev_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, ulong flags);
-- 
2.39.2




^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH master 2/3] fs: devfs: restore cdev reference count maintenance
  2024-05-15  8:05 [PATCH master 1/3] cdev: return error code from cdev_close Ahmad Fatoum
@ 2024-05-15  8:05 ` Ahmad Fatoum
  2024-05-15  8:05 ` [PATCH master 3/3] partition: reparse tables only if CONFIG_PARTITION_MANIPULATION=y Ahmad Fatoum
  2024-05-16  7:13 ` [PATCH master 1/3] cdev: return error code from cdev_close Sascha Hauer
  2 siblings, 0 replies; 5+ messages in thread
From: Ahmad Fatoum @ 2024-05-15  8:05 UTC (permalink / raw)
  To: barebox; +Cc: uol, ske, Ahmad Fatoum

barebox v2024.03.0 moves the reference count maintenance into
cdev_open/cdev_close, but missed to switch devfs_open and devfs_close to
actually use cdev_open/cdev_close. The result was that the cdev could be
deleted, e.g. due to partition reparsing, and further use of the file
descriptor would result in a use-after-free.

Fix this by doing what the commit introducing the breakage was purported
to do.

Fixes: d84c3daf1314 ("fs: move cdev open count to cdev_open()/cdev_close()")
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 fs/devfs.c | 18 ++----------------
 1 file changed, 2 insertions(+), 16 deletions(-)

diff --git a/fs/devfs.c b/fs/devfs.c
index c8ddbbdab04d..f5bad5aa9bf2 100644
--- a/fs/devfs.c
+++ b/fs/devfs.c
@@ -102,33 +102,19 @@ static int devfs_open(struct device *_dev, FILE *f, const char *filename)
 	struct inode *inode = f->f_inode;
 	struct devfs_inode *node = container_of(inode, struct devfs_inode, inode);
 	struct cdev *cdev = node->cdev;
-	int ret;
 
 	f->size = cdev->flags & DEVFS_IS_CHARACTER_DEV ?
 			FILE_SIZE_STREAM : cdev->size;
 	f->priv = cdev;
 
-	if (cdev->ops->open) {
-		ret = cdev->ops->open(cdev, f->flags);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
+	return cdev_open(cdev, f->flags);
 }
 
 static int devfs_close(struct device *_dev, FILE *f)
 {
 	struct cdev *cdev = f->priv;
-	int ret;
 
-	if (cdev->ops->close) {
-		ret = cdev->ops->close(cdev);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
+	return cdev_close(cdev);
 }
 
 static int devfs_flush(struct device *_dev, FILE *f)
-- 
2.39.2




^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH master 3/3] partition: reparse tables only if CONFIG_PARTITION_MANIPULATION=y
  2024-05-15  8:05 [PATCH master 1/3] cdev: return error code from cdev_close Ahmad Fatoum
  2024-05-15  8:05 ` [PATCH master 2/3] fs: devfs: restore cdev reference count maintenance Ahmad Fatoum
@ 2024-05-15  8:05 ` Ahmad Fatoum
  2024-05-15  9:24   ` [PATCH] fixup! " Ahmad Fatoum
  2024-05-16  7:13 ` [PATCH master 1/3] cdev: return error code from cdev_close Sascha Hauer
  2 siblings, 1 reply; 5+ messages in thread
From: Ahmad Fatoum @ 2024-05-15  8:05 UTC (permalink / raw)
  To: barebox; +Cc: uol, ske, Ahmad Fatoum

reparse_partition_table() will delete a device's existing partition
cdevs and allocate new ones according to the new partition table.

Holding a reference to a cdev prevents it from bring removed to avoid
dangling pointers and use-after-frees.

Unfortunately, not all users call cdev_open on the cdev and increment
the usage count, instead using functions like cdev_by_name, which don't
call cdev_open.

The proper solution for this is probably to change all functions that
return a cdev to actually take a reference to the cdev.

This will involve quite a bit of work though, so for now, restore old
behavior by making reparsing of the partition tables dependent on
CONFIG_PARTITION_MANIPULATION=y.

The option isn't fully appropriate as partition manipulation can happen
by writing to the parent block device, but not noticing changes of
partitions is the behavior we had before.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 common/partitions.c |  2 ++
 include/disks.h     | 11 +++++++++++
 2 files changed, 13 insertions(+)

diff --git a/common/partitions.c b/common/partitions.c
index 17c2f1eb281a..0b10377e7327 100644
--- a/common/partitions.c
+++ b/common/partitions.c
@@ -266,6 +266,7 @@ int parse_partition_table(struct block_device *blk)
 	return rc;
 }
 
+#ifdef CONFIG_PARTITION_MANIPULATION
 int reparse_partition_table(struct block_device *blk)
 {
 	struct cdev *cdev = &blk->cdev;
@@ -285,6 +286,7 @@ int reparse_partition_table(struct block_device *blk)
 
 	return parse_partition_table(blk);
 }
+#endif
 
 int partition_parser_register(struct partition_parser *p)
 {
diff --git a/include/disks.h b/include/disks.h
index ccb50d3ce94f..a3673d1e276f 100644
--- a/include/disks.h
+++ b/include/disks.h
@@ -3,6 +3,9 @@
 #ifndef DISKS_H
 #define DISKS_H
 
+#include <linux/types.h>
+#include <linux/errno.h>
+
 struct block_device;
 
 /** Size of one sector in bytes */
@@ -24,6 +27,14 @@ struct partition_entry {
 } __attribute__ ((packed));
 
 extern int parse_partition_table(struct block_device*);
+
+#ifdef CONFIG_PARTITION_MANIPULATION
 int reparse_partition_table(struct block_device *blk);
+#else
+static inline int reparse_partition_table(struct block_device *blk)
+{
+	return -ENOSYS;
+}
+#endif
 
 #endif /* DISKS_H */
-- 
2.39.2




^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] fixup! partition: reparse tables only if CONFIG_PARTITION_MANIPULATION=y
  2024-05-15  8:05 ` [PATCH master 3/3] partition: reparse tables only if CONFIG_PARTITION_MANIPULATION=y Ahmad Fatoum
@ 2024-05-15  9:24   ` Ahmad Fatoum
  0 siblings, 0 replies; 5+ messages in thread
From: Ahmad Fatoum @ 2024-05-15  9:24 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

partitions: add prompt and help text for CONFIG_PARTITION_MANIPULATION

So far, CONFIG_PARTITION_MANIPULATION was only selected by
CONFIG_CMD_PARTED and influenced repartitioning support.

Now that it's used to guard the feature of reparsing partition tables,
it makes sense to give it a help text and a prompt for devlopment usage.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 common/Kconfig | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/common/Kconfig b/common/Kconfig
index 97a03217eac9..67cbbf5197da 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -888,7 +888,15 @@ config PARTITION
 	prompt "Enable Partitions"
 
 config PARTITION_MANIPULATION
-	bool
+	bool "Runtime reparsing of partition table" if COMPILE_TEST
+	help
+	  Say y here to have barebox reparse the partition table automatically
+	  when it's rewritten. This is useful when using the parted command
+	  or when writing full disk images that change the existing partitions.
+
+	  Reparsing the partition table will delete existing partitions and thus
+	  may break users that don't do proper reference counting. For this
+	  reason, this option is currently disabled by default.
 
 source "common/partitions/Kconfig"
 
-- 
2.39.2




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH master 1/3] cdev: return error code from cdev_close
  2024-05-15  8:05 [PATCH master 1/3] cdev: return error code from cdev_close Ahmad Fatoum
  2024-05-15  8:05 ` [PATCH master 2/3] fs: devfs: restore cdev reference count maintenance Ahmad Fatoum
  2024-05-15  8:05 ` [PATCH master 3/3] partition: reparse tables only if CONFIG_PARTITION_MANIPULATION=y Ahmad Fatoum
@ 2024-05-16  7:13 ` Sascha Hauer
  2 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2024-05-16  7:13 UTC (permalink / raw)
  To: barebox, Ahmad Fatoum; +Cc: uol, ske


On Wed, 15 May 2024 10:05:05 +0200, Ahmad Fatoum wrote:
> cdev_operations::close can fail and thus cdev_close should pass along
> the error code to the users instead of discarding it.
> 
> Do that, so users like devfs close() can start propagating this error.
> 
> 

Applied, thanks!

[1/3] cdev: return error code from cdev_close
      https://git.pengutronix.de/cgit/barebox/commit/?id=490dab2db018 (link may not be stable)
[2/3] fs: devfs: restore cdev reference count maintenance
      https://git.pengutronix.de/cgit/barebox/commit/?id=dd6ac1612b4b (link may not be stable)
[3/3] partition: reparse tables only if CONFIG_PARTITION_MANIPULATION=y
      https://git.pengutronix.de/cgit/barebox/commit/?id=dfdfc732ba6f (link may not be stable)

Best regards,
-- 
Sascha Hauer <s.hauer@pengutronix.de>




^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-05-16  7:13 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-15  8:05 [PATCH master 1/3] cdev: return error code from cdev_close Ahmad Fatoum
2024-05-15  8:05 ` [PATCH master 2/3] fs: devfs: restore cdev reference count maintenance Ahmad Fatoum
2024-05-15  8:05 ` [PATCH master 3/3] partition: reparse tables only if CONFIG_PARTITION_MANIPULATION=y Ahmad Fatoum
2024-05-15  9:24   ` [PATCH] fixup! " Ahmad Fatoum
2024-05-16  7:13 ` [PATCH master 1/3] cdev: return error code from cdev_close Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox