xref: /openbmc/linux/block/ioctl.c (revision 6a143a7c)
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/capability.h>
3 #include <linux/compat.h>
4 #include <linux/blkdev.h>
5 #include <linux/export.h>
6 #include <linux/gfp.h>
7 #include <linux/blkpg.h>
8 #include <linux/hdreg.h>
9 #include <linux/backing-dev.h>
10 #include <linux/fs.h>
11 #include <linux/blktrace_api.h>
12 #include <linux/pr.h>
13 #include <linux/uaccess.h>
14 #include "blk.h"
15 
16 static int blkpg_do_ioctl(struct block_device *bdev,
17 			  struct blkpg_partition __user *upart, int op)
18 {
19 	struct blkpg_partition p;
20 	long long start, length;
21 
22 	if (!capable(CAP_SYS_ADMIN))
23 		return -EACCES;
24 	if (copy_from_user(&p, upart, sizeof(struct blkpg_partition)))
25 		return -EFAULT;
26 	if (bdev_is_partition(bdev))
27 		return -EINVAL;
28 
29 	if (p.pno <= 0)
30 		return -EINVAL;
31 
32 	if (op == BLKPG_DEL_PARTITION)
33 		return bdev_del_partition(bdev, p.pno);
34 
35 	start = p.start >> SECTOR_SHIFT;
36 	length = p.length >> SECTOR_SHIFT;
37 
38 	switch (op) {
39 	case BLKPG_ADD_PARTITION:
40 		/* check if partition is aligned to blocksize */
41 		if (p.start & (bdev_logical_block_size(bdev) - 1))
42 			return -EINVAL;
43 		return bdev_add_partition(bdev, p.pno, start, length);
44 	case BLKPG_RESIZE_PARTITION:
45 		return bdev_resize_partition(bdev, p.pno, start, length);
46 	default:
47 		return -EINVAL;
48 	}
49 }
50 
51 static int blkpg_ioctl(struct block_device *bdev,
52 		       struct blkpg_ioctl_arg __user *arg)
53 {
54 	struct blkpg_partition __user *udata;
55 	int op;
56 
57 	if (get_user(op, &arg->op) || get_user(udata, &arg->data))
58 		return -EFAULT;
59 
60 	return blkpg_do_ioctl(bdev, udata, op);
61 }
62 
63 #ifdef CONFIG_COMPAT
64 struct compat_blkpg_ioctl_arg {
65 	compat_int_t op;
66 	compat_int_t flags;
67 	compat_int_t datalen;
68 	compat_caddr_t data;
69 };
70 
71 static int compat_blkpg_ioctl(struct block_device *bdev,
72 			      struct compat_blkpg_ioctl_arg __user *arg)
73 {
74 	compat_caddr_t udata;
75 	int op;
76 
77 	if (get_user(op, &arg->op) || get_user(udata, &arg->data))
78 		return -EFAULT;
79 
80 	return blkpg_do_ioctl(bdev, compat_ptr(udata), op);
81 }
82 #endif
83 
84 static int blkdev_reread_part(struct block_device *bdev, fmode_t mode)
85 {
86 	struct block_device *tmp;
87 
88 	if (!disk_part_scan_enabled(bdev->bd_disk) || bdev_is_partition(bdev))
89 		return -EINVAL;
90 	if (!capable(CAP_SYS_ADMIN))
91 		return -EACCES;
92 
93 	/*
94 	 * Reopen the device to revalidate the driver state and force a
95 	 * partition rescan.
96 	 */
97 	mode &= ~FMODE_EXCL;
98 	set_bit(GD_NEED_PART_SCAN, &bdev->bd_disk->state);
99 
100 	tmp = blkdev_get_by_dev(bdev->bd_dev, mode, NULL);
101 	if (IS_ERR(tmp))
102 		return PTR_ERR(tmp);
103 	blkdev_put(tmp, mode);
104 	return 0;
105 }
106 
107 static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode,
108 		unsigned long arg, unsigned long flags)
109 {
110 	uint64_t range[2];
111 	uint64_t start, len;
112 	struct request_queue *q = bdev_get_queue(bdev);
113 	int err;
114 
115 	if (!(mode & FMODE_WRITE))
116 		return -EBADF;
117 
118 	if (!blk_queue_discard(q))
119 		return -EOPNOTSUPP;
120 
121 	if (copy_from_user(range, (void __user *)arg, sizeof(range)))
122 		return -EFAULT;
123 
124 	start = range[0];
125 	len = range[1];
126 
127 	if (start & 511)
128 		return -EINVAL;
129 	if (len & 511)
130 		return -EINVAL;
131 
132 	if (start + len > i_size_read(bdev->bd_inode))
133 		return -EINVAL;
134 
135 	err = truncate_bdev_range(bdev, mode, start, start + len - 1);
136 	if (err)
137 		return err;
138 
139 	return blkdev_issue_discard(bdev, start >> 9, len >> 9,
140 				    GFP_KERNEL, flags);
141 }
142 
143 static int blk_ioctl_zeroout(struct block_device *bdev, fmode_t mode,
144 		unsigned long arg)
145 {
146 	uint64_t range[2];
147 	uint64_t start, end, len;
148 	int err;
149 
150 	if (!(mode & FMODE_WRITE))
151 		return -EBADF;
152 
153 	if (copy_from_user(range, (void __user *)arg, sizeof(range)))
154 		return -EFAULT;
155 
156 	start = range[0];
157 	len = range[1];
158 	end = start + len - 1;
159 
160 	if (start & 511)
161 		return -EINVAL;
162 	if (len & 511)
163 		return -EINVAL;
164 	if (end >= (uint64_t)i_size_read(bdev->bd_inode))
165 		return -EINVAL;
166 	if (end < start)
167 		return -EINVAL;
168 
169 	/* Invalidate the page cache, including dirty pages */
170 	err = truncate_bdev_range(bdev, mode, start, end);
171 	if (err)
172 		return err;
173 
174 	return blkdev_issue_zeroout(bdev, start >> 9, len >> 9, GFP_KERNEL,
175 			BLKDEV_ZERO_NOUNMAP);
176 }
177 
178 static int put_ushort(unsigned short __user *argp, unsigned short val)
179 {
180 	return put_user(val, argp);
181 }
182 
183 static int put_int(int __user *argp, int val)
184 {
185 	return put_user(val, argp);
186 }
187 
188 static int put_uint(unsigned int __user *argp, unsigned int val)
189 {
190 	return put_user(val, argp);
191 }
192 
193 static int put_long(long __user *argp, long val)
194 {
195 	return put_user(val, argp);
196 }
197 
198 static int put_ulong(unsigned long __user *argp, unsigned long val)
199 {
200 	return put_user(val, argp);
201 }
202 
203 static int put_u64(u64 __user *argp, u64 val)
204 {
205 	return put_user(val, argp);
206 }
207 
208 #ifdef CONFIG_COMPAT
209 static int compat_put_long(compat_long_t __user *argp, long val)
210 {
211 	return put_user(val, argp);
212 }
213 
214 static int compat_put_ulong(compat_ulong_t __user *argp, compat_ulong_t val)
215 {
216 	return put_user(val, argp);
217 }
218 #endif
219 
220 #ifdef CONFIG_COMPAT
221 /*
222  * This is the equivalent of compat_ptr_ioctl(), to be used by block
223  * drivers that implement only commands that are completely compatible
224  * between 32-bit and 64-bit user space
225  */
226 int blkdev_compat_ptr_ioctl(struct block_device *bdev, fmode_t mode,
227 			unsigned cmd, unsigned long arg)
228 {
229 	struct gendisk *disk = bdev->bd_disk;
230 
231 	if (disk->fops->ioctl)
232 		return disk->fops->ioctl(bdev, mode, cmd,
233 					 (unsigned long)compat_ptr(arg));
234 
235 	return -ENOIOCTLCMD;
236 }
237 EXPORT_SYMBOL(blkdev_compat_ptr_ioctl);
238 #endif
239 
240 static int blkdev_pr_register(struct block_device *bdev,
241 		struct pr_registration __user *arg)
242 {
243 	const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
244 	struct pr_registration reg;
245 
246 	if (!capable(CAP_SYS_ADMIN))
247 		return -EPERM;
248 	if (!ops || !ops->pr_register)
249 		return -EOPNOTSUPP;
250 	if (copy_from_user(&reg, arg, sizeof(reg)))
251 		return -EFAULT;
252 
253 	if (reg.flags & ~PR_FL_IGNORE_KEY)
254 		return -EOPNOTSUPP;
255 	return ops->pr_register(bdev, reg.old_key, reg.new_key, reg.flags);
256 }
257 
258 static int blkdev_pr_reserve(struct block_device *bdev,
259 		struct pr_reservation __user *arg)
260 {
261 	const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
262 	struct pr_reservation rsv;
263 
264 	if (!capable(CAP_SYS_ADMIN))
265 		return -EPERM;
266 	if (!ops || !ops->pr_reserve)
267 		return -EOPNOTSUPP;
268 	if (copy_from_user(&rsv, arg, sizeof(rsv)))
269 		return -EFAULT;
270 
271 	if (rsv.flags & ~PR_FL_IGNORE_KEY)
272 		return -EOPNOTSUPP;
273 	return ops->pr_reserve(bdev, rsv.key, rsv.type, rsv.flags);
274 }
275 
276 static int blkdev_pr_release(struct block_device *bdev,
277 		struct pr_reservation __user *arg)
278 {
279 	const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
280 	struct pr_reservation rsv;
281 
282 	if (!capable(CAP_SYS_ADMIN))
283 		return -EPERM;
284 	if (!ops || !ops->pr_release)
285 		return -EOPNOTSUPP;
286 	if (copy_from_user(&rsv, arg, sizeof(rsv)))
287 		return -EFAULT;
288 
289 	if (rsv.flags)
290 		return -EOPNOTSUPP;
291 	return ops->pr_release(bdev, rsv.key, rsv.type);
292 }
293 
294 static int blkdev_pr_preempt(struct block_device *bdev,
295 		struct pr_preempt __user *arg, bool abort)
296 {
297 	const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
298 	struct pr_preempt p;
299 
300 	if (!capable(CAP_SYS_ADMIN))
301 		return -EPERM;
302 	if (!ops || !ops->pr_preempt)
303 		return -EOPNOTSUPP;
304 	if (copy_from_user(&p, arg, sizeof(p)))
305 		return -EFAULT;
306 
307 	if (p.flags)
308 		return -EOPNOTSUPP;
309 	return ops->pr_preempt(bdev, p.old_key, p.new_key, p.type, abort);
310 }
311 
312 static int blkdev_pr_clear(struct block_device *bdev,
313 		struct pr_clear __user *arg)
314 {
315 	const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
316 	struct pr_clear c;
317 
318 	if (!capable(CAP_SYS_ADMIN))
319 		return -EPERM;
320 	if (!ops || !ops->pr_clear)
321 		return -EOPNOTSUPP;
322 	if (copy_from_user(&c, arg, sizeof(c)))
323 		return -EFAULT;
324 
325 	if (c.flags)
326 		return -EOPNOTSUPP;
327 	return ops->pr_clear(bdev, c.key);
328 }
329 
330 static int blkdev_flushbuf(struct block_device *bdev, fmode_t mode,
331 		unsigned cmd, unsigned long arg)
332 {
333 	if (!capable(CAP_SYS_ADMIN))
334 		return -EACCES;
335 	fsync_bdev(bdev);
336 	invalidate_bdev(bdev);
337 	return 0;
338 }
339 
340 static int blkdev_roset(struct block_device *bdev, fmode_t mode,
341 		unsigned cmd, unsigned long arg)
342 {
343 	int ret, n;
344 
345 	if (!capable(CAP_SYS_ADMIN))
346 		return -EACCES;
347 
348 	if (get_user(n, (int __user *)arg))
349 		return -EFAULT;
350 	if (bdev->bd_disk->fops->set_read_only) {
351 		ret = bdev->bd_disk->fops->set_read_only(bdev, n);
352 		if (ret)
353 			return ret;
354 	}
355 	bdev->bd_read_only = n;
356 	return 0;
357 }
358 
359 static int blkdev_getgeo(struct block_device *bdev,
360 		struct hd_geometry __user *argp)
361 {
362 	struct gendisk *disk = bdev->bd_disk;
363 	struct hd_geometry geo;
364 	int ret;
365 
366 	if (!argp)
367 		return -EINVAL;
368 	if (!disk->fops->getgeo)
369 		return -ENOTTY;
370 
371 	/*
372 	 * We need to set the startsect first, the driver may
373 	 * want to override it.
374 	 */
375 	memset(&geo, 0, sizeof(geo));
376 	geo.start = get_start_sect(bdev);
377 	ret = disk->fops->getgeo(bdev, &geo);
378 	if (ret)
379 		return ret;
380 	if (copy_to_user(argp, &geo, sizeof(geo)))
381 		return -EFAULT;
382 	return 0;
383 }
384 
385 #ifdef CONFIG_COMPAT
386 struct compat_hd_geometry {
387 	unsigned char heads;
388 	unsigned char sectors;
389 	unsigned short cylinders;
390 	u32 start;
391 };
392 
393 static int compat_hdio_getgeo(struct block_device *bdev,
394 			      struct compat_hd_geometry __user *ugeo)
395 {
396 	struct gendisk *disk = bdev->bd_disk;
397 	struct hd_geometry geo;
398 	int ret;
399 
400 	if (!ugeo)
401 		return -EINVAL;
402 	if (!disk->fops->getgeo)
403 		return -ENOTTY;
404 
405 	memset(&geo, 0, sizeof(geo));
406 	/*
407 	 * We need to set the startsect first, the driver may
408 	 * want to override it.
409 	 */
410 	geo.start = get_start_sect(bdev);
411 	ret = disk->fops->getgeo(bdev, &geo);
412 	if (ret)
413 		return ret;
414 
415 	ret = copy_to_user(ugeo, &geo, 4);
416 	ret |= put_user(geo.start, &ugeo->start);
417 	if (ret)
418 		ret = -EFAULT;
419 
420 	return ret;
421 }
422 #endif
423 
424 /* set the logical block size */
425 static int blkdev_bszset(struct block_device *bdev, fmode_t mode,
426 		int __user *argp)
427 {
428 	int ret, n;
429 
430 	if (!capable(CAP_SYS_ADMIN))
431 		return -EACCES;
432 	if (!argp)
433 		return -EINVAL;
434 	if (get_user(n, argp))
435 		return -EFAULT;
436 
437 	if (mode & FMODE_EXCL)
438 		return set_blocksize(bdev, n);
439 
440 	if (IS_ERR(blkdev_get_by_dev(bdev->bd_dev, mode | FMODE_EXCL, &bdev)))
441 		return -EBUSY;
442 	ret = set_blocksize(bdev, n);
443 	blkdev_put(bdev, mode | FMODE_EXCL);
444 
445 	return ret;
446 }
447 
448 /*
449  * Common commands that are handled the same way on native and compat
450  * user space. Note the separate arg/argp parameters that are needed
451  * to deal with the compat_ptr() conversion.
452  */
453 static int blkdev_common_ioctl(struct block_device *bdev, fmode_t mode,
454 				unsigned cmd, unsigned long arg, void __user *argp)
455 {
456 	unsigned int max_sectors;
457 
458 	switch (cmd) {
459 	case BLKFLSBUF:
460 		return blkdev_flushbuf(bdev, mode, cmd, arg);
461 	case BLKROSET:
462 		return blkdev_roset(bdev, mode, cmd, arg);
463 	case BLKDISCARD:
464 		return blk_ioctl_discard(bdev, mode, arg, 0);
465 	case BLKSECDISCARD:
466 		return blk_ioctl_discard(bdev, mode, arg,
467 				BLKDEV_DISCARD_SECURE);
468 	case BLKZEROOUT:
469 		return blk_ioctl_zeroout(bdev, mode, arg);
470 	case BLKREPORTZONE:
471 		return blkdev_report_zones_ioctl(bdev, mode, cmd, arg);
472 	case BLKRESETZONE:
473 	case BLKOPENZONE:
474 	case BLKCLOSEZONE:
475 	case BLKFINISHZONE:
476 		return blkdev_zone_mgmt_ioctl(bdev, mode, cmd, arg);
477 	case BLKGETZONESZ:
478 		return put_uint(argp, bdev_zone_sectors(bdev));
479 	case BLKGETNRZONES:
480 		return put_uint(argp, blkdev_nr_zones(bdev->bd_disk));
481 	case BLKROGET:
482 		return put_int(argp, bdev_read_only(bdev) != 0);
483 	case BLKSSZGET: /* get block device logical block size */
484 		return put_int(argp, bdev_logical_block_size(bdev));
485 	case BLKPBSZGET: /* get block device physical block size */
486 		return put_uint(argp, bdev_physical_block_size(bdev));
487 	case BLKIOMIN:
488 		return put_uint(argp, bdev_io_min(bdev));
489 	case BLKIOOPT:
490 		return put_uint(argp, bdev_io_opt(bdev));
491 	case BLKALIGNOFF:
492 		return put_int(argp, bdev_alignment_offset(bdev));
493 	case BLKDISCARDZEROES:
494 		return put_uint(argp, 0);
495 	case BLKSECTGET:
496 		max_sectors = min_t(unsigned int, USHRT_MAX,
497 				    queue_max_sectors(bdev_get_queue(bdev)));
498 		return put_ushort(argp, max_sectors);
499 	case BLKROTATIONAL:
500 		return put_ushort(argp, !blk_queue_nonrot(bdev_get_queue(bdev)));
501 	case BLKRASET:
502 	case BLKFRASET:
503 		if(!capable(CAP_SYS_ADMIN))
504 			return -EACCES;
505 		bdev->bd_bdi->ra_pages = (arg * 512) / PAGE_SIZE;
506 		return 0;
507 	case BLKRRPART:
508 		return blkdev_reread_part(bdev, mode);
509 	case BLKTRACESTART:
510 	case BLKTRACESTOP:
511 	case BLKTRACETEARDOWN:
512 		return blk_trace_ioctl(bdev, cmd, argp);
513 	case IOC_PR_REGISTER:
514 		return blkdev_pr_register(bdev, argp);
515 	case IOC_PR_RESERVE:
516 		return blkdev_pr_reserve(bdev, argp);
517 	case IOC_PR_RELEASE:
518 		return blkdev_pr_release(bdev, argp);
519 	case IOC_PR_PREEMPT:
520 		return blkdev_pr_preempt(bdev, argp, false);
521 	case IOC_PR_PREEMPT_ABORT:
522 		return blkdev_pr_preempt(bdev, argp, true);
523 	case IOC_PR_CLEAR:
524 		return blkdev_pr_clear(bdev, argp);
525 	default:
526 		return -ENOIOCTLCMD;
527 	}
528 }
529 
530 /*
531  * Always keep this in sync with compat_blkdev_ioctl()
532  * to handle all incompatible commands in both functions.
533  *
534  * New commands must be compatible and go into blkdev_common_ioctl
535  */
536 int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
537 			unsigned long arg)
538 {
539 	int ret;
540 	loff_t size;
541 	void __user *argp = (void __user *)arg;
542 
543 	switch (cmd) {
544 	/* These need separate implementations for the data structure */
545 	case HDIO_GETGEO:
546 		return blkdev_getgeo(bdev, argp);
547 	case BLKPG:
548 		return blkpg_ioctl(bdev, argp);
549 
550 	/* Compat mode returns 32-bit data instead of 'long' */
551 	case BLKRAGET:
552 	case BLKFRAGET:
553 		if (!argp)
554 			return -EINVAL;
555 		return put_long(argp, (bdev->bd_bdi->ra_pages*PAGE_SIZE) / 512);
556 	case BLKGETSIZE:
557 		size = i_size_read(bdev->bd_inode);
558 		if ((size >> 9) > ~0UL)
559 			return -EFBIG;
560 		return put_ulong(argp, size >> 9);
561 
562 	/* The data is compatible, but the command number is different */
563 	case BLKBSZGET: /* get block device soft block size (cf. BLKSSZGET) */
564 		return put_int(argp, block_size(bdev));
565 	case BLKBSZSET:
566 		return blkdev_bszset(bdev, mode, argp);
567 	case BLKGETSIZE64:
568 		return put_u64(argp, i_size_read(bdev->bd_inode));
569 
570 	/* Incompatible alignment on i386 */
571 	case BLKTRACESETUP:
572 		return blk_trace_ioctl(bdev, cmd, argp);
573 	default:
574 		break;
575 	}
576 
577 	ret = blkdev_common_ioctl(bdev, mode, cmd, arg, argp);
578 	if (ret != -ENOIOCTLCMD)
579 		return ret;
580 
581 	if (!bdev->bd_disk->fops->ioctl)
582 		return -ENOTTY;
583 	return bdev->bd_disk->fops->ioctl(bdev, mode, cmd, arg);
584 }
585 EXPORT_SYMBOL_GPL(blkdev_ioctl); /* for /dev/raw */
586 
587 #ifdef CONFIG_COMPAT
588 
589 #define BLKBSZGET_32		_IOR(0x12, 112, int)
590 #define BLKBSZSET_32		_IOW(0x12, 113, int)
591 #define BLKGETSIZE64_32		_IOR(0x12, 114, int)
592 
593 /* Most of the generic ioctls are handled in the normal fallback path.
594    This assumes the blkdev's low level compat_ioctl always returns
595    ENOIOCTLCMD for unknown ioctls. */
596 long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
597 {
598 	int ret;
599 	void __user *argp = compat_ptr(arg);
600 	struct block_device *bdev = I_BDEV(file->f_mapping->host);
601 	struct gendisk *disk = bdev->bd_disk;
602 	fmode_t mode = file->f_mode;
603 	loff_t size;
604 
605 	/*
606 	 * O_NDELAY can be altered using fcntl(.., F_SETFL, ..), so we have
607 	 * to updated it before every ioctl.
608 	 */
609 	if (file->f_flags & O_NDELAY)
610 		mode |= FMODE_NDELAY;
611 	else
612 		mode &= ~FMODE_NDELAY;
613 
614 	switch (cmd) {
615 	/* These need separate implementations for the data structure */
616 	case HDIO_GETGEO:
617 		return compat_hdio_getgeo(bdev, argp);
618 	case BLKPG:
619 		return compat_blkpg_ioctl(bdev, argp);
620 
621 	/* Compat mode returns 32-bit data instead of 'long' */
622 	case BLKRAGET:
623 	case BLKFRAGET:
624 		if (!argp)
625 			return -EINVAL;
626 		return compat_put_long(argp,
627 			       (bdev->bd_bdi->ra_pages * PAGE_SIZE) / 512);
628 	case BLKGETSIZE:
629 		size = i_size_read(bdev->bd_inode);
630 		if ((size >> 9) > ~0UL)
631 			return -EFBIG;
632 		return compat_put_ulong(argp, size >> 9);
633 
634 	/* The data is compatible, but the command number is different */
635 	case BLKBSZGET_32: /* get the logical block size (cf. BLKSSZGET) */
636 		return put_int(argp, bdev_logical_block_size(bdev));
637 	case BLKBSZSET_32:
638 		return blkdev_bszset(bdev, mode, argp);
639 	case BLKGETSIZE64_32:
640 		return put_u64(argp, i_size_read(bdev->bd_inode));
641 
642 	/* Incompatible alignment on i386 */
643 	case BLKTRACESETUP32:
644 		return blk_trace_ioctl(bdev, cmd, argp);
645 	default:
646 		break;
647 	}
648 
649 	ret = blkdev_common_ioctl(bdev, mode, cmd, arg, argp);
650 	if (ret == -ENOIOCTLCMD && disk->fops->compat_ioctl)
651 		ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg);
652 
653 	return ret;
654 }
655 #endif
656