Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

io_uring/rw: free potentially allocated iovec on cache put failure

If a read/write request goes through io_req_rw_cleanup() and has an
allocated iovec attached and fails to put to the rw_cache, then it may
end up with an unaccounted iovec pointer. Have io_rw_recycle() return
whether it recycled the request or not, and use that to gauge whether to
free a potential iovec or not.

Reviewed-by: Nitesh Shetty <nj.shetty@samsung.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

+11 -4
+11 -4
io_uring/rw.c
··· 144 144 return 0; 145 145 } 146 146 147 - static void io_rw_recycle(struct io_kiocb *req, unsigned int issue_flags) 147 + static bool io_rw_recycle(struct io_kiocb *req, unsigned int issue_flags) 148 148 { 149 149 struct io_async_rw *rw = req->async_data; 150 150 151 151 if (unlikely(issue_flags & IO_URING_F_UNLOCKED)) 152 - return; 152 + return false; 153 153 154 154 io_alloc_cache_vec_kasan(&rw->vec); 155 155 if (rw->vec.nr > IO_VEC_CACHE_SOFT_CAP) 156 156 io_vec_free(&rw->vec); 157 157 158 - if (io_alloc_cache_put(&req->ctx->rw_cache, rw)) 158 + if (io_alloc_cache_put(&req->ctx->rw_cache, rw)) { 159 159 io_req_async_data_clear(req, 0); 160 + return true; 161 + } 162 + return false; 160 163 } 161 164 162 165 static void io_req_rw_cleanup(struct io_kiocb *req, unsigned int issue_flags) ··· 193 190 */ 194 191 if (!(req->flags & (REQ_F_REISSUE | REQ_F_REFCOUNT))) { 195 192 req->flags &= ~REQ_F_NEED_CLEANUP; 196 - io_rw_recycle(req, issue_flags); 193 + if (!io_rw_recycle(req, issue_flags)) { 194 + struct io_async_rw *rw = req->async_data; 195 + 196 + io_vec_free(&rw->vec); 197 + } 197 198 } 198 199 } 199 200