mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 10:09:10 +02:00
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>
This commit is contained in:
parent
5a7f4d6d8e
commit
474fd91f38
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user