From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4DCCB3F7AB3; Tue, 28 Apr 2026 10:41:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777372916; cv=none; b=ecuNII636yHNv7+DwHKDnflHMm+PjZJdy4HK2gGOcwF3Bv2FoVrnz4jBDUMKXb7IiFLyxWOvLY2ag0edzxEwe46gBfClnBwAdtC2bf4++t77XJWLEsNPcD1JbbAhtcF2hZMHKbxFwSZwx+xZjAeKkj/ebvqlzN8g98BQ5lpPsDg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777372916; c=relaxed/simple; bh=xOQhvTSWQ6gIx9DqleNJ3v6jwcJQnbebJT1dEWP3NZo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Icaj2wMgWfDdIbv6u/6C7ZJaDKqVQ47kyPHBFErUN32uxm5yHPaWQ684U0kWzPAApOqwFaT8Th31UnKl79PzaURn+DyhZWGtyBes8YBhMw/5xWqh6o5CeFFkvCJis/0H6qyWEIQn1ORV3q9qu9M13d1JjneLUtoQZAG+VAgpatY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=L0FkNfhy; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="L0FkNfhy" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 463C5C2BCB5; Tue, 28 Apr 2026 10:41:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777372916; bh=xOQhvTSWQ6gIx9DqleNJ3v6jwcJQnbebJT1dEWP3NZo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=L0FkNfhyjboOqUZG1yTF6aLNvY3uVOaJayjBlAgt+wAxpEt85lA8HuFmHmKhVVBuK jO2VVmti8chWZFO37m66P1/RLVXhnkMUuQ+cJ9QSYNsNnEW/9Cf4CWXCKVAgDbL1OQ muj6YZMBg00vBhDpD0APA2MRSNK1eaCVfoZW2OdC5pAbMPqK6GZ8gLrbs8R0vVUJDJ 1C5zLTV9UFxAAratg1OCY/Bp+BbqSEpOMHD2BcXBa4FRIJMLO2jufWsCX+7GFGsMq6 W3PUBkvDKx8n3ienHKjC9hbJCMedV0sWpggKrriyhCZUaFrHS5OOa2jmj6cxQimmbb q4HtR5Ck2gSkA== From: Sasha Levin To: patches@lists.linux.dev, stable@vger.kernel.org Cc: Enzo Matsumiya , Steve French , Sasha Levin , sfrench@samba.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-kernel@vger.kernel.org Subject: [PATCH AUTOSEL 7.0-6.12] smb: client: compress: fix counting in LZ77 match finding Date: Tue, 28 Apr 2026 06:40:27 -0400 Message-ID: <20260428104133.2858589-16-sashal@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260428104133.2858589-1-sashal@kernel.org> References: <20260428104133.2858589-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 7.0.2 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Enzo Matsumiya [ Upstream commit 20d4f9efe008be1b673f43d38d3d99fb1fd4cd68 ] - lz77_match_len() increments @cur before checking for equality, leading to off-by-one match len in some cases. Fix by moving pointers increment to inside the loop. Also rename @wnd arg to @match (more accurate name). - both lz77_match_len() and lz77_compress() checked for "buf + step < end" when the correct is "<=" for such cases. Signed-off-by: Enzo Matsumiya Signed-off-by: Steve French Signed-off-by: Sasha Levin --- LLM Generated explanations, may be completely bogus: Now I have enough information to perform the analysis. Let me structure my response covering all 9 phases. ## PHASE 1: COMMIT MESSAGE FORENSICS ### Step 1.1: PARSE THE SUBJECT LINE - Subsystem: `smb: client: compress:` (SMB 3.1.1 client-side compression) - Action verb: "fix" - Summary: fix counting in LZ77 match finding - **Record:** `[smb/client/compress]` `[fix]` `[off-by-one in LZ77 match length counting]` ### Step 1.2: PARSE ALL COMMIT MESSAGE TAGS - `Signed-off-by: Enzo Matsumiya ` (author) - `Signed-off-by: Steve French ` (subsystem maintainer) - NO `Fixes:` tag, NO `Cc: stable`, NO `Reported-by:`, NO `Link:`, NO `Tested-by:`, NO `Reviewed-by:`, NO `Acked-by:` - **Record:** Minimal tag set - only author + maintainer SOBs. No explicit stable/reviewer endorsements. ### Step 1.3: ANALYZE THE COMMIT BODY TEXT Two distinct bugs described: 1. `lz77_match_len()` byte-by-byte fallback increments `@cur` before equality check, over-counting match length by 1 on mismatch. 2. Both `lz77_match_len()` do-while and `lz77_compress()` do-while use `<` where `<=` is correct for the 8-byte window check, causing early exit to slow byte-by-byte fallback. - **Record:** Bug: off-by-one in match length produces incorrect LZ77 compressed output. Failure mode: decompressed data mismatches original (data corruption) on SMB3.1.1 compressed writes. ### Step 1.4: DETECT HIDDEN BUG FIXES - This is explicitly labeled as a fix ("fix counting"). Not hidden. - **Record:** Explicit bug fix with clear root cause described. ## PHASE 2: DIFF ANALYSIS - LINE BY LINE ### Step 2.1: INVENTORY THE CHANGES - 1 file: `fs/smb/client/compress/lz77.c` - +10/-7 (17 lines changed) - Functions: `lz77_match_len()`, `lz77_compress()` - Scope: single-file surgical fix - **Record:** Minimal-scope single-file fix. ### Step 2.2: UNDERSTAND THE CODE FLOW CHANGE Three hunks: 1. Rename parameter `wnd` → `match` (cosmetic, all occurrences). 2. Change `cur + LZ77_STEP_SIZE < end` → `<= end` in `lz77_match_len()` do-while. 3. Restructure byte-by-byte fallback: was `while(cur> 3; return (cur - start); - } while (likely(cur + LZ77_STEP_SIZE < end)); + } while (likely(cur + LZ77_STEP_SIZE <= end)); - while (cur < end && lz77_read8(cur++) == lz77_read8(wnd++)) - ; + /* Fallback to byte-by-byte comparison for last <8 bytes. */ + while (cur < end && lz77_read8(cur) == lz77_read8(match)) { + cur++; + match++; + } return (cur - start); } @@ -195,7 +198,7 @@ noinline int lz77_compress(const void *src, u32 slen, void *dst, u32 *dlen) flag_pos = dstp; dstp += 4; } - } while (likely(srcp + LZ77_STEP_SIZE < end)); + } while (likely(srcp + LZ77_STEP_SIZE <= end)); while (srcp < end) { u32 c = umin(end - srcp, 32 - flag_count); -- 2.53.0