@@ -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 );
@@ -420,8 +395,9 @@ static int __io_sqe_buffers_update(struct io_ring_ctx *ctx,
420395 struct io_uring_rsrc_update2 * up ,
421396 unsigned int nr_args )
422397{
398+ struct iovec __user * uvec = u64_to_user_ptr (up -> data );
423399 u64 __user * tags = u64_to_user_ptr (up -> tags );
424- struct iovec iov , __user * iovs = u64_to_user_ptr ( up -> data ) ;
400+ struct iovec fast_iov , * iov ;
425401 struct page * last_hpage = NULL ;
426402 __u32 done ;
427403 int i , err ;
@@ -435,21 +411,23 @@ static int __io_sqe_buffers_update(struct io_ring_ctx *ctx,
435411 struct io_mapped_ubuf * imu ;
436412 u64 tag = 0 ;
437413
438- err = io_copy_iov (ctx , & iov , iovs , done );
439- if (err )
414+ iov = iovec_from_user (& uvec [done ], 1 , 1 , & fast_iov , ctx -> compat );
415+ if (IS_ERR (iov )) {
416+ err = PTR_ERR (iov );
440417 break ;
418+ }
441419 if (tags && copy_from_user (& tag , & tags [done ], sizeof (tag ))) {
442420 err = - EFAULT ;
443421 break ;
444422 }
445- err = io_buffer_validate (& iov );
423+ err = io_buffer_validate (iov );
446424 if (err )
447425 break ;
448- if (!iov . iov_base && tag ) {
426+ if (!iov -> iov_base && tag ) {
449427 err = - EINVAL ;
450428 break ;
451429 }
452- err = io_sqe_buffer_register (ctx , & iov , & imu , & last_hpage );
430+ err = io_sqe_buffer_register (ctx , iov , & imu , & last_hpage );
453431 if (err )
454432 break ;
455433
@@ -971,8 +949,9 @@ int io_sqe_buffers_register(struct io_ring_ctx *ctx, void __user *arg,
971949{
972950 struct page * last_hpage = NULL ;
973951 struct io_rsrc_data * data ;
952+ struct iovec fast_iov , * iov = & fast_iov ;
953+ const struct iovec __user * uvec = (struct iovec * __user ) arg ;
974954 int i , ret ;
975- struct iovec iov ;
976955
977956 BUILD_BUG_ON (IORING_MAX_REG_BUFFERS >= (1u << 16 ));
978957
@@ -989,24 +968,27 @@ int io_sqe_buffers_register(struct io_ring_ctx *ctx, void __user *arg,
989968 return ret ;
990969 }
991970
971+ if (!arg )
972+ memset (iov , 0 , sizeof (* iov ));
973+
992974 for (i = 0 ; i < nr_args ; i ++ , ctx -> nr_user_bufs ++ ) {
993975 if (arg ) {
994- ret = io_copy_iov (ctx , & iov , arg , i );
995- if (ret )
976+ iov = iovec_from_user (& uvec [i ], 1 , 1 , & fast_iov , ctx -> compat );
977+ if (IS_ERR (iov )) {
978+ ret = PTR_ERR (iov );
996979 break ;
997- ret = io_buffer_validate (& iov );
980+ }
981+ ret = io_buffer_validate (iov );
998982 if (ret )
999983 break ;
1000- } else {
1001- memset (& iov , 0 , sizeof (iov ));
1002984 }
1003985
1004- if (!iov . iov_base && * io_get_tag_slot (data , i )) {
986+ if (!iov -> iov_base && * io_get_tag_slot (data , i )) {
1005987 ret = - EINVAL ;
1006988 break ;
1007989 }
1008990
1009- ret = io_sqe_buffer_register (ctx , & iov , & ctx -> user_bufs [i ],
991+ ret = io_sqe_buffer_register (ctx , iov , & ctx -> user_bufs [i ],
1010992 & last_hpage );
1011993 if (ret )
1012994 break ;
0 commit comments