@@ -85,31 +85,6 @@ static int io_account_mem(struct io_ring_ctx *ctx, unsigned long nr_pages)
8585 return 0 ;
8686}
8787
88- static int io_copy_iov (struct io_ring_ctx * ctx , struct iovec * dst ,
89- void __user * arg , unsigned index )
90- {
91- struct iovec __user * src ;
92-
93- #ifdef CONFIG_COMPAT
94- if (ctx -> compat ) {
95- struct compat_iovec __user * ciovs ;
96- struct compat_iovec ciov ;
97-
98- ciovs = (struct compat_iovec __user * ) arg ;
99- if (copy_from_user (& ciov , & ciovs [index ], sizeof (ciov )))
100- return - EFAULT ;
101-
102- dst -> iov_base = u64_to_user_ptr ((u64 )ciov .iov_base );
103- dst -> iov_len = ciov .iov_len ;
104- return 0 ;
105- }
106- #endif
107- src = (struct iovec __user * ) arg ;
108- if (copy_from_user (dst , & src [index ], sizeof (* dst )))
109- return - EFAULT ;
110- return 0 ;
111- }
112-
11388static int io_buffer_validate (struct iovec * iov )
11489{
11590 unsigned long tmp , acct_len = iov -> iov_len + (PAGE_SIZE - 1 );
@@ -419,8 +394,9 @@ static int __io_sqe_buffers_update(struct io_ring_ctx *ctx,
419394 struct io_uring_rsrc_update2 * up ,
420395 unsigned int nr_args )
421396{
397+ struct iovec __user * uvec = u64_to_user_ptr (up -> data );
422398 u64 __user * tags = u64_to_user_ptr (up -> tags );
423- struct iovec iov , __user * iovs = u64_to_user_ptr ( up -> data ) ;
399+ struct iovec fast_iov , * iov ;
424400 struct page * last_hpage = NULL ;
425401 __u32 done ;
426402 int i , err ;
@@ -434,21 +410,23 @@ static int __io_sqe_buffers_update(struct io_ring_ctx *ctx,
434410 struct io_mapped_ubuf * imu ;
435411 u64 tag = 0 ;
436412
437- err = io_copy_iov (ctx , & iov , iovs , done );
438- if (err )
413+ iov = iovec_from_user (& uvec [done ], 1 , 1 , & fast_iov , ctx -> compat );
414+ if (IS_ERR (iov )) {
415+ err = PTR_ERR (iov );
439416 break ;
417+ }
440418 if (tags && copy_from_user (& tag , & tags [done ], sizeof (tag ))) {
441419 err = - EFAULT ;
442420 break ;
443421 }
444- err = io_buffer_validate (& iov );
422+ err = io_buffer_validate (iov );
445423 if (err )
446424 break ;
447- if (!iov . iov_base && tag ) {
425+ if (!iov -> iov_base && tag ) {
448426 err = - EINVAL ;
449427 break ;
450428 }
451- err = io_sqe_buffer_register (ctx , & iov , & imu , & last_hpage );
429+ err = io_sqe_buffer_register (ctx , iov , & imu , & last_hpage );
452430 if (err )
453431 break ;
454432
@@ -970,8 +948,9 @@ int io_sqe_buffers_register(struct io_ring_ctx *ctx, void __user *arg,
970948{
971949 struct page * last_hpage = NULL ;
972950 struct io_rsrc_data * data ;
951+ struct iovec fast_iov , * iov = & fast_iov ;
952+ const struct iovec __user * uvec = (struct iovec * __user ) arg ;
973953 int i , ret ;
974- struct iovec iov ;
975954
976955 BUILD_BUG_ON (IORING_MAX_REG_BUFFERS >= (1u << 16 ));
977956
@@ -988,24 +967,27 @@ int io_sqe_buffers_register(struct io_ring_ctx *ctx, void __user *arg,
988967 return ret ;
989968 }
990969
970+ if (!arg )
971+ memset (iov , 0 , sizeof (* iov ));
972+
991973 for (i = 0 ; i < nr_args ; i ++ , ctx -> nr_user_bufs ++ ) {
992974 if (arg ) {
993- ret = io_copy_iov (ctx , & iov , arg , i );
994- if (ret )
975+ iov = iovec_from_user (& uvec [i ], 1 , 1 , & fast_iov , ctx -> compat );
976+ if (IS_ERR (iov )) {
977+ ret = PTR_ERR (iov );
995978 break ;
996- ret = io_buffer_validate (& iov );
979+ }
980+ ret = io_buffer_validate (iov );
997981 if (ret )
998982 break ;
999- } else {
1000- memset (& iov , 0 , sizeof (iov ));
1001983 }
1002984
1003- if (!iov . iov_base && * io_get_tag_slot (data , i )) {
985+ if (!iov -> iov_base && * io_get_tag_slot (data , i )) {
1004986 ret = - EINVAL ;
1005987 break ;
1006988 }
1007989
1008- ret = io_sqe_buffer_register (ctx , & iov , & ctx -> user_bufs [i ],
990+ ret = io_sqe_buffer_register (ctx , iov , & ctx -> user_bufs [i ],
1009991 & last_hpage );
1010992 if (ret )
1011993 break ;
0 commit comments