@@ -81,7 +81,9 @@ static int __io_import_iovec(int ddir, struct io_kiocb *req,
8181{
8282 const struct io_issue_def * def = & io_issue_defs [req -> opcode ];
8383 struct io_rw * rw = io_kiocb_to_cmd (req , struct io_rw );
84+ struct iovec * iov ;
8485 void __user * buf ;
86+ int nr_segs , ret ;
8587 size_t sqe_len ;
8688
8789 buf = u64_to_user_ptr (rw -> addr );
@@ -99,9 +101,24 @@ static int __io_import_iovec(int ddir, struct io_kiocb *req,
99101 return import_ubuf (ddir , buf , sqe_len , & io -> iter );
100102 }
101103
102- io -> free_iovec = io -> fast_iov ;
103- return __import_iovec (ddir , buf , sqe_len , UIO_FASTIOV , & io -> free_iovec ,
104- & io -> iter , req -> ctx -> compat );
104+ if (io -> free_iovec ) {
105+ nr_segs = io -> free_iov_nr ;
106+ iov = io -> free_iovec ;
107+ } else {
108+ iov = & io -> fast_iov ;
109+ nr_segs = 1 ;
110+ }
111+ ret = __import_iovec (ddir , buf , sqe_len , nr_segs , & iov , & io -> iter ,
112+ req -> ctx -> compat );
113+ if (unlikely (ret < 0 ))
114+ return ret ;
115+ if (iov ) {
116+ req -> flags |= REQ_F_NEED_CLEANUP ;
117+ io -> free_iov_nr = io -> iter .nr_segs ;
118+ kfree (io -> free_iovec );
119+ io -> free_iovec = iov ;
120+ }
121+ return 0 ;
105122}
106123
107124static inline int io_import_iovec (int rw , struct io_kiocb * req ,
@@ -122,19 +139,24 @@ static void io_rw_iovec_free(struct io_async_rw *rw)
122139{
123140 if (rw -> free_iovec ) {
124141 kfree (rw -> free_iovec );
142+ rw -> free_iov_nr = 0 ;
125143 rw -> free_iovec = NULL ;
126144 }
127145}
128146
129147static void io_rw_recycle (struct io_kiocb * req , unsigned int issue_flags )
130148{
131149 struct io_async_rw * rw = req -> async_data ;
150+ struct iovec * iov ;
132151
133152 if (unlikely (issue_flags & IO_URING_F_UNLOCKED )) {
134153 io_rw_iovec_free (rw );
135154 return ;
136155 }
156+ iov = rw -> free_iovec ;
137157 if (io_alloc_cache_put (& req -> ctx -> rw_cache , & rw -> cache )) {
158+ if (iov )
159+ kasan_mempool_poison_object (iov );
138160 req -> async_data = NULL ;
139161 req -> flags &= ~REQ_F_ASYNC_DATA ;
140162 }
@@ -184,15 +206,21 @@ static int io_rw_alloc_async(struct io_kiocb *req)
184206 entry = io_alloc_cache_get (& ctx -> rw_cache );
185207 if (entry ) {
186208 rw = container_of (entry , struct io_async_rw , cache );
209+ if (rw -> free_iovec ) {
210+ kasan_mempool_unpoison_object (rw -> free_iovec ,
211+ rw -> free_iov_nr * sizeof (struct iovec ));
212+ req -> flags |= REQ_F_NEED_CLEANUP ;
213+ }
187214 req -> flags |= REQ_F_ASYNC_DATA ;
188215 req -> async_data = rw ;
189216 goto done ;
190217 }
191218
192219 if (!io_alloc_async_data (req )) {
193220 rw = req -> async_data ;
194- done :
195221 rw -> free_iovec = NULL ;
222+ rw -> free_iov_nr = 0 ;
223+ done :
196224 rw -> bytes_done = 0 ;
197225 return 0 ;
198226 }
@@ -1145,6 +1173,10 @@ void io_rw_cache_free(struct io_cache_entry *entry)
11451173 struct io_async_rw * rw ;
11461174
11471175 rw = container_of (entry , struct io_async_rw , cache );
1148- kfree (rw -> free_iovec );
1176+ if (rw -> free_iovec ) {
1177+ kasan_mempool_unpoison_object (rw -> free_iovec ,
1178+ rw -> free_iov_nr * sizeof (struct iovec ));
1179+ io_rw_iovec_free (rw );
1180+ }
11491181 kfree (rw );
11501182}
0 commit comments