From nobody Thu Sep 24 18:40:32 2026 Received: from mail-ej2-f11.google.com (mail-ej2-f11.google.com [74.125.228.139]) (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 9F476383306 for ; Mon, 21 Sep 2026 19:22:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.228.139 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790018551; cv=none; b=T8QWYI2AWNXYwkMcIQYHhUaShU4GzVsvEzw+10w4FfFZ27UQIgjkYp6GVN7kr4iQijkX/y+Z1laVoCrCHv8/x3USB5qyjplJwI8fO459DO1tQ2sBK21RAeV0kckZkq2nAYN+jm0dBnUJSfwJuMo7FXl98w4zJlgWnS1NcwDPmec= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790018551; c=relaxed/simple; bh=FORjZ+fzBUQoGWjjV47sA34KGPbyAZucnZ7k2MeTYmk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JmIjmUoQUpIgL1uV65YYF9at7zNDjJcI5+xSlYBDYSg9MMS3G/Rp8AGTDpg0qMmpvkDcE+Epr+ioBy7IdWD3JnafFnmf89072UQrCaHK5VLe+ufsyc9OCuuTm3VDN5vH04CRG8gPdqnE0cBvHZseBc4tQbkp7GVkPkpsok/zak0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bynar.io; spf=pass smtp.mailfrom=bynar.io; dkim=pass (2048-bit key) header.d=bynar.io header.i=@bynar.io header.b=EAaAI3Wj; arc=none smtp.client-ip=74.125.228.139 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bynar.io Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bynar.io Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bynar.io header.i=@bynar.io header.b="EAaAI3Wj" Received: by mail-ej2-f11.google.com with SMTP id a640c23a62f3a-c25541acec6so212903266b.0 for ; Mon, 21 Sep 2026 12:22:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bynar.io; s=google; t=1790018541; x=1790623341; 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:content-type; bh=GF+AtI+XGFI4gbDHylpglKuu+gz0u51gNx6gyLy45VM=; b=EAaAI3Wj4aA3+4ZIfFnJ2r8CIUQ87UD4MO0629kiC8amQmzQ/Q0xQRJkzbboAfBHGn Jtk2zJufVOYzP9rAeKccZ4O6D3+FVQIbqCl0/5xsXGPCLXHw/ImTI4nlk1dG8Hxpjl0D gOpxwKRHJ72le7vE6zQXDaSRMyE2EGyT4qGXeBrc8a7Grr6ZpkMTF16jqucpsYl4hUrl QrXG5HqTeYp2fChYtvhqj9XyYeVgXQwsd4mNhf1L9hPDm0v+opKJB4J5UG3upySi25v+ 2RelkaEHP7AO2x0m3FgrPwRqrO3GF3BRCGRURawvXZnq6rK7Kc2YZyDfzSgcF97N3HmX /CWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790018541; x=1790623341; 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:content-type; bh=GF+AtI+XGFI4gbDHylpglKuu+gz0u51gNx6gyLy45VM=; b=Cvh6qVU4JIbdJi2s+Duu5XcTD3CkKVt9Ixn2Ycs14iSBeEwIGtiCgYrwWi3EJNlPH7 v9CZtw4nQQJjFUW1qUTDoGSCdzrGUo1+F8yfymq4zX5UrvUOPPoNQOktfQSa3c2O3kP9 L3r7bxudiMgOZEOvlSP4xzsRQJdTI4gqvt6KiGEfsspXTJ+ja4QJ7t9gXmlQDcdg0PVv lAUwz699Er2wl9rg/u1CYcio9JdEm0sIQQ5MO7wC/jdLLLKEQ7nzAEVdJbnQDLF9Ollm E1rl1thHG+mP3RUPu/RULLtgSgKAW9Yhu3kWRIAgOWURwPDBZykqKCl35fQspCXXcpkp N1Fg== X-Forwarded-Encrypted: i=1; AKwUvBxex57fBh3jVbEVAIMTHDhPiheghPK0QP6IOSsTzyMh0Zx3EqIhDsJbYv4g3SqOB5/97GZ0dHn9b3MfaHU=@vger.kernel.org X-Gm-Message-State: AFuF++mHHlNaSynRQie9V1+QKSg02OHBrKuy9r7Kbdb2NgLqPBzB8bEr 6GzT9q3TbARmLRNf5jP6H+0YkRncbcbJd4CZcJF26GWvlRk6IiWXGTFYnQ7992a9dm2FDA5P1wM 178qIURTmAgw= X-Gm-Gg: AYBFou23+hjJCaWYqVwPPx/08WTubo71NoNUKLf4B3IyGl9hWHF/1gv2d7Nb0d9j2WZ DKL9NySFl1rI00B/eQo4HoMJTGxwNo66rIsp1qVrZJsRNjLxaL5yNYZaDAjSIdVCWcX4Z4HH/p1 BjimjuQdlR3NO33NZb3gpqAko/jfyJDlX7BrnZJoY2I7Qd5UZ9oWwH87v95W0dXpFti0zaeVbvY 30wS8JEVO0j30vx8jZmFFbIp5oX0l01bZx+Gjk8DGWSv/kAahlFrhdwxMnfmF/+JZT7bFigNswl yqkF9JgkRS/XU7Kwg3xUs4Wv5WdNLIJYCV9l9L7EFG2LgG/A4HgLEQh9UxM6G6ZYHz6VX2S11ER gXQqHt65xq/swFnzC8mhM51+YvFWgWWA5DLXYHNIDwqHhPXNbdUxtra6gt1pYIBA4IZoilBomm/ SAaLhcPQRRCh08swtTQrpqogiFzNSQYqYxhGEyjA== X-Received: by 2002:a17:906:c155:b0:c29:63f2:99bb with SMTP id a640c23a62f3a-c2a15d12004mr1081031466b.47.1790018541023; Mon, 21 Sep 2026 12:22:21 -0700 (PDT) Received: from cachyos ([151.38.78.32]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c2a358868e1sm341089066b.47.2026.09.21.12.22.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Sep 2026 12:22:20 -0700 (PDT) From: Giulia Aloia To: almaz.alexandrovich@paragon-software.com Cc: ntfs3@lists.linux.dev, linux-kernel@vger.kernel.org, cenzhang@linux.microsoft.com Subject: [PATCH 1/4] fs/ntfs3: validate dirty page open attribute offsets Date: Mon, 21 Sep 2026 21:21:36 +0200 Message-ID: <20260921192157.102738-2-giulia@bynar.io> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260921192157.102738-1-giulia@bynar.io> References: <20260921192157.102738-1-giulia@bynar.io> 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" The dirty-page walk in log_replay() uses dp->target_attr as a byte offset into the open attribute table without validating it first. Checking oe->next already dereferences the unchecked pointer. A malformed dirty-page entry can select the table header, the middle of an entry, or data beyond the table. The lookup can then read an invalid entry and follow a bogus attribute pointer. A crafted table dump containing a fake open attribute entry at bytes_per_rt(oatbl), within the larger dump buffer, produced the following on x86-64 before the fix: KASAN: maybe wild-memory-access in range [0x4141414141414148-0x414141414141414f] RIP: 0010:log_replay+0xa698/0xe690 Call Trace: ntfs_loadlog_and_replay+0x3e0/0x500 ntfs_fill_super+0x1fd3/0x4510 ... Require the offset to be at or beyond the end of the table header, below the logical table size, and aligned to the table's entry size. Also require that each entry can hold an OPEN_ATTR_ENRTY; together these checks keep the whole selected entry within the table. Reject invalid offsets with -EINVAL, as the redo lookup does. Keep the existing handling of unallocated entries and NULL attribute pointers. This lookup uses dirty-page table entries and is separate from the redo and undo log-record lookups discussed in the linked report. Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/20260901174934.6275-1-cenzhang@linux.micr= osoft.com/ Assisted-by: Bynario AI Signed-off-by: Giulia Aloia --- fs/ntfs3/fslog.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c index ed50c1d0c23e..8ac0dbd2f07f 100644 --- a/fs/ntfs3/fslog.c +++ b/fs/ntfs3/fslog.c @@ -4987,6 +4987,15 @@ int log_replay(struct ntfs_inode *ni, bool *initiali= zed) if (!dp) goto do_redo_1; =20 + t32 =3D le32_to_cpu(dp->target_attr); + t16 =3D le16_to_cpu(oatbl->size); + if (t16 < sizeof(*oe) || t32 < sizeof(*oatbl) || + t32 >=3D bytes_per_rt(oatbl) || + (t32 - sizeof(*oatbl)) % t16) { + err =3D -EINVAL; + goto out; + } + oe =3D Add2Ptr(oatbl, le32_to_cpu(dp->target_attr)); =20 if (oe->next !=3D RESTART_ENTRY_ALLOCATED_LE) goto next_dirty_page; --=20 2.55.0 From nobody Thu Sep 24 18:40:32 2026 Received: from mail-ed2-f35.google.com (mail-ed2-f35.google.com [74.125.228.99]) (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 70E50382371 for ; Mon, 21 Sep 2026 19:22:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.228.99 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790018552; cv=none; b=htNevMtbccyZNmIvBArHDNBbn+beGqtw6aIoNkC1dSqdSTvkQ2xQESx6/L9YLkYF9fPqYDUZANq2mUPmdhswadEcswYyGi9uPlojFOLLKRKyUqUgeasHba26pnTlbdpuf1B//dJzVofPno06B2sr/Uyu7INQzx9wnevxi49aEac= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790018552; c=relaxed/simple; bh=NgErlbLUKaTbV82GyCOv0H7r7vbemZOfW2qhNTDcQU4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Z2ipbfyx0RyDS2N9uWw2Bx1jUP7cPLGtjG2pgI5DTQnlsJCUhzNg01G7TTDijihA23lRFM/BOFbjEyAIT3oJvdn5bpJV3elefrucBWiXPowCm55e4qdgGMtOlmcPRrJDidx+JoCpPQFaufJtiIjTfQ1pPI8DhaMNDKCTlj8PEHk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bynar.io; spf=pass smtp.mailfrom=bynar.io; dkim=pass (2048-bit key) header.d=bynar.io header.i=@bynar.io header.b=EK4TF3sA; arc=none smtp.client-ip=74.125.228.99 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bynar.io Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bynar.io Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bynar.io header.i=@bynar.io header.b="EK4TF3sA" Received: by mail-ed2-f35.google.com with SMTP id 4fb4d7f45d1cf-6aa1da63791so4193286a12.1 for ; Mon, 21 Sep 2026 12:22:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bynar.io; s=google; t=1790018544; x=1790623344; 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:content-type; bh=znjZZmXp9qS1UAlr/gd4YJ/jtvWf7HtdoU4GR7qfmoY=; b=EK4TF3sAGFci75eIeDP8HueU5vpXeGNGgGM0rLOfcMlqV3FMlXcJF9mYMFeXyWOjce NtUDc+kSCr/OmegGJP1hf6mEzkvZzQpkhjw3fqVsXAqgGdXQkKrw7RmpierbwY6qLaqT e5JT0SWg7AJrMBaE13dHxmpP+j7AC1LTjhVp/Bqhn0z7dHI15VhxH4HwOt6Ps5fXUwv5 2FOhEAF1qRkeSGjbe2ZBI2hPKUDgeGo59Aj6+j8Mc8kQgROE2ZoZ8/XMNBq+y35XJAM1 4TDxzxuhl17BgOs9UResurFI8ofmf9kwxDuFQSEMHH9RiDM3Ov7DZt/98W50JtwNZ2Lu PZ9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790018544; x=1790623344; 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:content-type; bh=znjZZmXp9qS1UAlr/gd4YJ/jtvWf7HtdoU4GR7qfmoY=; b=FGkrbNDzf2J1FKPHgSjPzbbnR2UGYSlOCdlM3/y+AutTQDAnTenhzsAXmJksKO5VUP BOGl9WXmykrpSGmV0yDick8rHozwyUMpw/y8CH8aFyaNxfRO3/c9xcLHZ2uD1Osvrv+g skLXA5oAtULlAAs+MN84UYOt/Lsejbtr0vd4rlq5BxJ9WyfCH3HU8LgAxXHqs7bvEvAG nxFSpdvJ2uDRnML+6gTOLjfMUH/P8wUJyp2eWnNW6x0o9dRZD50fUbnGJLTyJhZfiohD lLogqecvUFLf0Yrd9yC/4ZKkQoHDkgEt8LpQeQyF815i3tilynzrwV1FNUaCNTwToB5m WI9Q== X-Forwarded-Encrypted: i=1; AKwUvBwiSipUeS2Zs7zwOQEfnll9xwNessM9x2CuapCcz2ZDhKRKsJ7DAwa0yCDvrp7hwIX/EWk+tIytb/7xsV0=@vger.kernel.org X-Gm-Message-State: AFuF++kTvk6YVgxoUkTtXC1nfDEsODIBX/sNJgWxtyWJvZr/sPlchEFt wogr3yCEzYRiEMGxwQwuqcIRRCXLc5s+muBI+t/jdySPjlx3rXVbQIEB0gf9pi7IXVZ1 X-Gm-Gg: AYBFou1emCjQ/urq0NfFXQG9vtziAu7QEB1gkGmh89dfrKV40RveLzUTliB2IJPyMhi a9gAxa+EN6ez5PnUiP9fhXYJqH12Iv77Qcx2ywp1JmIlaFySrYTiJIsqjpHcnCBYE42BLtmAh8q hmGscxcF0ZsER5PqqAJS/zabKPChoSAXxG9q6SwVjEWIl/HSZnyqwa8TnWkgsY+1LKDd2fGbtFR O9GBMaCObtaEyVy2fgww8wLEw2lKv9fg4QzZOKj8xfAELN8cyOtOgfOPIJ+A2Ppm2FQLVigez/d 6vPKZN5LtDfwrUrdahV9AhmTSJ0vpFvwc/lxAZpSIQBR52OCZ9qniF9dFUNFqpWrje2OmUYFww6 rBNdi0ipeqsP45hBYb1t746wRdDxwrCbs1Ia+FoqwdGA03HrveHH+wAHKr7e2f+2jwIl9eL7z9Z Rtr9oo5kpqGQ1gBpLRq4bquN7AO3DLOZdlFKn1IOsZ2Jfd0jLo X-Received: by 2002:a17:907:8e86:b0:c26:306f:289b with SMTP id a640c23a62f3a-c2a156d56d1mr881253966b.13.1790018544407; Mon, 21 Sep 2026 12:22:24 -0700 (PDT) Received: from cachyos ([151.38.78.32]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c2a358868e1sm341089066b.47.2026.09.21.12.22.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Sep 2026 12:22:23 -0700 (PDT) From: Giulia Aloia To: almaz.alexandrovich@paragon-software.com Cc: ntfs3@lists.linux.dev, linux-kernel@vger.kernel.org, cenzhang@linux.microsoft.com Subject: [PATCH 2/4] fs/ntfs3: validate restart table offsets in log records Date: Mon, 21 Sep 2026 21:21:37 +0200 Message-ID: <20260921192157.102738-3-giulia@bynar.io> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260921192157.102738-1-giulia@bynar.io> References: <20260921192157.102738-1-giulia@bynar.io> 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" check_log_rec() validates transact_id and target_attr by subtracting the 24-byte restart-table header size, sizeof(struct RESTART_TABLE), and then checking entry alignment. This is unsafe for offsets that point inside the header. For example, offset 8 is below the header size, so the unsigned subtraction wraps and the wrapped value can still pass the alignment check. The driver uses transact_id as an offset into the transaction table when it looks up or allocates entries during journal analysis. This happens even on read-only mounts, before replay stops for read-only mode, so the offset must be checked at this stage too. If a forged transact_id points into the restart-table header, analysis first reads header bytes as tr->next. If those bytes do not look allocated, it can then ask alloc_rsttbl_from_idx() to allocate an offset inside the header. With crafted table metadata, that can make replay overwrite restart-table header bytes and later treat those bytes as a TRANSACTION_ENTRY. The attribute-offset check is also skipped when lcns_follow is zero. However, lcns_follow only describes page_lcns[] payload. It does not mean target_attr is unused. OpenNonresidentAttribute can have no LCN payload but still uses target_attr to choose or create an open-attribute entry. Header and misaligned offsets can therefore reach the open-attribute allocator unchecked. For offset 8, the subtraction wraps on both 32-bit and 64-bit systems. The wrapped value is divisible by 40, sizeof(struct TRANSACTION_ENTRY), on both, so the transaction-ID check can accept it. The same wrapped value is also divisible by the 40-byte v1 open-attribute entry size and, on 64-bit systems, by 44, SIZEOF_OPENATTRIBUTEENTRY0, so the attribute-offset check can accept it too. For target_attr, replay can then interpret the restart table header as an open-attribute entry. With crafted on-disk values, the interpreted entry can contain a NULL open_attr pointer, which log_replay() later dereferences. This is reachable by mounting the crafted image on an x86-64 KASAN kernel before this fix: KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f] RIP: 0010:log_replay+0xca58/0xe690 Call Trace: ntfs_loadlog_and_replay+0x3e0/0x500 ntfs_fill_super+0x1fd3/0x4510 ... Reject offsets that point inside the restart-table header before subtracting the header size, so the subtraction cannot wrap. Validate nonzero target_attr values even when lcns_follow is zero. Preserve zero target_attr for records that require neither an attribute nor LCN work. Do not impose a table upper bound in check_log_rec(): valid records can require the analysis pass to grow the table. Before OpenNonresidentAttribute grows the open attribute table or selects an entry, validate target_attr against the actual oatbl->size as well. Alignment to the version-specific entry size used by check_log_rec() does not guarantee alignment to the slots used by the current table when the on-disk table size differs. Allow aligned offsets beyond the current table so valid records can still grow it. Cen Zhang described the target_attr underflow in the linked patch and proposed checks at the redo and undo lookups. Validate the offsets in check_log_rec() itself, including transact_id and records without LCNs. Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/20260901174934.6275-1-cenzhang@linux.micr= osoft.com/ Assisted-by: Bynario AI Signed-off-by: Giulia Aloia --- fs/ntfs3/fslog.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c index 8ac0dbd2f07f..8dd233ec7d2f 100644 --- a/fs/ntfs3/fslog.c +++ b/fs/ntfs3/fslog.c @@ -697,7 +697,7 @@ static bool check_log_rec(const struct LOG_REC_HDR *lr,= u32 bytes, u32 tr, =20 if (bytes < sizeof(struct LOG_REC_HDR)) return false; - if (!tr) + if (tr < sizeof(struct RESTART_TABLE)) return false; =20 if ((tr - sizeof(struct RESTART_TABLE)) % @@ -711,7 +711,7 @@ static bool check_log_rec(const struct LOG_REC_HDR *lr,= u32 bytes, u32 tr, return false; =20 if (lr->target_attr) - goto check_lcns; + goto check_target; =20 if (is_target_required(le16_to_cpu(lr->redo_op))) return false; @@ -719,12 +719,13 @@ static bool check_log_rec(const struct LOG_REC_HDR *l= r, u32 bytes, u32 tr, if (is_target_required(le16_to_cpu(lr->undo_op))) return false; =20 -check_lcns: - if (!lr->lcns_follow) +check_target: + if (!lr->lcns_follow && !lr->target_attr) goto check_length; =20 t16 =3D le16_to_cpu(lr->target_attr); - if ((t16 - sizeof(struct RESTART_TABLE)) % bytes_per_attr_entry) + if (t16 < sizeof(struct RESTART_TABLE) || + (t16 - sizeof(struct RESTART_TABLE)) % bytes_per_attr_entry) return false; =20 check_length: @@ -4737,6 +4738,12 @@ int log_replay(struct ntfs_inode *ni, bool *initiali= zed) =20 case OpenNonresidentAttribute: t16 =3D le16_to_cpu(lrh->target_attr); + if (t16 < sizeof(*oatbl) || + (t16 - sizeof(*oatbl)) % le16_to_cpu(oatbl->size)) { + err =3D -EINVAL; + goto out; + } + if (t16 >=3D bytes_per_rt(oatbl)) { /* * Compute how big the table needs to be. --=20 2.55.0 From nobody Thu Sep 24 18:40:32 2026 Received: from mail-ej2-f12.google.com (mail-ej2-f12.google.com [74.125.228.140]) (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 DA12C383C88 for ; Mon, 21 Sep 2026 19:22:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.228.140 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790018552; cv=none; b=L4FxxZY0M5cpi1Q07xghIDuqHPvK9R2YL7D3647R6nHTHleplhNGol5RFuquhWHoeZjEYhQ0UoM1bGTsxdqCahzm40I+qECvKYRw2L5M1OhGHZ+xauVJER5JmhJ6LVF2AFTn5iX65RMqbwRvwQrwv7jp75SUs0+cSVc9Qntvgjw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790018552; c=relaxed/simple; bh=DK9/H7hX+pru8m1l06zVYRmh9mh18UWQ0oNg5FaI1GI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=g+6uztRfjQ+Oq5kVdr1aXiiJ6Rw/ZSe2zqLzqFLHxUhmsHMWFKFjRjX3iCLINQl1HH682jivezEyJyaJY5YMzbSuhdVbAT0mKa7hguU0GVpHfAlBmbSKVN0mFwr2mABKT1So8HhL6oYH5ZOAEZV6eSCkT6tbZ7U7HAFPXWdFepw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bynar.io; spf=pass smtp.mailfrom=bynar.io; dkim=pass (2048-bit key) header.d=bynar.io header.i=@bynar.io header.b=cY7dNLKA; arc=none smtp.client-ip=74.125.228.140 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bynar.io Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bynar.io Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bynar.io header.i=@bynar.io header.b="cY7dNLKA" Received: by mail-ej2-f12.google.com with SMTP id a640c23a62f3a-c29703cb470so496900666b.0 for ; Mon, 21 Sep 2026 12:22:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bynar.io; s=google; t=1790018547; x=1790623347; 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:content-type; bh=HL+2RvScf1wUse1sj5lMjJEzeH15N+fw/R86yhvN+Co=; b=cY7dNLKA5C50r1X9n+F3UbZwQWmGwURtSVB/PShA5pMAImKRsyu8dIZh8px7+uiL11 +HQDz4uSNrfaU0uqTAXlaNq1yzeLpvheo50c6JjOOAfG08J2f7zTlLEMj8hgr+s2KHl2 x3sTKVmjcI//fjHkbNEBUtsIcbO6N1tinFxVfw608I5VVRQZfaViFRVvTi5uaoneFWRe GS4LAJcF5A5/0xlCn8HKS2Kf+hIzv3fRDmO8okpAfbo0ZWde3amcwh1tsBYFJVL7rkRe 0inJ7RMIWWl6HBIti71qWEo8EtVf5d5IZ5vrkpVkVnLrbwe5cEUMSJ53YonfMq+b77UN fAow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790018547; x=1790623347; 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:content-type; bh=HL+2RvScf1wUse1sj5lMjJEzeH15N+fw/R86yhvN+Co=; b=hFxD2il3ntrMJ+XDPTqh5bSddBsfWP/cAlcfsmZ24SszQLhlSmG/1tg1WW3gRwUUjq 86M/BOY+YFRJ6Pi+yxnWIU5mxXXP1rm1h2r6X2WW4SYE83GuDoU4ZI6TFDyXj32Y9OdY uT6atVq/PngFXjsZj64V2jsbtS8V3OWFe2p6H2PhmBsa9GKAFlKJzP3LK6hBcKkMd0tE mLeN9w+KY+eddoqvvFkAjtZRo2Coj5xCeA72NbBXtPb0NzIjn+wVZm3QLaWQ9NQwyfk4 R4CTxtba/zqR2dPhF4aUYJ3SyZ64kkqDaucYgNLA+odvg2+7OaEfvyh6WVCfEd5/XTvs wbgQ== X-Forwarded-Encrypted: i=1; AKwUvBxLSUjqzcQuStnhTZflKRHGoHtcUoqTgTuejQrcJb5iqPiOCdrUfR8PKgyhHeWM7Hv0wfp8dXzmEWwCz1c=@vger.kernel.org X-Gm-Message-State: AFuF++kHEcMvoxe0R5YrnJfmuT2XJezcynxdwVGCB21Pm91GErRsPMXY G2tCCUxFlVCltchPe74faLkGFSOlJO+oL31CMr9r2dGlIz4m29R7qwohEAI5irS068vw X-Gm-Gg: AYBFou1+EL+hFeiKMn1Vl/t40w22bxF+xu2RKKHUqDy9H6ANzaN2T/bQoWnJCPapGJH 5VY3q3U3/jlst3bfw+GNd1mGA6DX1thueG1fSjGzGfS0QRGTdH59ENo0Fdq8E+V5atVU4OfA2wk Qg5nd6vxL8+07KHICc1LlFG09PMu3I7Sc4k7zuheyXfZ44RkmVtSeMabVo+Vu4+DjDi+ZjnhOtn qT64Hf/L/2QaPPt+6AW2YR4jsxy48COiMDkwNSbT7o08n4GQDiHhVCSUUcP7AU8oxz07XJwNhey WG44MGGLT5sFANMzwAQHuV8ATvsUHyTzjlDlApnhLKfEM3TLNJesW7EcsPeq+ChBXEqqcJBBBTz dtHfcUQJeOKcn/9TPE3kmjCSykTc/0ZMfZNeKhubK1lXhetEGQpCFcgtd0/EPeFWnk9Sr/u+QjU 6f9ocv6yL7txDkVfWuhXbPlDaAIr5FYZwehFAD X-Received: by 2002:a17:906:99c4:b0:c29:f5d8:9c82 with SMTP id a640c23a62f3a-c2a15ad760bmr961056466b.49.1790018547221; Mon, 21 Sep 2026 12:22:27 -0700 (PDT) Received: from cachyos ([151.38.78.32]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c2a358868e1sm341089066b.47.2026.09.21.12.22.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Sep 2026 12:22:26 -0700 (PDT) From: Giulia Aloia To: almaz.alexandrovich@paragon-software.com Cc: ntfs3@lists.linux.dev, linux-kernel@vger.kernel.org, cenzhang@linux.microsoft.com Subject: [PATCH 3/4] fs/ntfs3: validate on-disk restart tables before use Date: Mon, 21 Sep 2026 21:21:38 +0200 Message-ID: <20260921192157.102738-4-giulia@bynar.io> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260921192157.102738-1-giulia@bynar.io> References: <20260921192157.102738-1-giulia@bynar.io> 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" log_replay() locates restart-table dumps using redo_off and passes the remaining record length to check_rstbl(). However, check_log_rec() does not ensure that redo_off leaves room for a complete RESTART_TABLE header. check_rstbl() reads the header fields before validating the table size, so a truncated dump or an offset beyond the record can cause an out-of-bounds read. Before passing an on-disk restart table to check_rstbl(), require redo_off to leave enough bytes in the log record for a complete RESTART_TABLE header. Apply this to the transaction, dirty-page and open-attribute table dumps. For the open-attribute table, also require the table entry size to be at least as large as the expected entry size for the restart-area version. This ensures that each slot is large enough for the entry format used when converting and initializing the table. check_rstbl() also accepts transaction tables whose entry size differs from sizeof(struct TRANSACTION_ENTRY). check_log_rec() aligns transact_id to that structure size, not the on-disk entry size. Accessing smaller entries can read or write past their end. Larger entries can make an accepted offset point into the middle of a slot and leave too little space for the transaction fields. Require the entry size to equal sizeof(struct TRANSACTION_ENTRY) when loading the table. This also protects accesses to existing transaction entries, which bypass alloc_rsttbl_from_idx(). This is reachable by mounting the crafted image on an x86-64 KASAN kernel before this fix: KASAN: slab-out-of-bounds in log_replay+0x8094/0xe690 Write of size 8 at addr ffff888101107680 by task mount/67 Call Trace: log_replay+0x8094/0xe690 ntfs_loadlog_and_replay+0x3e0/0x500 ntfs_fill_super+0x1fd3/0x4510 ... Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal") Cc: stable@vger.kernel.org Assisted-by: Bynario AI Signed-off-by: Giulia Aloia --- fs/ntfs3/fslog.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c index 8dd233ec7d2f..e3b5a19f0e30 100644 --- a/fs/ntfs3/fslog.c +++ b/fs/ntfs3/fslog.c @@ -4274,12 +4274,17 @@ int log_replay(struct ntfs_inode *ni, bool *initial= ized) } =20 t16 =3D le16_to_cpu(lrh->redo_off); + if (t16 > rec_len || rec_len - t16 < sizeof(*rt)) { + err =3D -EINVAL; + goto out; + } =20 rt =3D Add2Ptr(lrh, t16); t32 =3D rec_len - t16; =20 /* Now check that this is a valid restart table. */ - if (!check_rstbl(rt, t32)) { + if (le16_to_cpu(rt->size) !=3D sizeof(struct TRANSACTION_ENTRY) || + !check_rstbl(rt, t32)) { err =3D -EINVAL; goto out; } @@ -4314,6 +4319,10 @@ int log_replay(struct ntfs_inode *ni, bool *initiali= zed) } =20 t16 =3D le16_to_cpu(lrh->redo_off); + if (t16 > rec_len || rec_len - t16 < sizeof(*rt)) { + err =3D -EINVAL; + goto out; + } =20 rt =3D Add2Ptr(lrh, t16); t32 =3D rec_len - t16; @@ -4441,11 +4450,16 @@ int log_replay(struct ntfs_inode *ni, bool *initial= ized) } =20 t16 =3D le16_to_cpu(lrh->redo_off); + if (t16 > rec_len || rec_len - t16 < sizeof(*rt)) { + err =3D -EINVAL; + goto out; + } =20 rt =3D Add2Ptr(lrh, t16); oatbl_bytes =3D rec_len - t16; =20 - if (!check_rstbl(rt, oatbl_bytes)) { + if (le16_to_cpu(rt->size) < bytes_per_attr_entry || + !check_rstbl(rt, oatbl_bytes)) { err =3D -EINVAL; goto out; } --=20 2.55.0 From nobody Thu Sep 24 18:40:32 2026 Received: from mail-ej2-f12.google.com (mail-ej2-f12.google.com [74.125.228.140]) (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 68B62383304 for ; Mon, 21 Sep 2026 19:22:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.228.140 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790018555; cv=none; b=oOGiBBEtkz3d6GRnlB404kDX+3D0yfpQuL/EKrQZIuj3T5rDDAaoHe2kzmF1RmzJJODLnewoBJqbnsbiGy8p2N7UgRFRZRPBjPX0esMuqpjbqQzpxnFETcaZERE/nyTvdn3pUUzbkcTbkmxJQPb0E9xMue7gJQzUfuEiOaMnnLs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790018555; c=relaxed/simple; bh=1Vln5AnR/u+M091VrCo4DLzJl69oZOZDH1fIZSxbeZY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=n9MM1u31aG0rwtBIGDMAmVYKkx1xQXXu14M6JvuGaVxwkAjtHoljkiSqVm/GqINplrB9+uTQW9GkXOVRYNV03ikcsTg1ppKmXAj9nJCNjZWOT37gjCv5gHaiSl5bC9LtE2hBlICuwTsPHedzpIljopXk4BZsLD3HXJfu0a+qIVU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bynar.io; spf=pass smtp.mailfrom=bynar.io; dkim=pass (2048-bit key) header.d=bynar.io header.i=@bynar.io header.b=ZDhrrLm2; arc=none smtp.client-ip=74.125.228.140 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bynar.io Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bynar.io Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bynar.io header.i=@bynar.io header.b="ZDhrrLm2" Received: by mail-ej2-f12.google.com with SMTP id a640c23a62f3a-c254f9f0b1eso533130566b.1 for ; Mon, 21 Sep 2026 12:22:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bynar.io; s=google; t=1790018551; x=1790623351; 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:content-type; bh=+NR5tPh32B4WBEE8oYN6wKQK61Annl5nRH515L8upHQ=; b=ZDhrrLm2QAEPg8l6tmNfxLSyqKWz8GfirZmefGTQPZZJFyxsD7b9fjvb+J3tCCGcol SyW/5hHg1/mpbKBketsefq8p8CK6Q/bEpbUKZupjcL6rhD8O37H8quI117bK5030lC8O Pf4OCVwiISlgCrhDUxy/4jyqjQune9+HrGP+Fz+Mlp2+5vktZrDiZ0EZmAG0fMU8b6Bh k0MYeWd9YMvXcMDiLgd+2x3bOqlCILXy5j7ZM/yGw/RypF98xF2EeXnF9lidks0RWS8r nLqw77KxxUAQu/ry1b7x8wZbpA6Ya14D+ddEeFIzQdhTml8qx6xwGaerJZ8eP9Fy+0mN G9Lg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790018551; x=1790623351; 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:content-type; bh=+NR5tPh32B4WBEE8oYN6wKQK61Annl5nRH515L8upHQ=; b=m/DaYfRwbigk/xW0Cv5idx7N20lY5W+WR83WYMMGqtX7OSEq3tB3N3FdOQiAuLS21y llN8C6i3xc+doEIFPobG61XiGWOPdEPKifQMjVwJDGfKIdYrvU0cA4wpY2WoNhz+XSac n7kO95EAtCuHd7UoQ+bC3SGPW2g69SzithGG+7KlRKNrxWewaz9jEfHoC7L9+neLlEt4 kIrHx0vEN35v4nq/4Pi/n4QY/cQXFOecd6AyAm6qiQvEax/dZXn7yQUblo67flNxRBbS To2KEYjeJQX1GN2+N5vsqx0GcqLloT2uSpsXjwx38CmytKqwO2KaDiDxqwI7csh0Udm6 FErw== X-Forwarded-Encrypted: i=1; AKwUvBwWfT8FV5ZirJw75Y0cKzl/U6+pzX5K3y2rSLQV4B3GtqUR0KEgCpVk9jZE1J6LRGKrEdXxu1nfSFLwVUk=@vger.kernel.org X-Gm-Message-State: AFuF++lxzDdeV2p569sqMQgisuWiwVjY09kcD75S03gKBhgY8zeSEdXd 4ExvLl8xlXBPqUxbmVv5rXaPEWWEJ7as5dqrTCYaKChCsidPhQabwliUxRQz5ClhZZri X-Gm-Gg: AYBFou3d9lmV0/PnXwJV4f4/vTO9IunanH9xlB1Sf8cW3lCb5dWHGdtLert201uodmR jIq2yF76Ke5tt7Vgaf4cs44MqLdzX/QvVq3mnwzWqdQIsw0r03/zN1jwg4dd8dTAU59eOtu/GOG vQPYjT8txRudZmw9GdCNnIaaTebaAn8A4dUL/kLRRrqAtRMNixgYmdSLsweJloABvx9ky+ZOTuD yu7eC2/BAYBB8iEMQo0rrOtNb9AFrckmw3H0yzzXEEHjseh3KiVDYdP2u20pLnGjfboOPqZiwoA dQ+vxI7YzclPR0eQMZnPOtV7KnhabLOC3YhuXqODlQNDxf81pSxOA6Au6p+IFxTACHxpKSbmHzD CbCJclSr5t1h0G+R9FLqK2yBS3b1U9+seTsJO5EvjtouoQMAO+OKT/OYWHTR5yVNxKQGR/BTRAH sXSgqX89LtSVOVRvWDwlpwpZwktNi2EKJvSacfNQ043wuuy98= X-Received: by 2002:a17:907:94cf:b0:c25:5114:c832 with SMTP id a640c23a62f3a-c2a156a37fdmr950115566b.3.1790018550970; Mon, 21 Sep 2026 12:22:30 -0700 (PDT) Received: from cachyos ([151.38.78.32]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c2a358868e1sm341089066b.47.2026.09.21.12.22.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Sep 2026 12:22:30 -0700 (PDT) From: Giulia Aloia To: almaz.alexandrovich@paragon-software.com Cc: ntfs3@lists.linux.dev, linux-kernel@vger.kernel.org, cenzhang@linux.microsoft.com Subject: [PATCH 4/4] fs/ntfs3: fix out-of-bounds access in alloc_rsttbl_from_idx() Date: Mon, 21 Sep 2026 21:21:39 +0200 Message-ID: <20260921192157.102738-5-giulia@bynar.io> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260921192157.102738-1-giulia@bynar.io> References: <20260921192157.102738-1-giulia@bynar.io> 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" alloc_rsttbl_from_idx() walks the restart table free list until it finds the requested offset. If the requested entry is not already allocated, the old code expects to find it in the free list and keeps walking until it does. A crafted on-disk restart table can use individually valid free-list offsets but still omit the requested entry from the list. When log replay asks alloc_rsttbl_from_idx() to allocate that entry, the old code keeps following the list without bound checks. This is reachable by mounting the crafted image on an x86-64 KASAN kernel before this fix: KASAN: use-after-free in log_replay+0x8986/0xe690 Read of size 4 at addr ffff888102477828 by task mount/67 Call Trace: log_replay+0x8986/0xe690 ntfs_loadlog_and_replay+0x3e0/0x500 ntfs_fill_super+0x1fd3/0x4510 ... Validate the requested offset against the table entry size before using it. Then bound the free-list search by rt->used and reject invalid, allocated, out-of-range, or misaligned links while walking. If the requested entry is not found in the bounded walk, return failure instead of continuing indefinitely. Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal") Cc: stable@vger.kernel.org Assisted-by: Bynario AI Signed-off-by: Giulia Aloia --- fs/ntfs3/fslog.c | 66 ++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c index e3b5a19f0e30..1793dd9ccfba 100644 --- a/fs/ntfs3/fslog.c +++ b/fs/ntfs3/fslog.c @@ -947,12 +947,20 @@ static inline void *alloc_rsttbl_idx(struct RESTART_T= ABLE **tbl) */ static inline void *alloc_rsttbl_from_idx(struct RESTART_TABLE **tbl, u32 = vbo) { + u32 i; u32 off; + u32 prev_off =3D 0; __le32 *e; + __le32 *prev_e =3D NULL; struct RESTART_TABLE *rt =3D *tbl; u32 bytes =3D bytes_per_rt(rt); + u16 used; u16 esize =3D le16_to_cpu(rt->size); =20 + if (esize < sizeof(__le32) || vbo < sizeof(struct RESTART_TABLE) || + (vbo - sizeof(struct RESTART_TABLE)) % esize) + return NULL; + /* If the entry is not the table, we will have to extend the table. */ if (vbo >=3D bytes) { /* @@ -968,57 +976,49 @@ static inline void *alloc_rsttbl_from_idx(struct REST= ART_TABLE **tbl, u32 vbo) *tbl =3D rt =3D extend_rsttbl(rt, bytes2idx / esize + 1, bytes); if (!rt) return NULL; + bytes =3D bytes_per_rt(rt); } =20 + used =3D le16_to_cpu(rt->used); + /* See if the entry is already allocated, and just return if it is. */ e =3D Add2Ptr(rt, vbo); =20 if (*e =3D=3D RESTART_ENTRY_ALLOCATED_LE) return e; =20 - /* - * Walk through the table, looking for the entry we're - * interested and the previous entry. - */ off =3D le32_to_cpu(rt->first_free); - e =3D Add2Ptr(rt, off); - - if (off =3D=3D vbo) { - /* this is a match */ - rt->first_free =3D *e; - goto skip_looking; - } - - /* - * Need to walk through the list looking for the predecessor - * of our entry. - */ - for (;;) { - /* Remember the entry just found */ - u32 last_off =3D off; - __le32 *last_e =3D e; =20 - /* Should never run of entries. */ + for (i =3D 0; off; i++) { + if (i >=3D used || off =3D=3D RESTART_ENTRY_ALLOCATED || + off < sizeof(struct RESTART_TABLE) || + off > bytes - sizeof(__le32) || + (off - sizeof(struct RESTART_TABLE)) % esize) { + return NULL; + } =20 - /* Lookup up the next entry the list. */ - off =3D le32_to_cpu(*last_e); e =3D Add2Ptr(rt, off); =20 - /* If this is our match we are done. */ if (off =3D=3D vbo) { - *last_e =3D *e; + if (prev_e) { + *prev_e =3D *e; =20 - /* - * If this was the last entry, we update that - * table as well. - */ - if (le32_to_cpu(rt->last_free) =3D=3D off) - rt->last_free =3D cpu_to_le32(last_off); - break; + if (le32_to_cpu(rt->last_free) =3D=3D off) + rt->last_free =3D cpu_to_le32(prev_off); + } else { + rt->first_free =3D *e; + } + goto found; } + + prev_e =3D e; + prev_off =3D off; + off =3D le32_to_cpu(*e); } =20 -skip_looking: + return NULL; + +found: /* If the list is now empty, we fix the last_free as well. */ if (!rt->first_free) rt->last_free =3D 0; --=20 2.55.0