From nobody Thu Jul 23 21:54:32 2026 Received: from mail-wr1-f48.google.com (mail-wr1-f48.google.com [209.85.221.48]) (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 DC71137AA61 for ; Sun, 5 Jul 2026 11:56:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783252605; cv=none; b=DNq94G8KVdgUvMpTGzv2AtZsGVNlSON8t92jNFLBwzKDPF9CSj+MsLBPTUYZiUKRTQWbWwbs/7/g5AFWLRXh3Y0/KSuZdmD7/Jq1NXUauNz6ODQrV+4/8mBWL0hxDIGmMRGj5UgwtHnv2YiCfwq2SMeEi5mZ+DVGtMhexDUNNZ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783252605; c=relaxed/simple; bh=psdL2ehjhK1+otPuT+qxaqnsGupxQEbTsh2uBQHmRy4=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=nAne8+9382NXJyYFB45fVWBOwf4u5IPnygNSpzjGW0CuLDCgG0Y7RqHUeaxtSosHpVNSSU8822lcRhLFWwbxuv3YU8gOXid2pc5ubEQFh/8G/xp9dZIK0vVAk71+b63Wh/moOnDGqF+3G6YTeVJ001q9GTnucYwxoOPmK5hguFw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=0sec.ai; spf=pass smtp.mailfrom=0sec.ai; dkim=temperror (0-bit key) header.d=0sec.ai header.i=@0sec.ai header.b=k+DIDVzr; arc=none smtp.client-ip=209.85.221.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=0sec.ai Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=0sec.ai Authentication-Results: smtp.subspace.kernel.org; dkim=temperror (0-bit key) header.d=0sec.ai header.i=@0sec.ai header.b="k+DIDVzr" Received: by mail-wr1-f48.google.com with SMTP id ffacd0b85a97d-471eee9b7d5so345218f8f.0 for ; Sun, 05 Jul 2026 04:56:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=0sec.ai; s=google; t=1783252602; x=1783857402; 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=pwRuSlbR797Mkzk8fZcr08AJmiX5cll2qBttTfovZeo=; b=k+DIDVzrLzklVsV3ENFHFunWW8O8Ho35rpail8JmCa1wxn2niCAMlDdU10/J8u0dZa oSFWrHK6yqrl1dmMeI4NX7CQ7LiIHTsnlQ590B3RQijkubkEH6LSxmtU3VvRoUtfIorU oagZI8MBIlfm4K1ar44FV1cWz2KmO48p/9qxCpNvrXDr2c2luCPvLItZ2VKeP4kCqIId xUif8IMLO8cKmR2GjMJUVzY03Tk5mFZDTRGPrk/MsGWWHrwxA7uuFIDUkTzXfP5NEZjO s8l95r2izTiL9W9PyW0vo49HzmO5KhAD1I2Go0kgAWnJi3AUAxlPwTFEkg8WeVkeOJ5i Jh3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783252602; x=1783857402; 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=pwRuSlbR797Mkzk8fZcr08AJmiX5cll2qBttTfovZeo=; b=K7BuOXDm7PWquBIYPr00lqQB/rH7ms1WvgfIjv/bL/nzlPSRQ8MHMGiGuE3Nl94Yxl 9pWYoZn8dRTeeYa+i0+J2lUR+cfEGo5DiAWpLYg7Pis0AVhCYdaEZu9AS1Ui5qoX508H 2jkZ70IN8pTvBTtmTCU0YJEZnfGjkr8sGFGBgYaHjVEqTbcYvaYO2aCtQGauV8I4GGVq /K3AYZGhNAPmFnUnkRDaBMkzc5GQoAVGf/edv6naYGv0lMItQwmNBi4yoY0e/vYXuVFU PW5/vP3SbiIJ1yWMV3EMKMeytBQe+GgEvlMriizJzA0tH4LDlKAwBsSrv+yjsdswQCGZ BHPA== X-Forwarded-Encrypted: i=1; AHgh+Roh1wLCgbMIcXyBUB8gIQg7m8bBW9L9nksPXztSg6ndFpm63ilVqsRQH/TLcJQdGZHo/4lYLdBKoucAqas=@vger.kernel.org X-Gm-Message-State: AOJu0Yzkhtcgj7oitISRTq9d0Vo0AfsKJ1tvLegBaz9ByX5MYzJu+5I1 DKCFkZqOtLf2tpkZTnyLAOQgKzRZ7LOPXSd3ijmrPTR7UMdUmqklw5yunBcGXSG4c0VV X-Gm-Gg: AfdE7cn87++C5jO2pjQ2AXuLQzPGBifyHJWF24jk+LLCu0jU6l6Un3Y28eCpMH5BcoR Fw4rAIEIAYiMYjm+1MiXSAyOQVIEGMKWFfDC/hmEmoDkn/RZLgkmAcvWUHIeMSulAZf4lmFYiDh ltANBCQ9Jj4y+98L/fMUdRcMk/bN5rgdxAAv9vrT6VUtz8DkAN6bQVZWb6WFuEX2SJJXRStUxxv QAMk45HMhuJHffaOcAKhfONvqjL7w7DuVcpT2ozl5KMpm4gsxMsQ1ROWqKl+RjOvYKCTEjsLGAk ELb2qrzfHwZ3bpOnEtnaybvFBQhUWbxC0QF5soU2Y5SNYR69KQVOxT0HGytQmEXtbCTZ8rsnvms kROtWdZ3QEqG1dGzsTElfJQASEsTpMDyVrk9QJ9UPCiMZQUHg5P/LCX6oqbz+RjHVkjtLk5MW5S xZfbp0AdU5iDZHr5qkPaPPubgYMh7iHt0+VI9EZbqrUm5AJjg3FhsL3tyGUwI5rkYLgbdQoKUVC vmCn8lCL5nXs43MXiuGg/XaAQXE39cOtRA= X-Received: by 2002:a05:6000:1818:b0:475:f0c2:5afb with SMTP id ffacd0b85a97d-47aad07e091mr5521587f8f.49.1783252601779; Sun, 05 Jul 2026 04:56:41 -0700 (PDT) Received: from PeakBook-Mini.tail8e484.ts.net ([178.197.219.178]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47a9e4d83bdsm15695537f8f.13.2026.07.05.04.56.40 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sun, 05 Jul 2026 04:56:41 -0700 (PDT) From: Doruk Tan Ozturk To: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Juergen Gross Cc: Stefano Stabellini , Oleksandr Tyshchenko , Jens Axboe , xen-devel@lists.xenproject.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, Doruk Tan Ozturk Subject: [PATCH] xen-blkfront: fix double completion of split requests on resume Date: Sun, 5 Jul 2026 13:56:39 +0200 Message-ID: <20260705115639.72805-1-doruk@0sec.ai> X-Mailer: git-send-email 2.53.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When a block request is too large for a single ring entry and the backend does not support indirect descriptors, blkfront splits it across two ring requests. blkif_ring_get_request() is called twice and both shadow slots (shadow[id] and shadow[extra_id]) are made to point at the *same* struct request, linked together through associated_id. On the normal completion path blkif_completion() collapses the pair: it recycles the second slot via add_id_to_freelist() and only completes the request once. The suspend/resume path in blkfront_resume() does not. It walks every physical shadow slot and, for each slot whose ->request is set, calls blk_mq_end_request() or re-queues ->request. For an in-flight split request this visits the shared struct request twice, so on resume/migration the same request is ended (or re-queued) two times. The second visit is a double blk_mq_end_request() (refcount underflow / double free) and a use-after-free read of req->bio, which was cleared on the first visit. Skip the secondary slot of a split request in the resume walk, so each logical request is completed or re-queued exactly once, matching how blkif_completion() already treats the pair. The secondary slot is the one that is linked (associated_id !=3D NO_ASSOCIATED_ID) and carries no scatter-gather list (num_sg =3D=3D 0); the first slot always keeps the scatter-gather list. This was found by 0sec automated security-research tooling (https://0sec.ai). The bug is only reachable on suspend/resume or live migration of a guest whose backend lacks indirect-descriptor support, so it has no local reproducer; the fix is by source inspection against the existing blkif_completion() collapse logic. Fixes: 6cc568339047 ("xen/blkfront: Handle non-indirect grant with 64KB pag= es") Assisted-by: 0sec:claude-opus-4-8 Signed-off-by: Doruk Tan Ozturk --- drivers/block/xen-blkfront.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index f765970578f9..b2e83fd0c77b 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -2079,6 +2079,15 @@ static int blkfront_resume(struct xenbus_device *dev) if (!shadow[j].request) continue; =20 + /* + * Split requests alias one request across two shadow + * slots; skip the sg-less secondary so it completes + * once, like blkif_completion() does. + */ + if (shadow[j].associated_id !=3D NO_ASSOCIATED_ID && + shadow[j].num_sg =3D=3D 0) + continue; + /* * Get the bios in the request so we can re-queue them. */ --=20 2.43.0