History

block: allow IOC_PR_READ_* ioctls with BLK_OPEN_READ

The recently added IOC_PR_READ_* ioctls require the same BLK_OPEN_WRITE permission as the older persistent reservation ioctls. This has the drawback that udev triggers when the file descriptor is closed, resulting in unnecessary activity like scanning partitions even though these read-only ioctls do not modify the device. Change IOC_PR_READ_KEYS and IOC_PR_READ_RESERVATION to require BLK_OPEN_READ. This prevents unnecessary activity every time `blkpr --read-keys` or `blkpr --read-reservation` is invoked by shell scripts, for example. It is safe to reduce the permission requirement from BLK_OPEN_WRITE to BLK_OPEN_READ since these two ioctls do not modify the persistent reservation state. Userspace cannot use the information fetched by these ioctls to make changes to the device unless it later opens the device with BLK_OPEN_WRITE.

Stefan Hajnoczi committed 9 months ago

Commit 5b88af71 parent 2ebc8d61 file · +23 −11Browse files

Unified · Split

block/ioctl.c+23−11
@@ -318,7 +318,13 @@ int blkdev_compat_ptr_ioctl(struct block_device *bdev, blk_mode_t mode, · 317 unmodified lines
318EXPORT_SYMBOL(blkdev_compat_ptr_ioctl);318EXPORT_SYMBOL(blkdev_compat_ptr_ioctl);
319#endif319#endif
320 320
321static bool blkdev_pr_allowed(struct block_device *bdev, blk_mode_t mode)321enum pr_direction {
322 PR_IN, /* read from device */
323 PR_OUT, /* write to device */
324};
325
326static bool blkdev_pr_allowed(struct block_device *bdev, blk_mode_t mode,
327 enum pr_direction dir)
322{328{
323 /* no sense to make reservations for partitions */329 /* no sense to make reservations for partitions */
324 if (bdev_is_partition(bdev))330 if (bdev_is_partition(bdev))
@@ -326,11 +332,17 @@ static bool blkdev_pr_allowed(struct block_device *bdev, blk_mode_t mode) · 1 unmodified line
326 332
327 if (capable(CAP_SYS_ADMIN))333 if (capable(CAP_SYS_ADMIN))
328 return true;334 return true;
335
329 /*336 /*
330 * Only allow unprivileged reservations if the file descriptor is open337 * Only allow unprivileged reservation _out_ commands if the file
331 * for writing.338 * descriptor is open for writing. Allow reservation _in_ commands if
339 * the file descriptor is open for reading since they do not modify the
340 * device.
332 */341 */
333 return mode & BLK_OPEN_WRITE;342 if (dir == PR_IN)
343 return mode & BLK_OPEN_READ;
344 else
345 return mode & BLK_OPEN_WRITE;
334}346}
335 347
336static int blkdev_pr_register(struct block_device *bdev, blk_mode_t mode,348static int blkdev_pr_register(struct block_device *bdev, blk_mode_t mode,
@@ -339,7 +351,7 @@ static int blkdev_pr_register(struct block_device *bdev, blk_mode_t mode, · 2 unmodified lines
339 const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;351 const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
340 struct pr_registration reg;352 struct pr_registration reg;
341 353
342 if (!blkdev_pr_allowed(bdev, mode))354 if (!blkdev_pr_allowed(bdev, mode, PR_OUT))
343 return -EPERM;355 return -EPERM;
344 if (!ops || !ops->pr_register)356 if (!ops || !ops->pr_register)
345 return -EOPNOTSUPP;357 return -EOPNOTSUPP;
@@ -357,7 +369,7 @@ static int blkdev_pr_reserve(struct block_device *bdev, blk_mode_t mode, · 11 unmodified lines
357 const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;369 const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
358 struct pr_reservation rsv;370 struct pr_reservation rsv;
359 371
360 if (!blkdev_pr_allowed(bdev, mode))372 if (!blkdev_pr_allowed(bdev, mode, PR_OUT))
361 return -EPERM;373 return -EPERM;
362 if (!ops || !ops->pr_reserve)374 if (!ops || !ops->pr_reserve)
363 return -EOPNOTSUPP;375 return -EOPNOTSUPP;
@@ -375,7 +387,7 @@ static int blkdev_pr_release(struct block_device *bdev, blk_mode_t mode, · 11 unmodified lines
375 const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;387 const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
376 struct pr_reservation rsv;388 struct pr_reservation rsv;
377 389
378 if (!blkdev_pr_allowed(bdev, mode))390 if (!blkdev_pr_allowed(bdev, mode, PR_OUT))
379 return -EPERM;391 return -EPERM;
380 if (!ops || !ops->pr_release)392 if (!ops || !ops->pr_release)
381 return -EOPNOTSUPP;393 return -EOPNOTSUPP;
@@ -393,7 +405,7 @@ static int blkdev_pr_preempt(struct block_device *bdev, blk_mode_t mode, · 11 unmodified lines
393 const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;405 const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
394 struct pr_preempt p;406 struct pr_preempt p;
395 407
396 if (!blkdev_pr_allowed(bdev, mode))408 if (!blkdev_pr_allowed(bdev, mode, PR_OUT))
397 return -EPERM;409 return -EPERM;
398 if (!ops || !ops->pr_preempt)410 if (!ops || !ops->pr_preempt)
399 return -EOPNOTSUPP;411 return -EOPNOTSUPP;
@@ -411,7 +423,7 @@ static int blkdev_pr_clear(struct block_device *bdev, blk_mode_t mode, · 11 unmodified lines
411 const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;423 const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
412 struct pr_clear c;424 struct pr_clear c;
413 425
414 if (!blkdev_pr_allowed(bdev, mode))426 if (!blkdev_pr_allowed(bdev, mode, PR_OUT))
415 return -EPERM;427 return -EPERM;
416 if (!ops || !ops->pr_clear)428 if (!ops || !ops->pr_clear)
417 return -EOPNOTSUPP;429 return -EOPNOTSUPP;
@@ -434,7 +446,7 @@ static int blkdev_pr_read_keys(struct block_device *bdev, blk_mode_t mode, · 16 unmodified lines
434 size_t keys_copy_len;446 size_t keys_copy_len;
435 int ret;447 int ret;
436 448
437 if (!blkdev_pr_allowed(bdev, mode))449 if (!blkdev_pr_allowed(bdev, mode, PR_IN))
438 return -EPERM;450 return -EPERM;
439 if (!ops || !ops->pr_read_keys)451 if (!ops || !ops->pr_read_keys)
440 return -EOPNOTSUPP;452 return -EOPNOTSUPP;
@@ -486,7 +498,7 @@ static int blkdev_pr_read_reservation(struct block_device *bdev, · 45 unmodified lines
486 struct pr_read_reservation out = {};498 struct pr_read_reservation out = {};
487 int ret;499 int ret;
488 500
489 if (!blkdev_pr_allowed(bdev, mode))501 if (!blkdev_pr_allowed(bdev, mode, PR_IN))
490 return -EPERM;502 return -EPERM;
491 if (!ops || !ops->pr_read_reservation)503 if (!ops || !ops->pr_read_reservation)
492 return -EOPNOTSUPP;504 return -EOPNOTSUPP;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t