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.
This commit is contained in:
Yu Watanabe
2025-03-17 12:18:41 +09:00
parent 73a2912092
commit 6cfb5866fe

View File

@@ -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");