From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pg1-f175.google.com (mail-pg1-f175.google.com [209.85.215.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 95F7C2D8376 for ; Mon, 11 May 2026 16:06:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.175 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778515597; cv=none; b=Fmf5esBlp95jePEW5evwHMqq5xtPSxrGdMQRLZ65APjZpGw0uF8sBuhopIMwWs9HP3eILKXuOf+8I/mkLjU3uG1ymobfnCeWnSis4lXfYqBfm4S9cwPBe3ZAAiEAA1mC/Yut8QBAZ/mQPg83qkPkwpFMCzQ81DQ84835NPsDGCA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778515597; c=relaxed/simple; bh=O7vxKwK4Frz7hw3ZsessBjAsAnJnPJnx/DkxIn7A+M4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JzHtLc/XoHD+91uWZ/G84zytH24GXmRXApZmeOvv+30jIoS/CJ/c1A8QpWH3PUdM7eYP7I/3AXkvkkQe+F7xjsaqMKfdXBsBcG5AZ5Ur1r1YINEmDZpc/Q0D1lm+v2McLogt7OsDEdGO02vwwm2BlsGKfjJOPGuPjZxXmq0F0mk= 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=cv5idmbU; arc=none smtp.client-ip=209.85.215.175 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="cv5idmbU" Received: by mail-pg1-f175.google.com with SMTP id 41be03b00d2f7-c70e3eb3af1so173326a12.2 for ; Mon, 11 May 2026 09:06:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778515593; x=1779120393; 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=DGyckoWlKcj/g+dvE3DVtCFjUKqFutWWvhlGNP+u3/Y=; b=cv5idmbUvwwbsLar+rJ+v0orLgJTCjLfgcHPDdRDEFretshVL1lbVBejHNm3+Wt1Y2 CJvjyrcWOTe+opE6bE4C0Q/OQeBpN4FMR6NZjGukEQtjB2ljJZVjePxX5DIdaYo+yNxc Gb09LpHs6SqRb1Ph2oeGqnNpnUwBxpqLLXObN0R23m+MwzgSDCP06vfO8WnPJM4y5cLq Qu3gBruJWTk+kVOQbxW2nGD/3YpwOOrDtljOnCUDccYfLV6prSJjCs5SYfvZqHSgVrT6 Pn0TcDoDXi7fFYTvT+Lbhwof6NImX4eUPk6AnLZ6Ts0ICTYALm6lWbzVS+A+C43LtZDe ernA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778515593; x=1779120393; 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=DGyckoWlKcj/g+dvE3DVtCFjUKqFutWWvhlGNP+u3/Y=; b=RSdAHd1VTlcVib9HuF6cKo9nKLIzyi1wdlGZUzJTXLvVF0PbVvqEaT2am9GZJnHyqU i1fl4iKwN+BNqk7fmnPPXgew8OmvTxl1C/YYRS+rf86gKm+pl+yMXZAXJ1bK90ltwEUR IitOGTgcrIjYulJ4QvEQ7KJeOZSqLFDpLHnFlMQtncUBQh1knreY9WD0l3+2rOm3CAZL 1u7I2Gy4ytT6KJnw4V4u4Z80GXqEfoL7h0OuSK5cvzVwZlOS2YFcrCQ5tRowavR5EiVB zZ5bNp+Zf5PpNHG7jijSYau5/BvqF2v+6bKwomSb3mITBZzh8gWdWEJllkZQ5GHZ4FGp D91g== X-Forwarded-Encrypted: i=1; AFNElJ+hZB2DzUBuBBTEd0q4JkfTI7BZNUm6FECyfxHhK6ZWNRJA0eAO13L2wBwn6V7YnYZ2PV2iDGHjrtsZ1Gs=@vger.kernel.org X-Gm-Message-State: AOJu0YzgqprZmeW3+z7eP1T8wEAvV3IbFzBL+ciDn9DpN4W5H0yzHGmU uT55aFtZDWjtyu5T5p6wDRwfr66AYGB3p7+3XMbls8epOi7bpxA/RG/5 X-Gm-Gg: Acq92OG5vKEFm5dAf4Ga1U+UlgV3IWKnLl07Wchv3219VLuCNuh8XPEDP6LA5rdWBdq ftwDacuFJF+M4UewJzWAfplQCzZ3f9NVF6T0bYyc7xfKKlQKWflpI3W2j67Ts5PSb7wM8IWN/ND vi4yWX1zTY8vIbYSKVJQJYDItk7uSmL7W85XTsrkS9oTf7dhnHOSkC++oaXwgXUyzy5MFYEkeVZ U3DWTjUl3ezK1XiXMulNsYBTGHqRB/VKUzAg4pGLeHe5XlKQWIERQuZjUZ+PBh4V1KckLfJPHpN Fpc1MU54do7XzLNYv2w8cd5ZEaPikKrrdrZPLLHnsjy7+s/GwIca6gMLxqLrvrG+AOhsD6LAbeM cVnPCMEopDt0pzy2NEh6M8eRv/c4PS8w51Kb/GSKibLHi45gpQg+XJwhGrj2RoDeBjuTm5dT9qz kd7YcORdX3P0+dYE6FYGh4OYDPhA8= X-Received: by 2002:a17:902:d2cb:b0:2b2:aa7b:b3bd with SMTP id d9443c01a7336-2ba7f425857mr135549775ad.6.1778515593031; Mon, 11 May 2026 09:06:33 -0700 (PDT) Received: from ser8.. ([221.156.231.192]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2baf1e35ebesm112447045ad.43.2026.05.11.09.06.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 May 2026 09:06:32 -0700 (PDT) From: DaeMyung Kang To: linkinjeon@kernel.org, hyc.lee@gmail.com Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, DaeMyung Kang Subject: [PATCH 1/3] ntfs: return view index entry data from lookup Date: Tue, 12 May 2026 01:06:23 +0900 Message-ID: <20260511160626.1268612-2-charsyam@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260511160626.1268612-1-charsyam@gmail.com> References: <20260511160626.1268612-1-charsyam@gmail.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 ntfs_index_lookup() always exposes the matched entry key through icx->data. That is correct for file name indexes, where $I30 callers expect the key to be a struct file_name_attr and update it in place. NTFS view indexes store a separate value in index_entry.data.vi. For example, $Quota/$Q uses the owner_id as the key and stores the quota_control_entry in the entry value. Returning the key makes quota code see only the 4-byte owner_id instead of the quota control entry. Preserve the existing $FILE_NAME index behavior, but return the entry value for view indexes. Use the index root type for that layout decision: indexes with ir->type == AT_FILE_NAME expose the entry key, while view indexes have type 0 and expose the entry value through data.vi. Validate the value offset and length before exposing the pointer, and clear icx->data when the key is not found because the context then describes an insertion point rather than a matched value. Use unsigned arithmetic for the minimum data offset check, account for the VCN stored at the end of INDEX_ENTRY_NODE entries, and clear the returned context pointers before returning an entry-data validation error. Move the matched-entry data exposure and validation into a small helper, ntfs_index_lookup_set_data(), so the done label stays flat and the bounds check has a single return. Signed-off-by: DaeMyung Kang --- fs/ntfs/index.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- fs/ntfs/index.h | 3 +- 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/fs/ntfs/index.c b/fs/ntfs/index.c index a547bdc..30dfcbb 100644 --- a/fs/ntfs/index.c +++ b/fs/ntfs/index.c @@ -696,6 +696,53 @@ static int ntfs_icx_parent_dec(struct ntfs_index_context *icx) } /* + * ntfs_index_lookup_set_data - populate icx->data for the matched entry + * + * For directory $FILE_NAME indexes the caller updates the key in place, so + * expose the key. For view indexes the value lives at data.vi; validate + * its offset and length before exposing the pointer. Return 0 on success, + * or -EIO if the entry value is out of bounds. + */ +static int ntfs_index_lookup_set_data(struct ntfs_index_context *icx, + struct index_root *ir, + struct index_entry *ie) +{ + u16 data_len, data_off, entry_len, found_key_len; + unsigned int data_end, min_data_off; + + if (ie->flags & INDEX_ENTRY_END) + return -EIO; + + found_key_len = le16_to_cpu(ie->key_length); + if (ir->type == AT_FILE_NAME) { + icx->data = (u8 *)ie + offsetof(struct index_entry, key); + icx->data_len = found_key_len; + return 0; + } + + entry_len = le16_to_cpu(ie->length); + data_off = le16_to_cpu(ie->data.vi.data_offset); + data_len = le16_to_cpu(ie->data.vi.data_length); + data_end = entry_len; + if (ie->flags & INDEX_ENTRY_NODE) { + /* The trailing child VCN is not part of the entry value. */ + if (data_end < sizeof(s64)) + return -EIO; + data_end -= sizeof(s64); + } + + min_data_off = offsetof(struct index_entry, key) + found_key_len; + if (data_off < min_data_off || data_off > data_end) + return -EIO; + if (data_len > data_end - data_off) + return -EIO; + + icx->data = (u8 *)ie + data_off; + icx->data_len = data_len; + return 0; +} + +/* * ntfs_index_lookup - find a key in an index and return its index entry * @key: key for which to search in the index * @key_len: length of @key in bytes @@ -710,7 +757,8 @@ static int ntfs_icx_parent_dec(struct ntfs_index_context *icx) * If the @key is found in the index, 0 is returned and @icx is setup to * describe the index entry containing the matching @key. @icx->entry is the * index entry and @icx->data and @icx->data_len are the index entry data and - * its length in bytes, respectively. + * its length in bytes, respectively. For file name indexes @icx->data points + * to the entry key; for view indexes @icx->data points to the entry value. * * If the @key is not found in the index, -ENOENT is returned and * @icx is setup to describe the index entry whose key collates immediately @@ -836,11 +884,30 @@ err_out: return err; done: icx->entry = ie; - icx->data = (u8 *)ie + offsetof(struct index_entry, key); - icx->data_len = le16_to_cpu(ie->key_length); + if (err) { + /* When the key is not found, ie is an insertion point. */ + icx->data = NULL; + icx->data_len = 0; + ntfs_debug("Done.\n"); + return err; + } + err = ntfs_index_lookup_set_data(icx, ir, ie); + if (err) { + ntfs_error(sb, + "Index entry data out of bounds in inode 0x%llx.", + (unsigned long long)ni->mft_no); + icx->entry = NULL; + icx->data = NULL; + icx->data_len = 0; + if (!icx->is_in_root) { + kvfree(ib); + ib = NULL; + icx->ib = NULL; + } + goto err_out; + } ntfs_debug("Done.\n"); return err; - } static struct index_block *ntfs_ib_alloc(s64 ib_vcn, u32 ib_size, diff --git a/fs/ntfs/index.h b/fs/ntfs/index.h index e68d6fa..4b8c5c8 100644 --- a/fs/ntfs/index.h +++ b/fs/ntfs/index.h @@ -58,7 +58,8 @@ * To obtain a context call ntfs_index_ctx_get(). * * We use this context to allow ntfs_index_lookup() to return the found index * @entry and its @data without having to allocate a buffer and copy the @entry - * and/or its @data into it. + * and/or its @data into it. For file name indexes @data points to the entry + * key; for view indexes @data points to the entry value. * * When finished with the @entry and its @data, call ntfs_index_ctx_put() to * free the context and other associated resources. -- 2.43.0