summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNamjae Jeon <linkinjeon@kernel.org>2026-06-21 21:21:01 +0900
committerSteve French <stfrench@microsoft.com>2026-06-22 20:15:06 -0500
commit474fd91f3828a89dd7dc0a862f77f14e9f9240ff (patch)
tree4afe5698cfb5f0f827a9f280465cce71226210f0
parent5a7f4d6d8e7fc9c3b67412f1b8e5b56c9aec21af (diff)
ksmbd: fix UBSAN array-index-out-of-bounds in decode_compress_ctxt()
decode_compress_ctxt() walks CompressionAlgorithms[] using the client supplied CompressionAlgorithmCount. That field is declared in struct smb2_compression_capabilities_context as a fixed 4-element array, but the number of algorithms is actually variable and clients such as Windows advertise more than four (e.g. LZ77, LZ77+Huffman, LZNT1, Pattern_V1 and LZ4). The on-wire context length is already validated, so the access is within the received buffer, but indexing the statically sized [4] array makes UBSAN report an out-of-bounds access: UBSAN: array-index-out-of-bounds in smb2pdu.c:1122:48 index 4 is out of range for type '__le16 [4]' Call Trace: smb2_handle_negotiate+0xda7/0xde0 [ksmbd] ksmbd_smb_negotiate_common+0x27b/0x3e0 [ksmbd] smb2_negotiate_request+0x14/0x20 [ksmbd] handle_ksmbd_work+0x181/0x500 [ksmbd] Walk the algorithms through a pointer so the fixed-array bounds check is not applied, while keeping the existing length validation that bounds the loop to the data actually received. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
-rw-r--r--fs/smb/server/smb2pdu.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index c0d3062e4d93..5859fa68bb84 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -1094,6 +1094,7 @@ static __le32 decode_compress_ctxt(struct ksmbd_conn *conn,
int ctxt_len)
{
int alg_cnt, algs_size, i;
+ __le16 *algs;
if (sizeof(struct smb2_neg_context) + 10 > ctxt_len) {
pr_err("Invalid SMB2_COMPRESSION_CAPABILITIES context length\n");
@@ -1118,8 +1119,15 @@ static __le32 decode_compress_ctxt(struct ksmbd_conn *conn,
return STATUS_INVALID_PARAMETER;
}
+ /*
+ * CompressionAlgorithms[] is declared as a fixed 4-element array, but
+ * the actual element count is variable (clients such as Windows may
+ * advertise more). The on-wire length was validated above, so walk the
+ * algorithms through a pointer to avoid a fixed-array bounds check.
+ */
+ algs = pneg_ctxt->CompressionAlgorithms;
for (i = 0; i < alg_cnt; i++) {
- __le16 alg = pneg_ctxt->CompressionAlgorithms[i];
+ __le16 alg = algs[i];
/*
* LZ77 is the required general-purpose codec. Pattern_V1 is an