1010
1111enum {
1212 NVME_IOCTL_VEC = (1 << 0 ),
13+ NVME_IOCTL_PARTITION = (1 << 1 ),
1314};
1415
1516static bool nvme_cmd_allowed (struct nvme_ns * ns , struct nvme_command * c ,
16- fmode_t mode )
17+ unsigned int flags , fmode_t mode )
1718{
1819 u32 effects ;
1920
2021 if (capable (CAP_SYS_ADMIN ))
2122 return true;
2223
24+ /*
25+ * Do not allow unprivileged passthrough on partitions, as that allows an
26+ * escape from the containment of the partition.
27+ */
28+ if (flags & NVME_IOCTL_PARTITION )
29+ return false;
30+
2331 /*
2432 * Do not allow unprivileged processes to send vendor specific or fabrics
2533 * commands as we can't be sure about their effects.
@@ -327,7 +335,8 @@ static bool nvme_validate_passthru_nsid(struct nvme_ctrl *ctrl,
327335}
328336
329337static int nvme_user_cmd (struct nvme_ctrl * ctrl , struct nvme_ns * ns ,
330- struct nvme_passthru_cmd __user * ucmd , fmode_t mode )
338+ struct nvme_passthru_cmd __user * ucmd , unsigned int flags ,
339+ fmode_t mode )
331340{
332341 struct nvme_passthru_cmd cmd ;
333342 struct nvme_command c ;
@@ -355,7 +364,7 @@ static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
355364 c .common .cdw14 = cpu_to_le32 (cmd .cdw14 );
356365 c .common .cdw15 = cpu_to_le32 (cmd .cdw15 );
357366
358- if (!nvme_cmd_allowed (ns , & c , mode ))
367+ if (!nvme_cmd_allowed (ns , & c , 0 , mode ))
359368 return - EACCES ;
360369
361370 if (cmd .timeout_ms )
@@ -402,7 +411,7 @@ static int nvme_user_cmd64(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
402411 c .common .cdw14 = cpu_to_le32 (cmd .cdw14 );
403412 c .common .cdw15 = cpu_to_le32 (cmd .cdw15 );
404413
405- if (!nvme_cmd_allowed (ns , & c , mode ))
414+ if (!nvme_cmd_allowed (ns , & c , flags , mode ))
406415 return - EACCES ;
407416
408417 if (cmd .timeout_ms )
@@ -571,7 +580,7 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
571580 c .common .cdw14 = cpu_to_le32 (READ_ONCE (cmd -> cdw14 ));
572581 c .common .cdw15 = cpu_to_le32 (READ_ONCE (cmd -> cdw15 ));
573582
574- if (!nvme_cmd_allowed (ns , & c , ioucmd -> file -> f_mode ))
583+ if (!nvme_cmd_allowed (ns , & c , 0 , ioucmd -> file -> f_mode ))
575584 return - EACCES ;
576585
577586 d .metadata = READ_ONCE (cmd -> metadata );
@@ -641,7 +650,7 @@ static int nvme_ctrl_ioctl(struct nvme_ctrl *ctrl, unsigned int cmd,
641650{
642651 switch (cmd ) {
643652 case NVME_IOCTL_ADMIN_CMD :
644- return nvme_user_cmd (ctrl , NULL , argp , mode );
653+ return nvme_user_cmd (ctrl , NULL , argp , 0 , mode );
645654 case NVME_IOCTL_ADMIN64_CMD :
646655 return nvme_user_cmd64 (ctrl , NULL , argp , 0 , mode );
647656 default :
@@ -668,16 +677,14 @@ struct nvme_user_io32 {
668677#endif /* COMPAT_FOR_U64_ALIGNMENT */
669678
670679static int nvme_ns_ioctl (struct nvme_ns * ns , unsigned int cmd ,
671- void __user * argp , fmode_t mode )
680+ void __user * argp , unsigned int flags , fmode_t mode )
672681{
673- unsigned int flags = 0 ;
674-
675682 switch (cmd ) {
676683 case NVME_IOCTL_ID :
677684 force_successful_syscall_return ();
678685 return ns -> head -> ns_id ;
679686 case NVME_IOCTL_IO_CMD :
680- return nvme_user_cmd (ns -> ctrl , ns , argp , mode );
687+ return nvme_user_cmd (ns -> ctrl , ns , argp , flags , mode );
681688 /*
682689 * struct nvme_user_io can have different padding on some 32-bit ABIs.
683690 * Just accept the compat version as all fields that are used are the
@@ -703,10 +710,14 @@ int nvme_ioctl(struct block_device *bdev, fmode_t mode,
703710{
704711 struct nvme_ns * ns = bdev -> bd_disk -> private_data ;
705712 void __user * argp = (void __user * )arg ;
713+ unsigned int flags = 0 ;
714+
715+ if (bdev_is_partition (bdev ))
716+ flags |= NVME_IOCTL_PARTITION ;
706717
707718 if (is_ctrl_ioctl (cmd ))
708719 return nvme_ctrl_ioctl (ns -> ctrl , cmd , argp , mode );
709- return nvme_ns_ioctl (ns , cmd , argp , mode );
720+ return nvme_ns_ioctl (ns , cmd , argp , flags , mode );
710721}
711722
712723long nvme_ns_chr_ioctl (struct file * file , unsigned int cmd , unsigned long arg )
@@ -717,7 +728,7 @@ long nvme_ns_chr_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
717728
718729 if (is_ctrl_ioctl (cmd ))
719730 return nvme_ctrl_ioctl (ns -> ctrl , cmd , argp , file -> f_mode );
720- return nvme_ns_ioctl (ns , cmd , argp , file -> f_mode );
731+ return nvme_ns_ioctl (ns , cmd , argp , 0 , file -> f_mode );
721732}
722733
723734static int nvme_uring_cmd_checks (unsigned int issue_flags )
@@ -807,6 +818,10 @@ int nvme_ns_head_ioctl(struct block_device *bdev, fmode_t mode,
807818 void __user * argp = (void __user * )arg ;
808819 struct nvme_ns * ns ;
809820 int srcu_idx , ret = - EWOULDBLOCK ;
821+ unsigned int flags = 0 ;
822+
823+ if (bdev_is_partition (bdev ))
824+ flags |= NVME_IOCTL_PARTITION ;
810825
811826 srcu_idx = srcu_read_lock (& head -> srcu );
812827 ns = nvme_find_path (head );
@@ -822,7 +837,7 @@ int nvme_ns_head_ioctl(struct block_device *bdev, fmode_t mode,
822837 return nvme_ns_head_ctrl_ioctl (ns , cmd , argp , head , srcu_idx ,
823838 mode );
824839
825- ret = nvme_ns_ioctl (ns , cmd , argp , mode );
840+ ret = nvme_ns_ioctl (ns , cmd , argp , flags , mode );
826841out_unlock :
827842 srcu_read_unlock (& head -> srcu , srcu_idx );
828843 return ret ;
@@ -847,7 +862,7 @@ long nvme_ns_head_chr_ioctl(struct file *file, unsigned int cmd,
847862 return nvme_ns_head_ctrl_ioctl (ns , cmd , argp , head , srcu_idx ,
848863 file -> f_mode );
849864
850- ret = nvme_ns_ioctl (ns , cmd , argp , file -> f_mode );
865+ ret = nvme_ns_ioctl (ns , cmd , argp , 0 , file -> f_mode );
851866out_unlock :
852867 srcu_read_unlock (& head -> srcu , srcu_idx );
853868 return ret ;
@@ -946,7 +961,7 @@ static int nvme_dev_user_cmd(struct nvme_ctrl *ctrl, void __user *argp,
946961 kref_get (& ns -> kref );
947962 up_read (& ctrl -> namespaces_rwsem );
948963
949- ret = nvme_user_cmd (ctrl , ns , argp , mode );
964+ ret = nvme_user_cmd (ctrl , ns , argp , 0 , mode );
950965 nvme_put_ns (ns );
951966 return ret ;
952967
@@ -963,7 +978,7 @@ long nvme_dev_ioctl(struct file *file, unsigned int cmd,
963978
964979 switch (cmd ) {
965980 case NVME_IOCTL_ADMIN_CMD :
966- return nvme_user_cmd (ctrl , NULL , argp , file -> f_mode );
981+ return nvme_user_cmd (ctrl , NULL , argp , 0 , file -> f_mode );
967982 case NVME_IOCTL_ADMIN64_CMD :
968983 return nvme_user_cmd64 (ctrl , NULL , argp , 0 , file -> f_mode );
969984 case NVME_IOCTL_IO_CMD :
0 commit comments