]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ksmbd: fix UBSAN array-index-out-of-bounds in decode_compress_ctxt()
authorNamjae Jeon <linkinjeon@kernel.org>
Sun, 21 Jun 2026 12:21:01 +0000 (21:21 +0900)
committerSteve French <stfrench@microsoft.com>
Tue, 23 Jun 2026 01:15:06 +0000 (20:15 -0500)
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>
fs/smb/server/smb2pdu.c

index c0d3062e4d936df7656ca8af167a8cab138c664d..5859fa68bb84f8175ce3392fe69c30ac7d9d6aa8 100644 (file)
@@ -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