diff options
| author | Namjae Jeon <linkinjeon@kernel.org> | 2026-06-21 21:21:01 +0900 |
|---|---|---|
| committer | Steve French <stfrench@microsoft.com> | 2026-06-22 20:15:06 -0500 |
| commit | 474fd91f3828a89dd7dc0a862f77f14e9f9240ff (patch) | |
| tree | 4afe5698cfb5f0f827a9f280465cce71226210f0 | |
| parent | 5a7f4d6d8e7fc9c3b67412f1b8e5b56c9aec21af (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.c | 10 |
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 |
