mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
ksmbd: validate compression Flags before kvmalloc
ksmbd_decompress_request() allocated the decompressed request buffer
before smb_compression_decompress() rejected unknown transform Flags or
chained mode when it was not negotiated. A remote peer could force a
transient multi-megabyte allocation that was immediately freed on
-EINVAL.
Validate CHAINED/NONE Flags and compress_chained before kvmalloc.
Link: https://github.com/namjaejeon/ksmbd/issues/529
Fixes: a08de24c2b ("ksmbd: negotiate and decode SMB2 compression")
Signed-off-by: Anatolii Shumak <anatoliy.shumak@gmail.com>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
0710dd0882
commit
ba3afa8ccd
|
|
@ -46,13 +46,22 @@ int ksmbd_decompress_request(struct ksmbd_conn *conn)
|
|||
return -EINVAL;
|
||||
|
||||
orig_size = le32_to_cpu(hdr->OriginalCompressedSegmentSize);
|
||||
/*
|
||||
* For chained transforms the top-level header is only eight bytes; the
|
||||
* Flags field overlays the first payload header. Reject unknown Flags
|
||||
* and unnegotiated chained mode before allocating the output buffer.
|
||||
*/
|
||||
if (hdr->Flags == cpu_to_le16(SMB2_COMPRESSION_FLAG_CHAINED)) {
|
||||
if (!conn->compress_chained)
|
||||
return -EINVAL;
|
||||
out_size = orig_size;
|
||||
} else {
|
||||
} else if (hdr->Flags == cpu_to_le16(SMB2_COMPRESSION_FLAG_NONE)) {
|
||||
offset = le32_to_cpu(hdr->Offset);
|
||||
if (offset > pdu_size - sizeof(*hdr) ||
|
||||
check_add_overflow(orig_size, offset, &out_size))
|
||||
return -EINVAL;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
max_allowed_pdu_size = SMB3_MAX_MSGSIZE + conn->vals->max_write_size;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user