From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f53.google.com (mail-pj1-f53.google.com [209.85.216.53]) (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 AF942233952 for ; Wed, 24 Jun 2026 03:44:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.53 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782272677; cv=none; b=iw0p2A4ZgYWwpIH3ZV/Ij8sycQOJRnXN6nYe1hzuk9PV0aRcJe5fVYMN1SUri+x02aDIX3wfE9yW1xU5i51nznpIItLQ6j5J0zZ++clQsAhgwP7/iTGaiFhi6S6DiN5GXJudYUz5QKcRck9P7XE/ZcBy5U67LbL3O1TKVfJatJg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782272677; c=relaxed/simple; bh=q25iHf+CTLzOTtX70p4T5EsLMPiZX1/QhXL5i3mo6es=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WODwkfqHBeL1Smb3LB+Jm3z3vSOJfgS1rAuoerQVYjujdGonMDm6EZ8cMrQ90fu6hkML0/sE2GO10cPcOHW8trJlQ8IpPZlmBXOVHL21dXNZBYRWn7po0TVORLFSrRmHhh0Yk0R80HdOUcLlEPW0WJdIgMiiJrfwUWi60DhNWf4= 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=PnVtaY4P; arc=none smtp.client-ip=209.85.216.53 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="PnVtaY4P" Received: by mail-pj1-f53.google.com with SMTP id 98e67ed59e1d1-37de8c6a2b6so4907a91.0 for ; Tue, 23 Jun 2026 20:44:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1782272676; x=1782877476; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=jot/AQTs3wic1cTjRFa2JPwvqng3r+y2tF1TTKTrEdE=; b=PnVtaY4P2my06EuhklNQMGBiTeo4i3R9I01dQPaG+5HXAaok3sK2hJtcWN5bAukk8x MLoZTZjxcTB9VNXFgOJ7JsQILqcJRItLL5uJCW0CSnDIlamAwFQQu19p1qUo9DoCGzP3 /Y4HI403TxNlkWjuIguIOlkmALwFjtyCfYh1ps7cm63EA3bJ7MkoJdXCKJfTvG/zWRym ADvV7hbteSGU6ajTBGCRuufZxg1/jDnLae3FwZt6QiVRbLlBMLYYPIQAEVlFczIGix8Q nNUTDkop1IbFW36C7ORrWvjuPWa2Cw8UmzVgtDbrrXbThz4KllUNeYENVUWO9LG3rHtf GfqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782272676; x=1782877476; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=jot/AQTs3wic1cTjRFa2JPwvqng3r+y2tF1TTKTrEdE=; b=kvl9ve93OX0ffeNr4uujYTRPJCDsspR77v7+OZQVm70iQEydtuMUFdkdCoQNVASUjG 1S6qVBqvbcS0E38vzgPfePom7gtDIi5jE7mG39L7T/XpZwnghYD0RMCWSuAK23o7+dt1 2LqLyDH9XUz3FxNFO9D1+oq8kX3NPOMgH6rwBe8xCI0D06Bgdu430Wg5bLYUpNFLXAwn O2mOTifsSHaoQSFjjAlE3pIomaM1eoq+K0fMxssnCSvh9736mR68puZkUWYUVg2/Sj1/ DgMJAXscGFvxFP5cAJjQ6ZHOSPnM4MMUJMuHxlke4tAL+KRefV7KDEZvY8tyY78VW0a9 rAXA== X-Forwarded-Encrypted: i=1; AFNElJ80vHj/anmCTwEHzE09yWCfoaviNjbDPyOYjsBpBTysUXZAJz3a5btsuhLtPpshEw7l6hBbAQgmVhlSWgU=@vger.kernel.org X-Gm-Message-State: AOJu0Yx9Yt9ILWTXFeY9oe461a8Km46i609Bob2y1Ar5pwEs8bb45BPZ a1a1AEIdamzAa5SV4uasVfwlORwRx4DgM7HlMkE2O016FYT8yaCu6JB6+S2avA== X-Gm-Gg: AfdE7ck/qN/7qxzuNhCuENUeJne1lqrk1wF0GoFURxgDh9JfsRPDaGvCpQAKxs47ZYZ tQ5lSuBHlY5TGEYxqxJW3RXIrYat4/bGqgCc56eZ+/8o9ZFKJxg0kxfY9KMNJ+owQLgkLkfZkrO mWsXEFCkbXJjeI4uF6RCnB9GsXf+i6EWD3EGx7aaF6MkNBJqia2f/UHteV14bSdh8Qlq3GyYhNo 7EQ8gREnkz1vKubknulOXg28zggWAfANmgZKuCr5JrQ8TfqhHrtuHIXu1KwKMw/uZQih6Psfics CuwV/J7D9oLzhXv/RNtv1Ipgd5HAu07SBXuB7Bg3UZSn84EPsAXzBM+LCXNuCj1pCvGvOWlJ14B BrEycxSrQdn0A77Adcdgm+0knsLGhVxwfWS1q8byWy3CQmHdJTj1xHs52IjKkNpf2D8jCVF6qEu iNIkrLDMmmeFGRcaPqIqkV247ltr+ie1XDcw== X-Received: by 2002:a05:6a21:6e97:b0:3b4:b259:6965 with SMTP id adf61e73a8af0-3bd2d099307mr1922286637.11.1782272675940; Tue, 23 Jun 2026 20:44:35 -0700 (PDT) Received: from osman.mioffice.cn ([43.224.245.178]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-c8bc326c487sm11233637a12.12.2026.06.23.20.44.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Jun 2026 20:44:35 -0700 (PDT) From: Zhan Xusheng X-Google-Original-From: Zhan Xusheng To: Konstantin Komarov Cc: ntfs3@lists.linux.dev, linux-kernel@vger.kernel.org, Zhan Xusheng Subject: [PATCH v5] fs/ntfs3: reject out-of-range evcn in mi_enum_attr() Date: Wed, 24 Jun 2026 11:44:30 +0800 Message-ID: <20260624034430.58214-1-zhanxusheng@xiaomi.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <71e5333c-bb8a-4886-bfa1-e1b4cb8ea451@paragon-software.com> References: <71e5333c-bb8a-4886-bfa1-e1b4cb8ea451@paragon-software.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit In mi_enum_attr(), the start/end VCN validation for non-resident attributes is: if (svcn > evcn + 1) goto out; When evcn is U64_MAX the "evcn + 1" expression wraps to 0 and any svcn passes the check. For evcn values close to U64_MAX (but not equal to it) the right-hand side is still a meaningless near-wrap upper bound, so a malformed on-disk attribute with svcn == 0 and evcn near U64_MAX can pass mi_enum_attr() unrejected. VCN (virtual cluster number) is a cluster index, so any valid evcn is bounded by the volume's total cluster count, which ntfs3 holds in sbi->used.bitmap.nbits (set up in ntfs_init_from_boot() before any caller of mi_enum_attr() runs). Reject evcn values that fall outside this range. However, an empty non-resident attribute (no allocated clusters) is legitimately encoded with svcn == 0 and evcn == -1 (U64_MAX), e.g. via attr->nres.evcn = cpu_to_le64((u64)vcn - 1) with vcn == 0. That sentinel must keep passing, so exclude evcn == U64_MAX from the range check. The existing "svcn > evcn + 1" test still tolerates the sentinel ("0 > 0" is false) and continues to require svcn == 0 for it, while the range check rejects every other out-of-range evcn and thereby also defuses the "evcn + 1" wraparound. svcn does not need its own bound: once evcn < nbits, "svcn > evcn + 1" implies svcn <= nbits. Fixes: 013ff63b6494 ("fs/ntfs3: Add more attributes checks in mi_enum_attr()") Signed-off-by: Zhan Xusheng --- fs/ntfs3/record.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/fs/ntfs3/record.c b/fs/ntfs3/record.c index 32bdb034c2a3..d6ca4ac35a45 100644 --- a/fs/ntfs3/record.c +++ b/fs/ntfs3/record.c @@ -202,7 +202,7 @@ struct ATTRIB *mi_enum_attr(struct ntfs_inode *ni, struct mft_inode *mi, u32 used = le32_to_cpu(rec->used); u32 t32, off, asize, prev_type; u16 t16; - u64 data_size, alloc_size, tot_size; + u64 svcn, evcn, data_size, alloc_size, tot_size; if (!attr) { u32 total = le32_to_cpu(rec->total); @@ -310,8 +310,22 @@ struct ATTRIB *mi_enum_attr(struct ntfs_inode *ni, struct mft_inode *mi, if (t32 && le16_to_cpu(attr->name_off) + t32 > t16) goto out; - /* Check start/end vcn. */ - if (le64_to_cpu(attr->nres.svcn) > le64_to_cpu(attr->nres.evcn) + 1) + /* + * Check start/end vcn. svcn == 0 with evcn == -1 (U64_MAX) is the + * sentinel for an empty non-resident attribute (no allocated + * clusters) and must be accepted: "svcn > evcn + 1" tolerates it, + * since "(u64)-1 + 1" is 0 and "0 > 0" is false. + * + * For a non-empty attribute evcn is a cluster index and must lie + * within the volume (sbi->used.bitmap.nbits, set up in + * ntfs_init_from_boot() before any caller of mi_enum_attr() runs). + * Bounding evcn also prevents a malformed value close to U64_MAX + * from slipping through the near-wrap "evcn + 1" upper bound. + */ + svcn = le64_to_cpu(attr->nres.svcn); + evcn = le64_to_cpu(attr->nres.evcn); + if (svcn > evcn + 1 || + (evcn != U64_MAX && evcn >= mi->sbi->used.bitmap.nbits)) goto out; data_size = le64_to_cpu(attr->nres.data_size); -- 2.43.0