public inbox for io-uring@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH AUTOSEL 6.18] io_uring: use GFP_NOWAIT for overflow CQEs on legacy rings
       [not found] <20260107155329.4063936-1-sashal@kernel.org>
@ 2026-01-07 15:53 ` Sasha Levin
  0 siblings, 0 replies; only message in thread
From: Sasha Levin @ 2026-01-07 15:53 UTC (permalink / raw)
  To: patches, stable; +Cc: Alexandre Negrel, Jens Axboe, Sasha Levin, io-uring

From: Alexandre Negrel <alexandre@negrel.dev>

[ Upstream commit fc5ff2500976cd2710a7acecffd12d95ee4f98fc ]

Allocate the overflowing CQE with GFP_NOWAIT instead of GFP_ATOMIC. This
changes causes allocations to fail earlier in out-of-memory situations,
rather than being deferred. Using GFP_ATOMIC allows a process to exceed
memory limits.

Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220794
Signed-off-by: Alexandre Negrel <alexandre@negrel.dev>
Link: https://lore.kernel.org/io-uring/20251229201933.515797-1-alexandre@negrel.dev/
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Analysis of io_uring GFP_NOWAIT Commit

### 1. COMMIT MESSAGE ANALYSIS

The commit message is clear and well-structured:
- **Problem**: Using `GFP_ATOMIC` for overflow CQE allocations allows
  processes to exceed memory limits
- **Solution**: Change to `GFP_NOWAIT` which fails earlier in OOM
  situations
- **Bug Reference**: Links to kernel bugzilla (bug 220794) - indicates a
  real user-reported issue
- **Proper sign-offs**: Author and maintainer (Jens Axboe) signatures
  present

The key insight is that `GFP_ATOMIC` can dip into emergency memory
reserves, allowing allocations to succeed even when a process should be
constrained by memory limits. This is a resource exhaustion / memory
limit bypass issue.

### 2. CODE CHANGE ANALYSIS

The change is minimal - a single line:
```c
- ocqe = io_alloc_ocqe(ctx, cqe, big_cqe, GFP_ATOMIC);
+       ocqe = io_alloc_ocqe(ctx, cqe, big_cqe, GFP_NOWAIT);
```

**Technical mechanism of the bug:**
- `io_cqe_overflow_locked()` is called when the completion queue is full
  and entries must overflow
- This function runs with `completion_lock` held, so it cannot sleep
  (ruling out `GFP_KERNEL`)
- `GFP_ATOMIC` can access emergency memory reserves, bypassing memory
  limits
- `GFP_NOWAIT` is also non-sleeping but respects memory limits by
  failing instead of dipping into reserves

**Why the fix works:**
- Both flags are appropriate for the atomic context (holding spinlock)
- `GFP_NOWAIT` is semantically correct: the allocation should fail
  gracefully under memory pressure rather than bypass system memory
  constraints

### 3. CLASSIFICATION

- **Bug fix**: Yes - fixes memory limit bypass
- **Feature**: No - no new functionality added
- **Security-relevant**: Yes - this could be exploited for resource
  exhaustion/DoS, particularly in containerized or multi-tenant
  environments with memory cgroups

### 4. SCOPE AND RISK ASSESSMENT

- **Lines changed**: 1
- **Files touched**: 1 (io_uring/io_uring.c)
- **Complexity**: Trivial
- **Function context**: `__cold` path - not in hot path, used only
  during overflow conditions

**Risk analysis:**
- Allocation may fail more readily under memory pressure - but that's
  the *intended* behavior
- If overflow allocation fails, the CQE won't be recorded - applications
  relying on completion notifications might be affected, but this is
  correct behavior when memory is exhausted
- Very low risk of regression since this is the semantically correct
  change

### 5. USER IMPACT

- **Who is affected**: Users running io_uring workloads (databases,
  high-performance I/O applications)
- **Severity of bug**: Medium-High - allows memory limit bypass which is
  particularly problematic in:
  - Container environments (Docker, Kubernetes)
  - Systems with memory cgroups
  - Multi-tenant systems
- **Reported by users**: Yes - bugzilla link indicates real-world issue

### 6. STABILITY INDICATORS

- Accepted by Jens Axboe (io_uring maintainer)
- Has proper Link: to mailing list discussion
- Referenced bug report demonstrates real user impact
- Simple, well-understood change

### 7. DEPENDENCY CHECK

- No dependencies on other commits
- `io_alloc_ocqe()` and `io_cqe_overflow_locked()` exist in stable
  kernels
- io_uring has been present since kernel 5.1

### CONCLUSION

**Meets stable criteria:**
- ✅ Obviously correct - semantically appropriate GFP flag
- ✅ Fixes a real bug - memory limit bypass (resource exhaustion)
- ✅ Small and contained - single line change
- ✅ No new features or APIs
- ✅ Tested in mainline
- ✅ Referenced bug report shows real user impact

**Risk vs Benefit:**
- Risk: Minimal - well-understood change to allocation flags
- Benefit: Fixes a memory limit bypass that could be used for DoS

This is an ideal stable backport candidate: a tiny, surgical fix
addressing a real security-relevant bug (memory limit bypass) with
minimal risk of regression.

**YES**

 io_uring/io_uring.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
index 60adab71ad2d..93b203205a16 100644
--- a/io_uring/io_uring.c
+++ b/io_uring/io_uring.c
@@ -897,7 +897,7 @@ static __cold bool io_cqe_overflow_locked(struct io_ring_ctx *ctx,
 {
 	struct io_overflow_cqe *ocqe;
 
-	ocqe = io_alloc_ocqe(ctx, cqe, big_cqe, GFP_ATOMIC);
+	ocqe = io_alloc_ocqe(ctx, cqe, big_cqe, GFP_NOWAIT);
 	return io_cqring_add_overflow(ctx, ocqe);
 }
 
-- 
2.51.0


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-01-07 15:53 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20260107155329.4063936-1-sashal@kernel.org>
2026-01-07 15:53 ` [PATCH AUTOSEL 6.18] io_uring: use GFP_NOWAIT for overflow CQEs on legacy rings Sasha Levin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox