[PATCH 3/5] cdev: fix cdev_open_by_name() misuse

Sascha Hauer s.hauer at pengutronix.de
Mon Jun 2 06:28:37 PDT 2025


cdev_open_by_name() opens a cdev by its name or path. The open by path
is implemented with a simple skip the "/dev/" part of the string and use
the remaining part as name.
The effect is that several commands in barebox work with "/dev/mmc0" and
"mmc0" as argument, but not with "dev/mmc0" or even "../dev/mmc0".

Create a new cdev_open_by_path_name() function which uses
canonicalize_path() to resolve the full path and skip the "/dev/" part
afterwards.

Convert the places where a path or a name is expected to use the new
function. With this we can drop the "/dev/" skipping from
cdev_open_by_name() so that this function does what the name suggests.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 commands/devlookup.c |  4 +---
 commands/findmnt.c   |  2 +-
 commands/parted.c    |  2 +-
 fs/devfs-core.c      | 17 ++++++++++++++++-
 fs/fs.c              |  6 +++---
 include/driver.h     |  5 +++++
 6 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/commands/devlookup.c b/commands/devlookup.c
index b7fd7be3b624fa2625a8d6968ba95f76e2c75b7d..8f34687352677c4541685c69229ef321e60d1669 100644
--- a/commands/devlookup.c
+++ b/commands/devlookup.c
@@ -71,9 +71,7 @@ static int do_devlookup(int argc, char *argv[])
 		devicefile = aliasbuf;
 	}
 
-	devicefile = devpath_to_name(devicefile);
-
-	cdev = cdev_open_by_name(devicefile, O_RDONLY);
+	cdev = cdev_open_by_path_name(devicefile, O_RDONLY);
 	if (!cdev) {
 		printf("devlookup: cdev %s not found\n", devicefile);
 		ret = -ENOENT;
diff --git a/commands/findmnt.c b/commands/findmnt.c
index c64ef8760684ca075458921ddb382d6a4353e009..a531b1a95a835b3f3d5351733c481c58d7df034e 100644
--- a/commands/findmnt.c
+++ b/commands/findmnt.c
@@ -87,7 +87,7 @@ static int do_findmnt(int argc, char *argv[])
 			const char *backingstore;
 			struct cdev *cdev;
 
-			cdev = cdev_open_by_name(devpath_to_name(device), O_RDONLY);
+			cdev = cdev_open_by_path_name(device, O_RDONLY);
 			if (!cdev)
 				continue;
 
diff --git a/commands/parted.c b/commands/parted.c
index 6872a8414c79e8e116c9ecce864888cec542ad18..7ec56da4c15fe05bb0c78af86c2a9d708aa53e6b 100644
--- a/commands/parted.c
+++ b/commands/parted.c
@@ -366,7 +366,7 @@ static int do_parted(int argc, char *argv[])
 	if (argc < 3)
 		return COMMAND_ERROR_USAGE;
 
-	cdev = cdev_open_by_name(argv[1], O_RDWR);
+	cdev = cdev_open_by_path_name(argv[1], O_RDWR);
 	if (!cdev) {
 		printf("Cannot open %s\n", argv[1]);
 		return COMMAND_ERROR;
diff --git a/fs/devfs-core.c b/fs/devfs-core.c
index 5fafcaecc70d63287e0b716cc0133198c28e79e9..1c1666c55382f6e33830f7df46d1027e810d3e18 100644
--- a/fs/devfs-core.c
+++ b/fs/devfs-core.c
@@ -262,7 +262,7 @@ struct cdev *cdev_open_by_name(const char *name, unsigned long flags)
 	struct cdev *cdev;
 	int ret;
 
-	cdev = cdev_by_name(devpath_to_name(name));
+	cdev = cdev_by_name(name);
 	if (!cdev)
 		return NULL;
 
@@ -273,6 +273,21 @@ struct cdev *cdev_open_by_name(const char *name, unsigned long flags)
 	return cdev;
 }
 
+struct cdev *cdev_open_by_path_name(const char *name, unsigned long flags)
+{
+	char *canon = canonicalize_path(AT_FDCWD, name);
+	struct cdev *cdev;
+
+	if (!canon)
+		return cdev_open_by_name(name, flags);
+
+	cdev = cdev_open_by_name(devpath_to_name(canon), flags);
+
+	free(canon);
+
+	return cdev;
+}
+
 int cdev_close(struct cdev *cdev)
 {
 	if (cdev->ops->close) {
diff --git a/fs/fs.c b/fs/fs.c
index 465fd617c2baa268ea3e5da784d31436629abd51..bca99b1338c6b05f10c8445599170c2d3331883b 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -910,7 +910,7 @@ const char *fs_detect(const char *filename, const char *fsoptions)
 		ret = file_name_detect_type_offset(filename, offset, &type,
 						   file_detect_fs_type);
 	} else {
-		struct cdev *cdev = cdev_open_by_name(filename, O_RDONLY);
+		struct cdev *cdev = cdev_open_by_path_name(filename, O_RDONLY);
 		if (cdev) {
 			ret = cdev_detect_type(cdev, &type);
 			cdev_close(cdev);
@@ -955,7 +955,7 @@ int fsdev_open_cdev(struct fs_device *fsdev)
 			}
 		}
 	} else {
-		fsdev->cdev = cdev_open_by_name(fsdev->backingstore, O_RDWR);
+		fsdev->cdev = cdev_open_by_path_name(fsdev->backingstore, O_RDWR);
 	}
 	if (!fsdev->cdev) {
 		path_put(&path);
@@ -3197,7 +3197,7 @@ int umount(const char *pathname)
 	path_put(&path);
 
 	if (!fsdev) {
-		struct cdev *cdev = cdev_open_by_name(pathname, O_RDWR);
+		struct cdev *cdev = cdev_open_by_path_name(pathname, O_RDWR);
 
 		if (cdev) {
 			cdev_close(cdev);
diff --git a/include/driver.h b/include/driver.h
index b5f4de01e42468ae9245671e130a2285e672f2c0..7606f7d2c241e296ab956b199d4d4ff1bb641a2b 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -540,6 +540,7 @@ ssize_t cdev_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulo
 ssize_t cdev_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, ulong flags);
 struct cdev *cdev_by_name(const char *filename);
 struct cdev *cdev_open_by_name(const char *name, unsigned long flags);
+struct cdev *cdev_open_by_path_name(const char *name, unsigned long flags);
 #else
 static inline ssize_t cdev_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags)
 {
@@ -557,6 +558,10 @@ static inline struct cdev *cdev_open_by_name(const char *name, unsigned long fla
 {
 	return NULL;
 }
+static inline struct cdev *cdev_open_by_path_name(const char *name, unsigned long flags)
+{
+	return NULL;
+}
 #endif
 int cdev_ioctl(struct cdev *cdev, unsigned int cmd, void *buf);
 int cdev_erase(struct cdev *cdev, loff_t count, loff_t offset);

-- 
2.39.5




More information about the barebox mailing list