From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-oi1-f175.google.com (mail-oi1-f175.google.com [209.85.167.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3BA7D282F02 for ; Sun, 7 Jun 2026 19:07:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.175 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780859240; cv=none; b=G3ja7X2U51u56zp+rFkPy/jJX/8piOxlJuK5eiYqgo00OWXSM4ZgG91h5l7nuWO+jasqM2A3P1ZPELgtq9/e5VvvFc1haSW1kHw7IH+AxAI+X68wC28F5k+GsnvuGn8ad4WF7xmoKKZ/aaN0YwZjt9K0G+vJQ7ZndxZL/4DOnNw= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780859240; c=relaxed/simple; bh=Nv+IuUeu7QHUcyDigJjy/119CXZqiZ3izQIWywAjeHQ=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=sZKdSVMgqk6H8VASqOTsRo5cs+p/U18XIYbSU060Eu6xxPC0VKXZvUhN0yelBjj0iDhgTp+OZGPkGto6b9Xc6IleAcVA0hV4QmW6eJLyy/oIH/5RljYFKDnIgPH0obR7ngQ8mXWju43DU6My/hqkbI2HdWe5V8lHSDy+3/xLNYE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.dk; spf=pass smtp.mailfrom=kernel.dk; dkim=pass (2048-bit key) header.d=kernel-dk.20251104.gappssmtp.com header.i=@kernel-dk.20251104.gappssmtp.com header.b=vKGo0pP9; arc=none smtp.client-ip=209.85.167.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.dk Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kernel.dk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel-dk.20251104.gappssmtp.com header.i=@kernel-dk.20251104.gappssmtp.com header.b="vKGo0pP9" Received: by mail-oi1-f175.google.com with SMTP id 5614622812f47-4854166e1efso3586758b6e.3 for ; Sun, 07 Jun 2026 12:07:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel-dk.20251104.gappssmtp.com; s=20251104; t=1780859237; x=1781464037; darn=vger.kernel.org; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=eokQC1Z5vs2eUgGBLXd9scSPkjDARsD4VafD1xgopGI=; b=vKGo0pP98J3wrPoIQeX22bcIWk7sxCVVnFCm5I1Pb4Ql0zF6bfofupnzbNySSR15TB 0IYVwcOuCBuNONayQRCMyCbQNn/pRuobr0KzcQu2xTmYy+0Qrj+aqS5R6jf1RS5XKsgt sUcL2TimzhcJ+ZLA8EuBQRG5oEDa+0DfZTuVp0v4e1oEMJ7U2wNmAc+F0xb66bpUfv7T pMLt5WjwLuH+nsfaJ2DfV0fHk0Ju9RtCVAFV3wv91z8ejWSxRaVnRb0PlgY1TyhWWB+k P57YsqPPdqe4NFd2o5UM7NMm0vqL+OI1jhLYNtlVe42k+YUpwREnV+xAg+Nqc/reKCBc gkpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780859237; x=1781464037; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=eokQC1Z5vs2eUgGBLXd9scSPkjDARsD4VafD1xgopGI=; b=lMoemVMmKvOtiejtASbeZj8Yc/twrU41xenyAtCGmusa8BekDp1E5Peer+0/G6lrQm E4ivSsyhZlzhUUdl7LlKN7LtCHXTDVpUcuSpvGDTPSJokGLGiIAsMMbhlvciEdBcmo0S WhoHd6OdLCcF4s2jWi3JaXpSj9ZWCuGJ/iFtcOOg782ZFbpWzsYiTQjOdRuw6A9FgMtA fcWWkYrWXnmQ3ftHEKt2srQTCdBqp3WDQtGrx3DZDz71pyEjbG9qh0BbWf9eZYBgFWHu 5LQ8EUXrkiYqEbCtvBhInAAvc3ElUbjiQXgbBGmivy1cgrUWrTUnVxDzotNly7SGONF3 LDCw== X-Gm-Message-State: AOJu0Yxiw6sTWVCVl71bEQayUgU4qoihmcft9j+UGdipm9xUugX27ue0 GHDRQVQ1v8gO+QPO8feKrUApKHB15AWaPwWS5NUSunS7ZbyxLj0CZZOIZ8TpU6zMyl8= X-Gm-Gg: Acq92OGKrSQXLHpCHIkn9l/zQvBnaUIUqQLGj1MSCBgRoVsJ440G0J4h1wZfvmkd63+ MA3aRtYvmp5r+TGi6RtD7+dWfQgRJ3Qn7lOehAjsj3c0KySIqZ0cp5TUpla7aUfD/+i2tgKnDkR 0kZrl/Y/vfWNGVcEx70d+FqKZUx8h6whgomlBGdZdc4ovE76d5KqkTZzgohmoM38uwDXFhFXCIq zAO1SYSDXJJc9VliE5e3TG4aAisN7imLiHx4mAnXdZYV0l+ypZ8o8Py7BfLsvzcq7ZnuaaAPnil 2Hwe8j5UqTJKSCpiLRDAYtIUXAHk2AD5sjKSxJA5Iv0Mt9GMEQR8zDDfwFjXk7OHCbtTHMU/Ch1 sl+L6G1lhlvODhxJerEPt0HXfhy19GVvPLEPDDOsHKYDkJnVR5T+1RM4BY8zKYX9yc1ez7zgcQb 7lXJj7CD0MccpBQmcfR7gMV2z/VNtv6/556mvMNMdSoo4CZsJEzOXvUBjV2pROfLcQ8aG97J3IE Qx0y1g+jOsz6XWZmpcd X-Received: by 2002:a05:6808:1991:b0:467:281e:3d85 with SMTP id 5614622812f47-4868def7241mr6781474b6e.29.1780859236808; Sun, 07 Jun 2026 12:07:16 -0700 (PDT) Received: from [192.168.1.150] ([198.8.77.157]) by smtp.gmail.com with ESMTPSA id 5614622812f47-4865b91ead7sm12254490b6e.10.2026.06.07.12.07.15 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sun, 07 Jun 2026 12:07:15 -0700 (PDT) Message-ID: <71417fb0-4060-4823-8e4f-f216ce0235d4@kernel.dk> Date: Sun, 7 Jun 2026 13:07:14 -0600 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [BUG io_uring] Failed RECVSEND_BUNDLE can persistently shrink non-INC pbuf ring len and affect later READ operations To: Federico Brasili , io-uring@vger.kernel.org Cc: linux-kernel@vger.kernel.org References: Content-Language: en-US From: Jens Axboe In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit On 6/7/26 5:41 AM, Federico Brasili wrote: > Hi, > > I found a reproducible io_uring provided-buffer ring issue on Ubuntu > kernel 7.0.0-22-generic. > > A failed IORING_RECVSEND_BUNDLE receive on a non-INC provided-buffer > ring can persistently shrink the user-visible buffer descriptor > length. The modified length is not rolled back when the receive fails > with -EAGAIN/no data, and a later unrelated io_uring operation, such > as IORING_OP_READ from a pipe, consumes the corrupted length. > > This is not a demonstrated privilege escalation. The demonstrated > impact is deterministic unprivileged provided-buffer ring metadata > corruption across unrelated io_uring operations. > > Tested kernel: > > Linux ubuntu 7.0.0-22-generic #22-Ubuntu SMP PREEMPT_DYNAMIC Mon May > 25 15:54:34 UTC 2026 x86_64 GNU/Linux > > Summary: > > Create an io_uring instance as an unprivileged user. > > Register a non-INC provided-buffer ring with two buffers: > > entry0.len = 4096 > > entry1.len = 4096 > > Submit IORING_OP_RECV with: > > IOSQE_BUFFER_SELECT > > IORING_RECVSEND_BUNDLE > > req_len = 1 > > MSG_DONTWAIT > > empty AF_UNIX SOCK_DGRAM socket > > The receive fails with -EAGAIN, but entry0.len is changed from 4096 to 1. > > Submit a later unrelated IORING_OP_READ from a pipe using the same > provided-buffer group with req_len = 4096. > > The READ returns only 1 byte, because it uses the previously corrupted > entry0.len. > > A second READ then consumes entry1 normally and returns 4096 bytes, > showing that head/bid accounting remains coherent and the corruption > is localized to the poisoned descriptor. > > Observed output from clean unprivileged reproduction: > > [INIT] uid=1002 entry0.len=4096 entry1.len=4096 tail=2 > [STEP1] RECV BUNDLE on empty socket, req_len=1, expected CQE=-EAGAIN > [CQE_RECV_BUNDLE] res=-11 flags=0x0 user=0x1111 > [AFTER_RECV_BUNDLE] entry0.len=1 entry1.len=4096 changed_buf0=0 > changed_buf1=0 guard_before=0 guard_after=0 > [STEP2] write pipe bytes=4096, then IORING_OP_READ req_len=4096 using > same pbuf group > [CQE_READ1] res=1 flags=0x1 user=0x6666 > [AFTER_READ1] entry0.len=1 entry1.len=4096 changed_buf0=1 > changed_buf1=0 guard_before=0 guard_after=0 > [STEP3] write second pipe bytes=4096, then second IORING_OP_READ > req_len=4096 without republish > [CQE_READ2] res=4096 flags=0x10001 user=0x7777 > [AFTER_READ2] entry0.len=1 entry1.len=4096 changed_buf0=1 > changed_buf1=4096 guard_before=0 guard_after=0 > [RESULT] PASS: unprivileged RECV_BUNDLE -EAGAIN poisoned pbuf len and > later IORING_OP_READ consumed the corrupted len. > > Why this looks like a bug: > > The failed receive should not persistently alter the provided-buffer > descriptor in a way that affects future unrelated operations. In this > case, a no-data/-EAGAIN RECV_BUNDLE changes entry0.len from 4096 to 1, > and that corrupted length is later consumed by IORING_OP_READ from a > pipe. > > The suspected root cause is in the non-INC provided-buffer ring BUNDLE > selection path: > > io_ring_buffers_peek() > if (len > arg->max_len) { > len = arg->max_len; > if (!(bl->flags & IOBL_INC)) { > arg->partial_map = 1; > if (iov != arg->iovs) > break; > WRITE_ONCE(buf->len, len); > } > } > > The descriptor length is modified during buffer selection/peek before > the receive operation has completed successfully. If the receive later > fails with -EAGAIN/no data, the buffer is recycled but the modified > buf->len is not restored. > > Additional observations: > > The issue reproduces as an unprivileged user. > > The effect crosses io_uring operations: RECV affects a later READ. > > The effect crosses subsystems: socket receive affects pipe read. > > The second READ correctly uses entry1 and returns 4096 bytes, so this > does not appear to be a head/bid desync in the tested case. > > No kernel crash, OOB write, UAF, or privilege escalation has been demonstrated. > > Expected behavior: > > If IORING_RECVSEND_BUNDLE fails with -EAGAIN/no data, the > provided-buffer ring descriptor should not be persistently modified, > or the original len should be restored during recycle/rollback. > > Actual behavior: > > The failed BUNDLE receive leaves entry0.len shortened to the requested > length, and later unrelated operations using the same provided-buffer > group consume that corrupted length. > > I can provide the minimal C reproducer and full output if useful. Please do, no point in me recreating one for it. Then it can also get turned into a regression test cor liburing. Reproducers also mean more than a thousand words in an email, it tells us exactly what is bring run and what is going wrong. Or in some cases, what the wrong expectations are. -- Jens Axboe