8
8
#include <linux/io_uring.h>
9
9
#include "nvme.h"
10
10
11
+ enum {
12
+ NVME_IOCTL_VEC = (1 << 0 ),
13
+ NVME_IOCTL_PARTITION = (1 << 1 ),
14
+ };
15
+
11
16
static bool nvme_cmd_allowed (struct nvme_ns * ns , struct nvme_command * c ,
12
- fmode_t mode )
17
+ unsigned int flags , fmode_t mode )
13
18
{
14
19
u32 effects ;
15
20
16
21
if (capable (CAP_SYS_ADMIN ))
17
22
return true;
18
23
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
+
19
31
/*
20
32
* Do not allow unprivileged processes to send vendor specific or fabrics
21
33
* commands as we can't be sure about their effects.
@@ -150,7 +162,7 @@ static struct request *nvme_alloc_user_request(struct request_queue *q,
150
162
static int nvme_map_user_request (struct request * req , u64 ubuffer ,
151
163
unsigned bufflen , void __user * meta_buffer , unsigned meta_len ,
152
164
u32 meta_seed , void * * metap , struct io_uring_cmd * ioucmd ,
153
- bool vec )
165
+ unsigned int flags )
154
166
{
155
167
struct request_queue * q = req -> q ;
156
168
struct nvme_ns * ns = q -> queuedata ;
@@ -163,7 +175,7 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
163
175
struct iov_iter iter ;
164
176
165
177
/* fixedbufs is only for non-vectored io */
166
- if (WARN_ON_ONCE (vec ))
178
+ if (WARN_ON_ONCE (flags & NVME_IOCTL_VEC ))
167
179
return - EINVAL ;
168
180
ret = io_uring_cmd_import_fixed (ubuffer , bufflen ,
169
181
rq_data_dir (req ), & iter , ioucmd );
@@ -172,8 +184,8 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
172
184
ret = blk_rq_map_user_iov (q , req , NULL , & iter , GFP_KERNEL );
173
185
} else {
174
186
ret = blk_rq_map_user_io (req , NULL , nvme_to_user_ptr (ubuffer ),
175
- bufflen , GFP_KERNEL , vec , 0 , 0 ,
176
- rq_data_dir (req ));
187
+ bufflen , GFP_KERNEL , flags & NVME_IOCTL_VEC , 0 ,
188
+ 0 , rq_data_dir (req ));
177
189
}
178
190
179
191
if (ret )
@@ -203,9 +215,9 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
203
215
}
204
216
205
217
static int nvme_submit_user_cmd (struct request_queue * q ,
206
- struct nvme_command * cmd , u64 ubuffer ,
207
- unsigned bufflen , void __user * meta_buffer , unsigned meta_len ,
208
- u32 meta_seed , u64 * result , unsigned timeout , bool vec )
218
+ struct nvme_command * cmd , u64 ubuffer , unsigned bufflen ,
219
+ void __user * meta_buffer , unsigned meta_len , u32 meta_seed ,
220
+ u64 * result , unsigned timeout , unsigned int flags )
209
221
{
210
222
struct nvme_ctrl * ctrl ;
211
223
struct request * req ;
@@ -221,7 +233,7 @@ static int nvme_submit_user_cmd(struct request_queue *q,
221
233
req -> timeout = timeout ;
222
234
if (ubuffer && bufflen ) {
223
235
ret = nvme_map_user_request (req , ubuffer , bufflen , meta_buffer ,
224
- meta_len , meta_seed , & meta , NULL , vec );
236
+ meta_len , meta_seed , & meta , NULL , flags );
225
237
if (ret )
226
238
return ret ;
227
239
}
@@ -304,10 +316,8 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
304
316
c .rw .apptag = cpu_to_le16 (io .apptag );
305
317
c .rw .appmask = cpu_to_le16 (io .appmask );
306
318
307
- return nvme_submit_user_cmd (ns -> queue , & c ,
308
- io .addr , length ,
309
- metadata , meta_len , lower_32_bits (io .slba ), NULL , 0 ,
310
- false);
319
+ return nvme_submit_user_cmd (ns -> queue , & c , io .addr , length , metadata ,
320
+ meta_len , lower_32_bits (io .slba ), NULL , 0 , 0 );
311
321
}
312
322
313
323
static bool nvme_validate_passthru_nsid (struct nvme_ctrl * ctrl ,
@@ -325,7 +335,8 @@ static bool nvme_validate_passthru_nsid(struct nvme_ctrl *ctrl,
325
335
}
326
336
327
337
static int nvme_user_cmd (struct nvme_ctrl * ctrl , struct nvme_ns * ns ,
328
- struct nvme_passthru_cmd __user * ucmd , fmode_t mode )
338
+ struct nvme_passthru_cmd __user * ucmd , unsigned int flags ,
339
+ fmode_t mode )
329
340
{
330
341
struct nvme_passthru_cmd cmd ;
331
342
struct nvme_command c ;
@@ -353,16 +364,15 @@ static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
353
364
c .common .cdw14 = cpu_to_le32 (cmd .cdw14 );
354
365
c .common .cdw15 = cpu_to_le32 (cmd .cdw15 );
355
366
356
- if (!nvme_cmd_allowed (ns , & c , mode ))
367
+ if (!nvme_cmd_allowed (ns , & c , 0 , mode ))
357
368
return - EACCES ;
358
369
359
370
if (cmd .timeout_ms )
360
371
timeout = msecs_to_jiffies (cmd .timeout_ms );
361
372
362
373
status = nvme_submit_user_cmd (ns ? ns -> queue : ctrl -> admin_q , & c ,
363
- cmd .addr , cmd .data_len ,
364
- nvme_to_user_ptr (cmd .metadata ), cmd .metadata_len ,
365
- 0 , & result , timeout , false);
374
+ cmd .addr , cmd .data_len , nvme_to_user_ptr (cmd .metadata ),
375
+ cmd .metadata_len , 0 , & result , timeout , 0 );
366
376
367
377
if (status >= 0 ) {
368
378
if (put_user (result , & ucmd -> result ))
@@ -373,8 +383,8 @@ static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
373
383
}
374
384
375
385
static int nvme_user_cmd64 (struct nvme_ctrl * ctrl , struct nvme_ns * ns ,
376
- struct nvme_passthru_cmd64 __user * ucmd , bool vec ,
377
- fmode_t mode )
386
+ struct nvme_passthru_cmd64 __user * ucmd , unsigned int flags ,
387
+ fmode_t mode )
378
388
{
379
389
struct nvme_passthru_cmd64 cmd ;
380
390
struct nvme_command c ;
@@ -401,16 +411,15 @@ static int nvme_user_cmd64(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
401
411
c .common .cdw14 = cpu_to_le32 (cmd .cdw14 );
402
412
c .common .cdw15 = cpu_to_le32 (cmd .cdw15 );
403
413
404
- if (!nvme_cmd_allowed (ns , & c , mode ))
414
+ if (!nvme_cmd_allowed (ns , & c , flags , mode ))
405
415
return - EACCES ;
406
416
407
417
if (cmd .timeout_ms )
408
418
timeout = msecs_to_jiffies (cmd .timeout_ms );
409
419
410
420
status = nvme_submit_user_cmd (ns ? ns -> queue : ctrl -> admin_q , & c ,
411
- cmd .addr , cmd .data_len ,
412
- nvme_to_user_ptr (cmd .metadata ), cmd .metadata_len ,
413
- 0 , & cmd .result , timeout , vec );
421
+ cmd .addr , cmd .data_len , nvme_to_user_ptr (cmd .metadata ),
422
+ cmd .metadata_len , 0 , & cmd .result , timeout , flags );
414
423
415
424
if (status >= 0 ) {
416
425
if (put_user (cmd .result , & ucmd -> result ))
@@ -571,7 +580,7 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
571
580
c .common .cdw14 = cpu_to_le32 (READ_ONCE (cmd -> cdw14 ));
572
581
c .common .cdw15 = cpu_to_le32 (READ_ONCE (cmd -> cdw15 ));
573
582
574
- if (!nvme_cmd_allowed (ns , & c , ioucmd -> file -> f_mode ))
583
+ if (!nvme_cmd_allowed (ns , & c , 0 , ioucmd -> file -> f_mode ))
575
584
return - EACCES ;
576
585
577
586
d .metadata = READ_ONCE (cmd -> metadata );
@@ -641,9 +650,9 @@ static int nvme_ctrl_ioctl(struct nvme_ctrl *ctrl, unsigned int cmd,
641
650
{
642
651
switch (cmd ) {
643
652
case NVME_IOCTL_ADMIN_CMD :
644
- return nvme_user_cmd (ctrl , NULL , argp , mode );
653
+ return nvme_user_cmd (ctrl , NULL , argp , 0 , mode );
645
654
case NVME_IOCTL_ADMIN64_CMD :
646
- return nvme_user_cmd64 (ctrl , NULL , argp , false , mode );
655
+ return nvme_user_cmd64 (ctrl , NULL , argp , 0 , mode );
647
656
default :
648
657
return sed_ioctl (ctrl -> opal_dev , cmd , argp );
649
658
}
@@ -668,14 +677,14 @@ struct nvme_user_io32 {
668
677
#endif /* COMPAT_FOR_U64_ALIGNMENT */
669
678
670
679
static 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 )
672
681
{
673
682
switch (cmd ) {
674
683
case NVME_IOCTL_ID :
675
684
force_successful_syscall_return ();
676
685
return ns -> head -> ns_id ;
677
686
case NVME_IOCTL_IO_CMD :
678
- return nvme_user_cmd (ns -> ctrl , ns , argp , mode );
687
+ return nvme_user_cmd (ns -> ctrl , ns , argp , flags , mode );
679
688
/*
680
689
* struct nvme_user_io can have different padding on some 32-bit ABIs.
681
690
* Just accept the compat version as all fields that are used are the
@@ -686,37 +695,40 @@ static int nvme_ns_ioctl(struct nvme_ns *ns, unsigned int cmd,
686
695
#endif
687
696
case NVME_IOCTL_SUBMIT_IO :
688
697
return nvme_submit_io (ns , argp );
689
- case NVME_IOCTL_IO64_CMD :
690
- return nvme_user_cmd64 (ns -> ctrl , ns , argp , false, mode );
691
698
case NVME_IOCTL_IO64_CMD_VEC :
692
- return nvme_user_cmd64 (ns -> ctrl , ns , argp , true, mode );
699
+ flags |= NVME_IOCTL_VEC ;
700
+ fallthrough ;
701
+ case NVME_IOCTL_IO64_CMD :
702
+ return nvme_user_cmd64 (ns -> ctrl , ns , argp , flags , mode );
693
703
default :
694
704
return - ENOTTY ;
695
705
}
696
706
}
697
707
698
- static int __nvme_ioctl (struct nvme_ns * ns , unsigned int cmd , void __user * arg ,
699
- fmode_t mode )
700
- {
701
- if (is_ctrl_ioctl (cmd ))
702
- return nvme_ctrl_ioctl (ns -> ctrl , cmd , arg , mode );
703
- return nvme_ns_ioctl (ns , cmd , arg , mode );
704
- }
705
-
706
708
int nvme_ioctl (struct block_device * bdev , fmode_t mode ,
707
709
unsigned int cmd , unsigned long arg )
708
710
{
709
711
struct nvme_ns * ns = bdev -> bd_disk -> private_data ;
712
+ void __user * argp = (void __user * )arg ;
713
+ unsigned int flags = 0 ;
710
714
711
- return __nvme_ioctl (ns , cmd , (void __user * )arg , mode );
715
+ if (bdev_is_partition (bdev ))
716
+ flags |= NVME_IOCTL_PARTITION ;
717
+
718
+ if (is_ctrl_ioctl (cmd ))
719
+ return nvme_ctrl_ioctl (ns -> ctrl , cmd , argp , mode );
720
+ return nvme_ns_ioctl (ns , cmd , argp , flags , mode );
712
721
}
713
722
714
723
long nvme_ns_chr_ioctl (struct file * file , unsigned int cmd , unsigned long arg )
715
724
{
716
725
struct nvme_ns * ns =
717
726
container_of (file_inode (file )-> i_cdev , struct nvme_ns , cdev );
727
+ void __user * argp = (void __user * )arg ;
718
728
719
- return __nvme_ioctl (ns , cmd , (void __user * )arg , file -> f_mode );
729
+ if (is_ctrl_ioctl (cmd ))
730
+ return nvme_ctrl_ioctl (ns -> ctrl , cmd , argp , file -> f_mode );
731
+ return nvme_ns_ioctl (ns , cmd , argp , 0 , file -> f_mode );
720
732
}
721
733
722
734
static int nvme_uring_cmd_checks (unsigned int issue_flags )
@@ -806,6 +818,10 @@ int nvme_ns_head_ioctl(struct block_device *bdev, fmode_t mode,
806
818
void __user * argp = (void __user * )arg ;
807
819
struct nvme_ns * ns ;
808
820
int srcu_idx , ret = - EWOULDBLOCK ;
821
+ unsigned int flags = 0 ;
822
+
823
+ if (bdev_is_partition (bdev ))
824
+ flags |= NVME_IOCTL_PARTITION ;
809
825
810
826
srcu_idx = srcu_read_lock (& head -> srcu );
811
827
ns = nvme_find_path (head );
@@ -821,7 +837,7 @@ int nvme_ns_head_ioctl(struct block_device *bdev, fmode_t mode,
821
837
return nvme_ns_head_ctrl_ioctl (ns , cmd , argp , head , srcu_idx ,
822
838
mode );
823
839
824
- ret = nvme_ns_ioctl (ns , cmd , argp , mode );
840
+ ret = nvme_ns_ioctl (ns , cmd , argp , flags , mode );
825
841
out_unlock :
826
842
srcu_read_unlock (& head -> srcu , srcu_idx );
827
843
return ret ;
@@ -846,7 +862,7 @@ long nvme_ns_head_chr_ioctl(struct file *file, unsigned int cmd,
846
862
return nvme_ns_head_ctrl_ioctl (ns , cmd , argp , head , srcu_idx ,
847
863
file -> f_mode );
848
864
849
- ret = nvme_ns_ioctl (ns , cmd , argp , file -> f_mode );
865
+ ret = nvme_ns_ioctl (ns , cmd , argp , 0 , file -> f_mode );
850
866
out_unlock :
851
867
srcu_read_unlock (& head -> srcu , srcu_idx );
852
868
return ret ;
@@ -945,7 +961,7 @@ static int nvme_dev_user_cmd(struct nvme_ctrl *ctrl, void __user *argp,
945
961
kref_get (& ns -> kref );
946
962
up_read (& ctrl -> namespaces_rwsem );
947
963
948
- ret = nvme_user_cmd (ctrl , ns , argp , mode );
964
+ ret = nvme_user_cmd (ctrl , ns , argp , 0 , mode );
949
965
nvme_put_ns (ns );
950
966
return ret ;
951
967
@@ -962,9 +978,9 @@ long nvme_dev_ioctl(struct file *file, unsigned int cmd,
962
978
963
979
switch (cmd ) {
964
980
case NVME_IOCTL_ADMIN_CMD :
965
- return nvme_user_cmd (ctrl , NULL , argp , file -> f_mode );
981
+ return nvme_user_cmd (ctrl , NULL , argp , 0 , file -> f_mode );
966
982
case NVME_IOCTL_ADMIN64_CMD :
967
- return nvme_user_cmd64 (ctrl , NULL , argp , false , file -> f_mode );
983
+ return nvme_user_cmd64 (ctrl , NULL , argp , 0 , file -> f_mode );
968
984
case NVME_IOCTL_IO_CMD :
969
985
return nvme_dev_user_cmd (ctrl , argp , file -> f_mode );
970
986
case NVME_IOCTL_RESET :
0 commit comments