hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/block/scsi_ioctl.c
....@@ -1,21 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * Copyright (C) 2001 Jens Axboe <axboe@suse.de>
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License version 2 as
6
- * published by the Free Software Foundation.
7
- *
8
- * This program is distributed in the hope that it will be useful,
9
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- *
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- * GNU General Public License for more details.
13
- *
14
- * You should have received a copy of the GNU General Public Licens
15
- * along with this program; if not, write to the Free Software
16
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-
17
- *
184 */
5
+#include <linux/compat.h>
196 #include <linux/kernel.h>
207 #include <linux/errno.h>
218 #include <linux/string.h>
....@@ -33,6 +20,7 @@
3320 #include <scsi/scsi.h>
3421 #include <scsi/scsi_ioctl.h>
3522 #include <scsi/scsi_cmnd.h>
23
+#include <scsi/sg.h>
3624
3725 struct blk_cmd_filter {
3826 unsigned long read_ok[BLK_SCSI_CMD_PER_LONG];
....@@ -48,8 +36,6 @@
4836 16, 12, 10, 10
4937 };
5038 EXPORT_SYMBOL(scsi_command_size_tbl);
51
-
52
-#include <scsi/sg.h>
5339
5440 static int sg_get_version(int __user *p)
5541 {
....@@ -205,6 +191,10 @@
205191 __set_bit(GPCMD_LOAD_UNLOAD, filter->write_ok);
206192 __set_bit(GPCMD_SET_STREAMING, filter->write_ok);
207193 __set_bit(GPCMD_SET_READ_AHEAD, filter->write_ok);
194
+
195
+ /* ZBC Commands */
196
+ __set_bit(ZBC_OUT, filter->write_ok);
197
+ __set_bit(ZBC_IN, filter->read_ok);
208198 }
209199
210200 int blk_verify_command(unsigned char *cmd, fmode_t mode)
....@@ -341,9 +331,8 @@
341331 struct iov_iter i;
342332 struct iovec *iov = NULL;
343333
344
- ret = import_iovec(rq_data_dir(rq),
345
- hdr->dxferp, hdr->iovec_count,
346
- 0, &iov, &i);
334
+ ret = import_iovec(rq_data_dir(rq), hdr->dxferp,
335
+ hdr->iovec_count, 0, &iov, &i);
347336 if (ret < 0)
348337 goto out_free_cdb;
349338
....@@ -556,6 +545,225 @@
556545 return __blk_send_generic(q, bd_disk, GPCMD_START_STOP_UNIT, data);
557546 }
558547
548
+int put_sg_io_hdr(const struct sg_io_hdr *hdr, void __user *argp)
549
+{
550
+#ifdef CONFIG_COMPAT
551
+ if (in_compat_syscall()) {
552
+ struct compat_sg_io_hdr hdr32 = {
553
+ .interface_id = hdr->interface_id,
554
+ .dxfer_direction = hdr->dxfer_direction,
555
+ .cmd_len = hdr->cmd_len,
556
+ .mx_sb_len = hdr->mx_sb_len,
557
+ .iovec_count = hdr->iovec_count,
558
+ .dxfer_len = hdr->dxfer_len,
559
+ .dxferp = (uintptr_t)hdr->dxferp,
560
+ .cmdp = (uintptr_t)hdr->cmdp,
561
+ .sbp = (uintptr_t)hdr->sbp,
562
+ .timeout = hdr->timeout,
563
+ .flags = hdr->flags,
564
+ .pack_id = hdr->pack_id,
565
+ .usr_ptr = (uintptr_t)hdr->usr_ptr,
566
+ .status = hdr->status,
567
+ .masked_status = hdr->masked_status,
568
+ .msg_status = hdr->msg_status,
569
+ .sb_len_wr = hdr->sb_len_wr,
570
+ .host_status = hdr->host_status,
571
+ .driver_status = hdr->driver_status,
572
+ .resid = hdr->resid,
573
+ .duration = hdr->duration,
574
+ .info = hdr->info,
575
+ };
576
+
577
+ if (copy_to_user(argp, &hdr32, sizeof(hdr32)))
578
+ return -EFAULT;
579
+
580
+ return 0;
581
+ }
582
+#endif
583
+
584
+ if (copy_to_user(argp, hdr, sizeof(*hdr)))
585
+ return -EFAULT;
586
+
587
+ return 0;
588
+}
589
+EXPORT_SYMBOL(put_sg_io_hdr);
590
+
591
+int get_sg_io_hdr(struct sg_io_hdr *hdr, const void __user *argp)
592
+{
593
+#ifdef CONFIG_COMPAT
594
+ struct compat_sg_io_hdr hdr32;
595
+
596
+ if (in_compat_syscall()) {
597
+ if (copy_from_user(&hdr32, argp, sizeof(hdr32)))
598
+ return -EFAULT;
599
+
600
+ *hdr = (struct sg_io_hdr) {
601
+ .interface_id = hdr32.interface_id,
602
+ .dxfer_direction = hdr32.dxfer_direction,
603
+ .cmd_len = hdr32.cmd_len,
604
+ .mx_sb_len = hdr32.mx_sb_len,
605
+ .iovec_count = hdr32.iovec_count,
606
+ .dxfer_len = hdr32.dxfer_len,
607
+ .dxferp = compat_ptr(hdr32.dxferp),
608
+ .cmdp = compat_ptr(hdr32.cmdp),
609
+ .sbp = compat_ptr(hdr32.sbp),
610
+ .timeout = hdr32.timeout,
611
+ .flags = hdr32.flags,
612
+ .pack_id = hdr32.pack_id,
613
+ .usr_ptr = compat_ptr(hdr32.usr_ptr),
614
+ .status = hdr32.status,
615
+ .masked_status = hdr32.masked_status,
616
+ .msg_status = hdr32.msg_status,
617
+ .sb_len_wr = hdr32.sb_len_wr,
618
+ .host_status = hdr32.host_status,
619
+ .driver_status = hdr32.driver_status,
620
+ .resid = hdr32.resid,
621
+ .duration = hdr32.duration,
622
+ .info = hdr32.info,
623
+ };
624
+
625
+ return 0;
626
+ }
627
+#endif
628
+
629
+ if (copy_from_user(hdr, argp, sizeof(*hdr)))
630
+ return -EFAULT;
631
+
632
+ return 0;
633
+}
634
+EXPORT_SYMBOL(get_sg_io_hdr);
635
+
636
+#ifdef CONFIG_COMPAT
637
+struct compat_cdrom_generic_command {
638
+ unsigned char cmd[CDROM_PACKET_SIZE];
639
+ compat_caddr_t buffer;
640
+ compat_uint_t buflen;
641
+ compat_int_t stat;
642
+ compat_caddr_t sense;
643
+ unsigned char data_direction;
644
+ unsigned char pad[3];
645
+ compat_int_t quiet;
646
+ compat_int_t timeout;
647
+ compat_caddr_t unused;
648
+};
649
+#endif
650
+
651
+static int scsi_get_cdrom_generic_arg(struct cdrom_generic_command *cgc,
652
+ const void __user *arg)
653
+{
654
+#ifdef CONFIG_COMPAT
655
+ if (in_compat_syscall()) {
656
+ struct compat_cdrom_generic_command cgc32;
657
+
658
+ if (copy_from_user(&cgc32, arg, sizeof(cgc32)))
659
+ return -EFAULT;
660
+
661
+ *cgc = (struct cdrom_generic_command) {
662
+ .buffer = compat_ptr(cgc32.buffer),
663
+ .buflen = cgc32.buflen,
664
+ .stat = cgc32.stat,
665
+ .sense = compat_ptr(cgc32.sense),
666
+ .data_direction = cgc32.data_direction,
667
+ .quiet = cgc32.quiet,
668
+ .timeout = cgc32.timeout,
669
+ .unused = compat_ptr(cgc32.unused),
670
+ };
671
+ memcpy(&cgc->cmd, &cgc32.cmd, CDROM_PACKET_SIZE);
672
+ return 0;
673
+ }
674
+#endif
675
+ if (copy_from_user(cgc, arg, sizeof(*cgc)))
676
+ return -EFAULT;
677
+
678
+ return 0;
679
+}
680
+
681
+static int scsi_put_cdrom_generic_arg(const struct cdrom_generic_command *cgc,
682
+ void __user *arg)
683
+{
684
+#ifdef CONFIG_COMPAT
685
+ if (in_compat_syscall()) {
686
+ struct compat_cdrom_generic_command cgc32 = {
687
+ .buffer = (uintptr_t)(cgc->buffer),
688
+ .buflen = cgc->buflen,
689
+ .stat = cgc->stat,
690
+ .sense = (uintptr_t)(cgc->sense),
691
+ .data_direction = cgc->data_direction,
692
+ .quiet = cgc->quiet,
693
+ .timeout = cgc->timeout,
694
+ .unused = (uintptr_t)(cgc->unused),
695
+ };
696
+ memcpy(&cgc32.cmd, &cgc->cmd, CDROM_PACKET_SIZE);
697
+
698
+ if (copy_to_user(arg, &cgc32, sizeof(cgc32)))
699
+ return -EFAULT;
700
+
701
+ return 0;
702
+ }
703
+#endif
704
+ if (copy_to_user(arg, cgc, sizeof(*cgc)))
705
+ return -EFAULT;
706
+
707
+ return 0;
708
+}
709
+
710
+static int scsi_cdrom_send_packet(struct request_queue *q,
711
+ struct gendisk *bd_disk,
712
+ fmode_t mode, void __user *arg)
713
+{
714
+ struct cdrom_generic_command cgc;
715
+ struct sg_io_hdr hdr;
716
+ int err;
717
+
718
+ err = scsi_get_cdrom_generic_arg(&cgc, arg);
719
+ if (err)
720
+ return err;
721
+
722
+ cgc.timeout = clock_t_to_jiffies(cgc.timeout);
723
+ memset(&hdr, 0, sizeof(hdr));
724
+ hdr.interface_id = 'S';
725
+ hdr.cmd_len = sizeof(cgc.cmd);
726
+ hdr.dxfer_len = cgc.buflen;
727
+ switch (cgc.data_direction) {
728
+ case CGC_DATA_UNKNOWN:
729
+ hdr.dxfer_direction = SG_DXFER_UNKNOWN;
730
+ break;
731
+ case CGC_DATA_WRITE:
732
+ hdr.dxfer_direction = SG_DXFER_TO_DEV;
733
+ break;
734
+ case CGC_DATA_READ:
735
+ hdr.dxfer_direction = SG_DXFER_FROM_DEV;
736
+ break;
737
+ case CGC_DATA_NONE:
738
+ hdr.dxfer_direction = SG_DXFER_NONE;
739
+ break;
740
+ default:
741
+ return -EINVAL;
742
+ }
743
+
744
+ hdr.dxferp = cgc.buffer;
745
+ hdr.sbp = cgc.sense;
746
+ if (hdr.sbp)
747
+ hdr.mx_sb_len = sizeof(struct request_sense);
748
+ hdr.timeout = jiffies_to_msecs(cgc.timeout);
749
+ hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd;
750
+ hdr.cmd_len = sizeof(cgc.cmd);
751
+
752
+ err = sg_io(q, bd_disk, &hdr, mode);
753
+ if (err == -EFAULT)
754
+ return -EFAULT;
755
+
756
+ if (hdr.status)
757
+ return -EIO;
758
+
759
+ cgc.stat = err;
760
+ cgc.buflen = hdr.resid;
761
+ if (scsi_put_cdrom_generic_arg(&cgc, arg))
762
+ return -EFAULT;
763
+
764
+ return err;
765
+}
766
+
559767 int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mode,
560768 unsigned int cmd, void __user *arg)
561769 {
....@@ -595,71 +803,20 @@
595803 case SG_IO: {
596804 struct sg_io_hdr hdr;
597805
598
- err = -EFAULT;
599
- if (copy_from_user(&hdr, arg, sizeof(hdr)))
600
- break;
601
- err = sg_io(q, bd_disk, &hdr, mode);
602
- if (err == -EFAULT)
603
- break;
604
-
605
- if (copy_to_user(arg, &hdr, sizeof(hdr)))
606
- err = -EFAULT;
607
- break;
608
- }
609
- case CDROM_SEND_PACKET: {
610
- struct cdrom_generic_command cgc;
611
- struct sg_io_hdr hdr;
612
-
613
- err = -EFAULT;
614
- if (copy_from_user(&cgc, arg, sizeof(cgc)))
615
- break;
616
- cgc.timeout = clock_t_to_jiffies(cgc.timeout);
617
- memset(&hdr, 0, sizeof(hdr));
618
- hdr.interface_id = 'S';
619
- hdr.cmd_len = sizeof(cgc.cmd);
620
- hdr.dxfer_len = cgc.buflen;
621
- err = 0;
622
- switch (cgc.data_direction) {
623
- case CGC_DATA_UNKNOWN:
624
- hdr.dxfer_direction = SG_DXFER_UNKNOWN;
625
- break;
626
- case CGC_DATA_WRITE:
627
- hdr.dxfer_direction = SG_DXFER_TO_DEV;
628
- break;
629
- case CGC_DATA_READ:
630
- hdr.dxfer_direction = SG_DXFER_FROM_DEV;
631
- break;
632
- case CGC_DATA_NONE:
633
- hdr.dxfer_direction = SG_DXFER_NONE;
634
- break;
635
- default:
636
- err = -EINVAL;
637
- }
806
+ err = get_sg_io_hdr(&hdr, arg);
638807 if (err)
639808 break;
640
-
641
- hdr.dxferp = cgc.buffer;
642
- hdr.sbp = cgc.sense;
643
- if (hdr.sbp)
644
- hdr.mx_sb_len = sizeof(struct request_sense);
645
- hdr.timeout = jiffies_to_msecs(cgc.timeout);
646
- hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd;
647
- hdr.cmd_len = sizeof(cgc.cmd);
648
-
649809 err = sg_io(q, bd_disk, &hdr, mode);
650810 if (err == -EFAULT)
651811 break;
652812
653
- if (hdr.status)
654
- err = -EIO;
655
-
656
- cgc.stat = err;
657
- cgc.buflen = hdr.resid;
658
- if (copy_to_user(arg, &cgc, sizeof(cgc)))
813
+ if (put_sg_io_hdr(&hdr, arg))
659814 err = -EFAULT;
660
-
661815 break;
662816 }
817
+ case CDROM_SEND_PACKET:
818
+ err = scsi_cdrom_send_packet(q, bd_disk, mode, arg);
819
+ break;
663820
664821 /*
665822 * old junk scsi send command ioctl
....@@ -688,7 +845,7 @@
688845
689846 int scsi_verify_blk_ioctl(struct block_device *bd, unsigned int cmd)
690847 {
691
- if (bd && bd == bd->bd_contains)
848
+ if (bd && !bdev_is_partition(bd))
692849 return 0;
693850
694851 if (capable(CAP_SYS_RAWIO))