From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f52.google.com (mail-pj1-f52.google.com [209.85.216.52]) (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 4841125B0B2 for ; Sun, 5 Jul 2026 23:46:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.52 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783295184; cv=none; b=b8JbdXsyfjxBAMnTrnC3DP3eIyfj060zBkALz57kEwLtCJDQkFn8T2UBYag5kyhSuyompNssGacKfnSFbBdjRnf4/wWg+pfxsRTonEQ7g3ts+YPt1lPwbEIQP5DDu+TfPj4awWCcpaVEG3bgIyXKIM0AEKoq39+6J1KaARAi0UU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783295184; c=relaxed/simple; bh=rwiGUlXrzKU1WnDfytZuyAUkQvRMBBDHS4rt18BXk1g=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=TC7Q4UZLri8yEYN54XE3cT9N9K6/8LO1rcWvs6Nrizc2mIOBOscMrc/Ej6bZ1JApaInWlDjnzhIAbg0ff3mDLpM/1b29ds3sm53IqcqWT996GLckjxTCp//dnm+4OrnYnCYANC/76XDgIfDOjmhSP60i0Gu+JmawddQtXZx1n3I= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=YHTkX2vp; arc=none smtp.client-ip=209.85.216.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="YHTkX2vp" Received: by mail-pj1-f52.google.com with SMTP id 98e67ed59e1d1-37df72c9984so2129964a91.3 for ; Sun, 05 Jul 2026 16:46:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1783295182; x=1783899982; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=1ww0dOKkmeJX/064KbajPe2nczUlwX/FWmPsoIooNcM=; b=YHTkX2vpTgUY6ZaSUw1gVW38HtwXZCyrEPHv+TAbZ/ZW9v6GpYklQuMTjWLeFHM4bG 2P0m7Zxfyydvzxlqau5hA9TnvJNIsONcatrK+KcyIFPNVH3vJ8QVsJy1Qlkj5ZBGGGKc QJKiHanhMVVnXYZwZuUIgVKtmGbrZxFYmpw4FtXRSW/cMCcQHM8woNz8eQcxTTicKIJV 8YgHglWdWxx3T7dhJCjxkCv0QJW4Pv32vLI7EoxSIbD5KvLi4RQCk3H+PYn78WthHqeH F6uxwTsVv3DVyUmVJzoVVgadDuMPcfSu5aymajg2hmCDtWs8phCPcJ4hapBkrFFpp+Gg K2fQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783295182; x=1783899982; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=1ww0dOKkmeJX/064KbajPe2nczUlwX/FWmPsoIooNcM=; b=mJ6q8vSIyZX31SSUu46riO3TMUMJ/God/AEkD80V3lHi1P9zF9GgingZbMLfu+Iseu JI3UH9sS/guKk65HrFk0eskkPP8WAwgXbjSt/VyxP0ibXF72/Pqn+DxGOjEp3bfS8+8J 41T4hfdocsxpKdX0uVI/DOGDUA9drzrbMGUy69YWk9vHNT3ggsl1E8lFg/VgBXUhft4Q R9rShtyZWN65etNXk+LzM9eh2vhYCblgmJleLUy32wKw1rcD+TolIgnru2UCQ9xsLnin E5gHQPUHzXL2qL+g6lEB3sN0K2XxTbsL8QykRPTjNolg1On5XxUniWUqpJ6hB2yw8vOa habw== X-Gm-Message-State: AOJu0Yz2QgObLYMxXRvze5lE8uWQn2qbM8lsnmA85Axz5gz9lXePvd3H bGwQGOLKygkc6P82gyQ3bl4kThOMfBwAIL7GRZmZOJkIU54RQlG2S8aAHnB32g== X-Gm-Gg: AfdE7cmNTrIJU7rjwGIl2bruxzM18BEAY42BIcyUYeD6eCcLZPCuBtrZI+dQqPrfl/h 7QH/4pwHkDmwl5MOI7l1W6Jl53knPzbGNzgLEoSEqRVr10s9ZH03pPL9xnGXitoyQ32T6sjykvm E4f7M2I/1rM9U8tjv9DpZAuYW6KBS9uCMcy2GYJDyGowdk5xpQ5HNrajxosG5hW+gKU1stUYRZB 9gpSn6liBmBClTPVP+WazHE6w99XgTJg0cmpaPLNll9zbANVuqst5nEdfGGcLoxBXL5cfed8TUp EXAyivEioGi6c05NXF0/ujLog5obBLht2yGPa0e/IcgAW/aAjrjPQSeilyrSnvQ+onsaPRMasEs Z0Yg+aFb+EpZlhrOArgRNvPSvJ4b1WgiFlOPSVJHRvWMLhF0J3qLL+xo5dgn8bpXh09BLNBb3Vw oc8SAER6cv+zk0Owd0wmjKGjrK9IgTa8Z15PfNAnefs77mmidbDQbG0W4= X-Received: by 2002:a17:90b:2e42:b0:381:720d:240 with SMTP id 98e67ed59e1d1-3828127f8f6mr7770740a91.14.1783295181617; Sun, 05 Jul 2026 16:46:21 -0700 (PDT) Received: from naup-virtual-machine.localdomain ([140.113.139.102]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-3812801eadasm3820671a91.10.2026.07.05.16.46.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 05 Jul 2026 16:46:20 -0700 (PDT) From: Hao-Yu Yang To: linux-kernel@vger.kernel.org Cc: axboe@kernel.dk, io-uring@vger.kernel.org, Hao-Yu Yang Subject: [PATCH v1] io_uring: fix dangling iovec after provided-buffer bundle grow failure Date: Mon, 6 Jul 2026 07:45:34 +0800 Message-Id: <20260705234534.768138-1-naup96721@gmail.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit When growing a provided-buffer bundle, the old cached iovec is freed before the new buffers have all been validated. If validation fails, the request still points at the freed iovec, which can be freed again during completion cleanup. BUG: KASAN: double-free in io_vec_free+0x2c/0x90 Freed by task 73: kfree+0x104/0x3b0 io_vec_free+0x2c/0x90 __io_submit_flush_completions+0xc03/0x1e40 io_submit_sqes+0xdb5/0x2310 Allocated by task 73: io_ring_buffers_peek+0x559/0xc60 io_buffers_select+0x1c1/0x460 io_send+0x770/0x1050 Fix this by deferring the free of the old cached iovec until validation has succeeded. On failure, free the newly allocated iovec and leave the request pointing at the original one. Fixes: 46800585ae04 ("io_uring/kbuf: validate ring provided buffer addresses with access_ok()") Signed-off-by: Hao-Yu Yang --- io_uring/kbuf.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c index 3cd29477fff2..4055173e0c48 100644 --- a/io_uring/kbuf.c +++ b/io_uring/kbuf.c @@ -256,6 +256,7 @@ static int io_ring_buffers_peek(struct io_kiocb *req, struct buf_sel_arg *arg, struct io_uring_buf_ring *br = bl->buf_ring; struct iovec *org_iovs = arg->iovs; struct iovec *iov = arg->iovs; + struct iovec *old = NULL; int nr_iovs = arg->nr_iovs; __u16 nr_avail, tail, head; struct io_uring_buf *buf; @@ -288,7 +289,7 @@ static int io_ring_buffers_peek(struct io_kiocb *req, struct buf_sel_arg *arg, if (unlikely(!iov)) return -ENOMEM; if (arg->mode & KBUF_MODE_FREE) - kfree(arg->iovs); + old = arg->iovs; arg->iovs = iov; nr_iovs = nr_avail; } else if (nr_avail < nr_iovs) { @@ -318,6 +319,8 @@ static int io_ring_buffers_peek(struct io_kiocb *req, struct buf_sel_arg *arg, if (unlikely(!access_ok(iov->iov_base, len))) { if (arg->iovs != org_iovs) kfree(arg->iovs); + /* hand the still-live cached vec back to the owner */ + arg->iovs = org_iovs; return -EFAULT; } iov++; @@ -330,6 +333,8 @@ static int io_ring_buffers_peek(struct io_kiocb *req, struct buf_sel_arg *arg, buf = io_ring_head_to_buf(br, ++head, bl->mask); } while (--nr_iovs); + kfree(old); + if (head == tail) req->flags |= REQ_F_BL_EMPTY; -- 2.34.1