From 6cfb5866fef7e7e6dccef9f9a886aec2863f65a0 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 17 Mar 2025 12:18:41 +0900 Subject: [PATCH] udev-builtin-btrfs: refuse to call for irrelevant device node If btrfs builtin command is called, then check if the specified device node is owned by the device. This also allows the command is called specifying any device node. --- src/udev/udev-builtin-btrfs.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/udev/udev-builtin-btrfs.c b/src/udev/udev-builtin-btrfs.c index 200b069efa6..a1238f1e1b3 100644 --- a/src/udev/udev-builtin-btrfs.c +++ b/src/udev/udev-builtin-btrfs.c @@ -16,11 +16,19 @@ static int builtin_btrfs(UdevEvent *event, int argc, char *argv[]) { sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); int r; - if (argc != 3 || !streq(argv[1], "ready")) - return log_device_error_errno(dev, SYNTHETIC_ERRNO(EINVAL), "Invalid arguments"); + if (!IN_SET(argc, 2, 3) || !streq(argv[1], "ready")) + return log_device_error_errno(dev, SYNTHETIC_ERRNO(EINVAL), "Invalid arguments."); - if (strlen(argv[2]) >= sizeof_field(struct btrfs_ioctl_vol_args, name)) - return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EINVAL), "Device name too long for BTRFS_IOC_DEVICES_READY call: %s", argv[2]); + const char *node; + r = sd_device_get_devname(dev, &node); + if (r < 0) + return log_device_error_errno(dev, r, "Failed to get device node: %m"); + + if (argc == 3 && !streq(argv[2], node)) + return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EINVAL), "Device node '%s' is not owned by the device, it must be '%s'.", argv[2], node); + + if (strlen(node) >= sizeof_field(struct btrfs_ioctl_vol_args, name)) + return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EINVAL), "Device name too long for BTRFS_IOC_DEVICES_READY call: %s", node); if (event->event_mode != EVENT_UDEV_WORKER) { log_device_debug(dev, "Running in test mode, skipping execution of 'btrfs' builtin command."); @@ -41,7 +49,7 @@ static int builtin_btrfs(UdevEvent *event, int argc, char *argv[]) { } struct btrfs_ioctl_vol_args args = {}; - strncpy(args.name, argv[2], sizeof(args.name)-1); + strncpy(args.name, node, sizeof(args.name)-1); r = ioctl(fd, BTRFS_IOC_DEVICES_READY, &args); if (r < 0) return log_device_debug_errno(dev, errno, "Failed to call BTRFS_IOC_DEVICES_READY: %m");