@@ -254,25 +254,28 @@ int blkdev_compat_ptr_ioctl(struct block_device *bdev, blk_mode_t mode,
254254EXPORT_SYMBOL (blkdev_compat_ptr_ioctl );
255255#endif
256256
257- static bool blkdev_pr_allowed (struct block_device * bdev )
257+ static bool blkdev_pr_allowed (struct block_device * bdev , blk_mode_t mode )
258258{
259259 /* no sense to make reservations for partitions */
260260 if (bdev_is_partition (bdev ))
261261 return false;
262262
263263 if (capable (CAP_SYS_ADMIN ))
264264 return true;
265-
266- return false;
265+ /*
266+ * Only allow unprivileged reservations if the file descriptor is open
267+ * for writing.
268+ */
269+ return mode & BLK_OPEN_WRITE ;
267270}
268271
269- static int blkdev_pr_register (struct block_device * bdev ,
272+ static int blkdev_pr_register (struct block_device * bdev , blk_mode_t mode ,
270273 struct pr_registration __user * arg )
271274{
272275 const struct pr_ops * ops = bdev -> bd_disk -> fops -> pr_ops ;
273276 struct pr_registration reg ;
274277
275- if (!blkdev_pr_allowed (bdev ))
278+ if (!blkdev_pr_allowed (bdev , mode ))
276279 return - EPERM ;
277280 if (!ops || !ops -> pr_register )
278281 return - EOPNOTSUPP ;
@@ -284,13 +287,13 @@ static int blkdev_pr_register(struct block_device *bdev,
284287 return ops -> pr_register (bdev , reg .old_key , reg .new_key , reg .flags );
285288}
286289
287- static int blkdev_pr_reserve (struct block_device * bdev ,
290+ static int blkdev_pr_reserve (struct block_device * bdev , blk_mode_t mode ,
288291 struct pr_reservation __user * arg )
289292{
290293 const struct pr_ops * ops = bdev -> bd_disk -> fops -> pr_ops ;
291294 struct pr_reservation rsv ;
292295
293- if (!blkdev_pr_allowed (bdev ))
296+ if (!blkdev_pr_allowed (bdev , mode ))
294297 return - EPERM ;
295298 if (!ops || !ops -> pr_reserve )
296299 return - EOPNOTSUPP ;
@@ -302,13 +305,13 @@ static int blkdev_pr_reserve(struct block_device *bdev,
302305 return ops -> pr_reserve (bdev , rsv .key , rsv .type , rsv .flags );
303306}
304307
305- static int blkdev_pr_release (struct block_device * bdev ,
308+ static int blkdev_pr_release (struct block_device * bdev , blk_mode_t mode ,
306309 struct pr_reservation __user * arg )
307310{
308311 const struct pr_ops * ops = bdev -> bd_disk -> fops -> pr_ops ;
309312 struct pr_reservation rsv ;
310313
311- if (!blkdev_pr_allowed (bdev ))
314+ if (!blkdev_pr_allowed (bdev , mode ))
312315 return - EPERM ;
313316 if (!ops || !ops -> pr_release )
314317 return - EOPNOTSUPP ;
@@ -320,13 +323,13 @@ static int blkdev_pr_release(struct block_device *bdev,
320323 return ops -> pr_release (bdev , rsv .key , rsv .type );
321324}
322325
323- static int blkdev_pr_preempt (struct block_device * bdev ,
326+ static int blkdev_pr_preempt (struct block_device * bdev , blk_mode_t mode ,
324327 struct pr_preempt __user * arg , bool abort )
325328{
326329 const struct pr_ops * ops = bdev -> bd_disk -> fops -> pr_ops ;
327330 struct pr_preempt p ;
328331
329- if (!blkdev_pr_allowed (bdev ))
332+ if (!blkdev_pr_allowed (bdev , mode ))
330333 return - EPERM ;
331334 if (!ops || !ops -> pr_preempt )
332335 return - EOPNOTSUPP ;
@@ -338,13 +341,13 @@ static int blkdev_pr_preempt(struct block_device *bdev,
338341 return ops -> pr_preempt (bdev , p .old_key , p .new_key , p .type , abort );
339342}
340343
341- static int blkdev_pr_clear (struct block_device * bdev ,
344+ static int blkdev_pr_clear (struct block_device * bdev , blk_mode_t mode ,
342345 struct pr_clear __user * arg )
343346{
344347 const struct pr_ops * ops = bdev -> bd_disk -> fops -> pr_ops ;
345348 struct pr_clear c ;
346349
347- if (!blkdev_pr_allowed (bdev ))
350+ if (!blkdev_pr_allowed (bdev , mode ))
348351 return - EPERM ;
349352 if (!ops || !ops -> pr_clear )
350353 return - EOPNOTSUPP ;
@@ -546,17 +549,17 @@ static int blkdev_common_ioctl(struct block_device *bdev, blk_mode_t mode,
546549 case BLKTRACETEARDOWN :
547550 return blk_trace_ioctl (bdev , cmd , argp );
548551 case IOC_PR_REGISTER :
549- return blkdev_pr_register (bdev , argp );
552+ return blkdev_pr_register (bdev , mode , argp );
550553 case IOC_PR_RESERVE :
551- return blkdev_pr_reserve (bdev , argp );
554+ return blkdev_pr_reserve (bdev , mode , argp );
552555 case IOC_PR_RELEASE :
553- return blkdev_pr_release (bdev , argp );
556+ return blkdev_pr_release (bdev , mode , argp );
554557 case IOC_PR_PREEMPT :
555- return blkdev_pr_preempt (bdev , argp , false);
558+ return blkdev_pr_preempt (bdev , mode , argp , false);
556559 case IOC_PR_PREEMPT_ABORT :
557- return blkdev_pr_preempt (bdev , argp , true);
560+ return blkdev_pr_preempt (bdev , mode , argp , true);
558561 case IOC_PR_CLEAR :
559- return blkdev_pr_clear (bdev , argp );
562+ return blkdev_pr_clear (bdev , mode , argp );
560563 default :
561564 return - ENOIOCTLCMD ;
562565 }
0 commit comments