From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-yw1-f176.google.com (mail-yw1-f176.google.com [209.85.128.176]) (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 485353803E9 for ; Tue, 11 Aug 2026 19:21:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.176 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786476075; cv=none; b=UOXTrxT2XSJfIKcqrR0aGCVcjBLCP/ihuGBRQjr+ocbzBEznMoNU/EKWG9JSm6eZK5xynngjIGyCMLFfPpwiZZBmIPIMZ/72CHxyuWDtp36VSomFrSIaHbF0ttG2x2iKKKqb107ycGxDO7mRsUmoJQCbZXZRiToS8uozjlCmKvE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786476075; c=relaxed/simple; bh=GtKx2FrILq6hjs4UID5Fcq+FRzXE15Cu9bDzlLwTZXM=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=mt8nRg6HaTDF6xVPRg7dboyNph4yyi2uQpFNAWR1QWiYlGopB/UAYOy39XawdT76ggG9ukjAYkip2LNQ9ZChBWLx5iVg5THX/f+m60eEB6uwpy7jdDPi8ZmRRSRqp/+PoAdO4HWfJVbnTqFNlwy/ZTWwWEjGg97QKbcZG+moPNI= 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=liwqHyJM; arc=none smtp.client-ip=209.85.128.176 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="liwqHyJM" Received: by mail-yw1-f176.google.com with SMTP id 00721157ae682-8143daf89c7so2117027b3.1 for ; Tue, 11 Aug 2026 12:21:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786476073; x=1787080873; 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:content-type; bh=xsGRF6OAYtOe4wGNm3PkEdXjvkEOAuUjKX79hFhAsys=; b=liwqHyJM0EZMqjksGYHaREU/BNyD5daCcBotSpnkR+zpvdMKgxFgI062NEeJpwF+i/ Kj612SClPYB8QmnGla/Dfc7aYt5NPEr8ttnh2nc+QQvr7EwkCXPbdRWnVOxVgJ85IlPJ JcttBTRh5jFyxXiZ8Fmgkh+moaRVX5IyjxwuSN8tMyYrZnq+MO39l4tBSzGJoKL0Hl4E ylntUEXGOXkF/KrPisTA5VqL0nBTD3BcqPYPNQX1qXAsffHdFJdSr1ddaoMuz9ioZqnu qSQEP35B5dEZgarL4cO32rmsEFhh40tihE24ZG3nU402g08IaYWxbiYGwBycu8AtBoSf 516Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786476073; x=1787080873; 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:content-type; bh=xsGRF6OAYtOe4wGNm3PkEdXjvkEOAuUjKX79hFhAsys=; b=nyupME5UMjM3MxXp8dpVgSwjYh21Y0hnOhq9Kvcn5xYDGJb3pc3a0Y5VZg1u0Hzapc K4lduyNSuygtaIi60BCsG7fmoJQRT7VzsvzigGRdN6qYFPZbq+i1ET07MA5QEMP1jOJA aRSHdIUCKG0lpHdXy0RQjdN6RgusDjknw5MQw8AkG7W2buFycxDIEOgeZc0pXMSMF/Pl DtW6nCRMrUniq4KToYtkMcvBtejJgaqTMBQHvKHQ0Pxrhz2vwMv06xyK9vMkuHWdOYVx qJg7nHwLgJ2dEsMDt5qNJg3a/EUoNFVotb3y+OJb3DJeT6WTwQ3WLY+zQDcE7cGEMJCm 4PCA== X-Forwarded-Encrypted: i=1; AHgh+Roz1K3IHbC1ij1prNuVbumk0nC5vrA2D9WcShBkxZPgYATGgVRddYWhytBv0UJ6MKe83G7w/VlM4ehHKgs=@vger.kernel.org X-Gm-Message-State: AOJu0YzMBLbJKNWllyUjprzXY9kpVYuBj5GfsXLNZFycikt55H38e8L0 nQk4/x4/cSAFISnG44aj/BtKQd/W8qvVuQPHQUS+7l38kJDQeekm9H9n X-Gm-Gg: AR+sD13oCigZaVEIDUOp2D2y607UCtjnlPPfNi9lgV0qWyT47lFGgk7QZsFhPmb2h87 EI9Zk+0JbSPDpjMzSRS9NukHyu5w+EqZbw5SaeKMVJlGwXN37qjrF/8jzuKPv1y3K2P2+nBLTSa e9Gw6K7Zb0bNOM3L/uRakShcT1np6VHHw7YaThA+wxjPZMB5H25JsgQ1v1msPuNqpmEcTus6ZQt ETCamKSaIPuBXy/yivI/QnP7Kn2PiNdt5pW8t9LYYCgngVFu3BWpdpni4HDERVtmnlT+x7viMSW KRC7ki8yLbMjl9JQx/aDSCxmRYP/fkiC53s3er3WxWTbeQgLd0SL3fGR/FFNdteS9TX02voflzl OUOlYLqOf3JMxnSY23HSIVRHYDUHqftZPKgqz9w9BV4VWZE6SeFfPm7e2lC2Q1NLUvXJ9w3iujC EBnB7iAFokOZEao3lx3NoWxtDXgF5Cpjey4tijZSte8rH118ZXi4kfUJQ8C8EvwFb2LwQaE0zxX CexIWQ= X-Received: by 2002:a05:690c:b88:b0:826:5659:28aa with SMTP id 00721157ae682-82f2ef152e0mr41609287b3.32.1786476073030; Tue, 11 Aug 2026 12:21:13 -0700 (PDT) Received: from syssplab.cs.fiu.edu (nat1.cs.fiu.edu. [131.94.134.89]) by smtp.gmail.com with ESMTPSA id 00721157ae682-830a41425d1sm2748287b3.11.2026.08.11.12.21.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Aug 2026 12:21:12 -0700 (PDT) From: Chao Shi To: Keith Busch , Jens Axboe , Christoph Hellwig , Sagi Grimberg , linux-nvme@lists.infradead.org Cc: "Martin K . Petersen" , Weidong Zhu , linux-block@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH] nvme: refuse an unsolicited format change on a namespace that is in use Date: Tue, 11 Aug 2026 15:21:11 -0400 Message-ID: <20260811192111.2058140-1-coshi036@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit A namespace can report a new LBA format or metadata size on revalidation. The host still holds cached data, queued bios and integrity buffers built for the old geometry. Adopting the new one reinterprets all of it. Freezing the queue does not help. The request is already complete when the integrity verify is handed to kintegrityd, so the freeze drains while that work is still pending. The verify then walks a buffer sized for the old metadata_size using the new step size. That is the reported KASAN slab-out-of-bounds read in t10_pi_verify(). Christoph suggested failing such a revalidation rather than handling the fallout. Do that. Compare the new LBA data size and metadata size against the live ones, before the queue is frozen. If they differ while the disk is open, return INVALID_NS/DNR. nvme_validate_ns() turns that into nvme_ns_remove(), as it already does for changed identifiers. Host-initiated format and namespace management are exempt. They arrive through nvme_passthru_end(), where the host asked for the change. NVME_CTRL_SELF_RESCAN marks that window. Link: https://lore.kernel.org/linux-block/ah03bXpgFLQjOUt8@infradead.org/ Link: https://lore.kernel.org/linux-block/20260531-blk-integrity-fix-v1-1-cc7084f42cf1@outlook.com/ Found by FuzzNvme. Signed-off-by: Chao Shi --- RFC: the refusal path is untested and the scoping is the part I am least sure of. * Build-tested only. W=1 clean, with and without CONFIG_NVME_MULTIPATH. syzkaller could not extract a reproducer, so the new path has not run. * Is the exemption right? It keeps "nvme format" working on a namespace that merely has a udev probe open. But it also lets through the one case where a change is expected. * NVME_CTRL_SELF_RESCAN is best effort. An AER-driven rescan inside the nvme_passthru_end() window looks solicited. * Only lba_shift and ms are compared. A PI type change with the same metadata size is not caught. * Replaces an earlier attempt from my group that Christoph NAK'd. We are dropping it rather than respinning it. drivers/nvme/host/core.c | 40 ++++++++++++++++++++++++++++++++++++++++ drivers/nvme/host/nvme.h | 1 + 2 files changed, 41 insertions(+) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 453c1f0b2dd0..ebac5a3d1a07 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1285,8 +1285,15 @@ void nvme_passthru_end(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u32 effects, } } if (effects & (NVME_CMD_EFFECTS_NIC | NVME_CMD_EFFECTS_NCC)) { + /* + * The host asked for this change, so let the rescan adopt the + * new namespace geometry even if the disk is open. Only an + * unsolicited change is refused, see nvme_update_ns_info_block(). + */ + set_bit(NVME_CTRL_SELF_RESCAN, &ctrl->flags); nvme_queue_scan(ctrl); flush_work(&ctrl->scan_work); + clear_bit(NVME_CTRL_SELF_RESCAN, &ctrl->flags); } if (ns) return; @@ -2384,6 +2391,17 @@ static bool nvme_invalid_lba_sz(u64 nsze, signed int shift, sector_t *capacity) return check_shl_overflow(nsze, shift, capacity); } +/* + * Openers of a multipath namespace go to the head disk; the per-path disk is + * hidden and never has any. + */ +static unsigned int nvme_ns_openers(struct nvme_ns *ns) +{ + if (nvme_ns_head_multipath(ns->head)) + return disk_openers(ns->head->disk); + return disk_openers(ns->disk); +} + static int nvme_update_ns_info_block(struct nvme_ns *ns, struct nvme_ns_info *info) { @@ -2436,6 +2454,28 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns, goto out; } + /* + * Changing the LBA format or the metadata size reinterprets everything + * the host has already cached, queued or handed to the integrity code + * for this namespace, and freezing the queue does not cover any of it: + * page cache contents, bios batched on a plug and the deferred + * integrity verify work all outlive the freeze. If such a change + * arrives unsolicited while the namespace is in use, refuse it and let + * the caller take the namespace offline rather than adopt a geometry + * that describes something else than what the host is holding. + */ + if (nvme_ns_openers(ns) && + !test_bit(NVME_CTRL_SELF_RESCAN, &ns->ctrl->flags) && + (ns->head->lba_shift != id->lbaf[lbaf].ds || + ns->head->ms != le16_to_cpu(id->lbaf[lbaf].ms))) { + dev_err(ns->ctrl->device, + "unsolicited format change on in-use nsid %u (lba_shift %u -> %u, ms %u -> %u)\n", + info->nsid, ns->head->lba_shift, id->lbaf[lbaf].ds, + ns->head->ms, le16_to_cpu(id->lbaf[lbaf].ms)); + ret = NVME_SC_INVALID_NS | NVME_STATUS_DNR; + goto out; + } + lim = queue_limits_start_update(ns->disk->queue); memflags = blk_mq_freeze_queue(ns->disk->queue); diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 824651cc898d..93c15d5580e3 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -329,6 +329,7 @@ enum nvme_ctrl_flags { NVME_CTRL_SKIP_ID_CNS_CS = 4, NVME_CTRL_DIRTY_CAPABILITY = 5, NVME_CTRL_FROZEN = 6, + NVME_CTRL_SELF_RESCAN = 7, }; struct nvme_ctrl { base-commit: f5bbbfec59b4e2fb7520a91de3df8a6174325d6a -- 2.43.0