From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Jens Axboe <axboe@kernel.dk>,
Nitesh Shetty <nj.shetty@samsung.com>,
Sasha Levin <sashal@kernel.org>,
io-uring@vger.kernel.org
Subject: [PATCH AUTOSEL 6.18] io_uring/rw: free potentially allocated iovec on cache put failure
Date: Mon, 2 Feb 2026 16:45:58 -0500 [thread overview]
Message-ID: <20260202214643.212290-3-sashal@kernel.org> (raw)
In-Reply-To: <20260202214643.212290-1-sashal@kernel.org>
From: Jens Axboe <axboe@kernel.dk>
[ Upstream commit 4b9748055457ac3a0710bf210c229d01ea1b01b9 ]
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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Now let's understand the scope. This commit fix is for a memory leak bug
in the io_uring rw (read/write) path. Let me summarize my analysis:
## Analysis Summary
### 1. COMMIT MESSAGE ANALYSIS
- **Subject**: "io_uring/rw: free potentially allocated iovec on cache
put failure"
- **Keywords**: "free", "allocated", "failure" - this is clearly a bug
fix for a resource leak
- **Description**: When a read/write request goes through
io_req_rw_cleanup() with an allocated iovec and fails to put to the
rw_cache, the iovec pointer becomes unaccounted (leaked).
- **Reviewed-by**: Nitesh Shetty (Samsung) - indicates review
- **Author**: Jens Axboe (io_uring maintainer)
### 2. CODE CHANGE ANALYSIS
The bug is in `io_rw_recycle()` and `io_req_rw_cleanup()`:
**Before the fix:**
```c
static void io_rw_recycle(struct io_kiocb *req, unsigned int
issue_flags)
{
struct io_async_rw *rw = req->async_data;
if (unlikely(issue_flags & IO_URING_F_UNLOCKED))
return; // Early return - iovec potentially leaked
io_alloc_cache_vec_kasan(&rw->vec);
if (rw->vec.nr > IO_VEC_CACHE_SOFT_CAP)
io_vec_free(&rw->vec);
if (io_alloc_cache_put(&req->ctx->rw_cache, rw))
io_req_async_data_clear(req, 0);
// PROBLEM: If io_alloc_cache_put fails (returns false when cache is
full),
// the rw structure is NOT freed and NOT put back into the cache,
// but the iovec inside rw->vec is also not freed!
}
```
**After the fix:**
```c
static bool io_rw_recycle(struct io_kiocb *req, unsigned int
issue_flags)
{
// Returns bool to indicate if recycling succeeded
if (unlikely(issue_flags & IO_URING_F_UNLOCKED))
return false; // Caller knows recycling failed
// ... same cleanup ...
if (io_alloc_cache_put(&req->ctx->rw_cache, rw)) {
io_req_async_data_clear(req, 0);
return true; // Successfully recycled
}
return false; // Failed to recycle - caller will free
}
static void io_req_rw_cleanup(struct io_kiocb *req, unsigned int
issue_flags)
{
if (!(req->flags & (REQ_F_REISSUE | REQ_F_REFCOUNT))) {
req->flags &= ~REQ_F_NEED_CLEANUP;
if (!io_rw_recycle(req, issue_flags)) {
struct io_async_rw *rw = req->async_data;
io_vec_free(&rw->vec); // FIX: Free the iovec if recycle
failed
}
}
}
```
### 3. CLASSIFICATION
- **Type**: Bug fix - memory leak
- **Category**: Resource leak in io_uring read/write path
- **Severity**: Medium - leads to memory leak over time with repeated
I/O operations when cache is full
### 4. SCOPE AND RISK ASSESSMENT
- **Lines changed**: 11 insertions, 4 deletions (small)
- **Files touched**: 1 (io_uring/rw.c)
- **Complexity**: Low - simple return value change and conditional free
- **Risk**: Very low - the fix is straightforward and localized
### 5. USER IMPACT
- **Who is affected**: All io_uring users doing read/write operations
- **How severe**: Memory leak - can cause gradual memory exhaustion on
systems with heavy io_uring usage
- **Trigger conditions**: When the rw_cache is full (reaches
IO_ALLOC_CACHE_MAX=128 entries) and a request cleanup occurs
### 6. STABILITY INDICATORS
- **Reviewed-by**: Yes (Nitesh Shetty)
- **Maintainer authored**: Yes (Jens Axboe is the io_uring maintainer)
- **Testing**: The fix is straightforward and has a Reviewed-by tag
### 7. DEPENDENCY CHECK
- The code being fixed was introduced in v6.14-rc1 (commit
9ac273ae3dc29)
- The `io_vec_free` function exists in v6.15+
- This fix applies cleanly to 6.14+ and 6.15+ stable branches
### Conclusion
This commit should be backported because:
1. **Fixes a real bug**: Memory leak when io_alloc_cache_put fails
2. **Small and surgical**: Only 15 lines changed in one file
3. **Obviously correct**: The fix simply ensures proper cleanup when
cache insertion fails
4. **No new features**: Just fixes the existing resource management
5. **Low risk**: The change is well-contained and logical
6. **Affects production code**: io_uring is widely used, and memory
leaks in this path affect real users
The fix is simple: change `io_rw_recycle()` to return a boolean
indicating success/failure, and have `io_req_rw_cleanup()` call
`io_vec_free()` when recycling fails. This ensures the iovec is always
properly freed.
**YES**
io_uring/rw.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/io_uring/rw.c b/io_uring/rw.c
index abe68ba9c9dc8..d7388a4a3ea5e 100644
--- a/io_uring/rw.c
+++ b/io_uring/rw.c
@@ -144,19 +144,22 @@ static inline int io_import_rw_buffer(int rw, struct io_kiocb *req,
return 0;
}
-static void io_rw_recycle(struct io_kiocb *req, unsigned int issue_flags)
+static bool io_rw_recycle(struct io_kiocb *req, unsigned int issue_flags)
{
struct io_async_rw *rw = req->async_data;
if (unlikely(issue_flags & IO_URING_F_UNLOCKED))
- return;
+ return false;
io_alloc_cache_vec_kasan(&rw->vec);
if (rw->vec.nr > IO_VEC_CACHE_SOFT_CAP)
io_vec_free(&rw->vec);
- if (io_alloc_cache_put(&req->ctx->rw_cache, rw))
+ if (io_alloc_cache_put(&req->ctx->rw_cache, rw)) {
io_req_async_data_clear(req, 0);
+ return true;
+ }
+ return false;
}
static void io_req_rw_cleanup(struct io_kiocb *req, unsigned int issue_flags)
@@ -190,7 +193,11 @@ static void io_req_rw_cleanup(struct io_kiocb *req, unsigned int issue_flags)
*/
if (!(req->flags & (REQ_F_REISSUE | REQ_F_REFCOUNT))) {
req->flags &= ~REQ_F_NEED_CLEANUP;
- io_rw_recycle(req, issue_flags);
+ if (!io_rw_recycle(req, issue_flags)) {
+ struct io_async_rw *rw = req->async_data;
+
+ io_vec_free(&rw->vec);
+ }
}
}
--
2.51.0
next prev parent reply other threads:[~2026-02-02 21:46 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-02 21:45 [PATCH AUTOSEL 6.18-6.12] ALSA: hda/realtek - fixed speaker no sound Sasha Levin
2026-02-02 21:45 ` [PATCH AUTOSEL 6.18-5.10] ALSA: hda/realtek: Fix headset mic for TongFang X6AR55xU Sasha Levin
2026-02-02 21:45 ` Sasha Levin [this message]
2026-02-02 21:45 ` [PATCH AUTOSEL 6.18-6.12] ALSA: hda/realtek: ALC269 fixup for Lenovo Yoga Book 9i 13IRU8 audio Sasha Levin
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18] ALSA: usb-audio: Add delay quirk for MOONDROP Moonriver2 Ti Sasha Levin
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18-6.1] ASoC: amd: yc: Add ASUS ExpertBook PM1503CDA to quirks list Sasha Levin
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18-5.10] gpio: sprd: Change sprd_gpio lock to raw_spin_lock Sasha Levin
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18-6.6] spi: hisi-kunpeng: Fixed the wrong debugfs node name in hisi_spi debugfs initialization Sasha Levin
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18-6.1] ASoC: cs35l45: Corrects ASP_TX5 DAPM widget channel Sasha Levin
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18-5.10] scsi: target: iscsi: Fix use-after-free in iscsit_dec_conn_usage_count() Sasha Levin
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18-6.1] ALSA: hda/realtek: Add quirk for Inspur S14-G1 Sasha Levin
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18] btrfs: fix Wmaybe-uninitialized warning in replay_one_buffer() Sasha Levin
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18-5.10] scsi: target: iscsi: Fix use-after-free in iscsit_dec_session_usage_count() Sasha Levin
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18] Revert "drm/amd/display: pause the workload setting in dm" Sasha Levin
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18] btrfs: sync read disk super and set block size Sasha Levin
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18-5.10] wifi: mac80211: don't increment crypto_tx_tailroom_needed_cnt twice Sasha Levin
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18] spi: intel-pci: Add support for Nova Lake SPI serial flash Sasha Levin
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18-6.12] btrfs: reject new transactions if the fs is fully read-only Sasha Levin
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18] riscv: Use 64-bit variable for output in __get_user_asm Sasha Levin
2026-02-02 21:46 ` Sasha Levin
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18-6.6] regmap: maple: free entry on mas_store_gfp() failure Sasha Levin
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18-6.6] wifi: mac80211: correctly check if CSA is active Sasha Levin
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18-5.10] romfs: check sb_set_blocksize() return value Sasha Levin
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18-5.10] wifi: cfg80211: Fix bitrate calculation overflow for HE rates Sasha Levin
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18] tracing: Avoid possible signed 64-bit truncation Sasha Levin
-- strict thread matches above, loose matches on Subject: below --
2026-01-28 22:32 [PATCH AUTOSEL 6.18-5.10] ALSA: hda/realtek: Fix headset mic for TongFang X6AR55xU Sasha Levin
2026-01-28 22:33 ` [PATCH AUTOSEL 6.18] io_uring/rw: free potentially allocated iovec on cache put failure Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260202214643.212290-3-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=axboe@kernel.dk \
--cc=io-uring@vger.kernel.org \
--cc=nj.shetty@samsung.com \
--cc=patches@lists.linux.dev \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.