Commit 6b4f875a authored by Nicholas Carlini's avatar Nicholas Carlini Committed by Steve French
Browse files

ksmbd: fix signededness bug in smb_direct_prepare_negotiation()



smb_direct_prepare_negotiation() casts an unsigned __u32 value
from sp->max_recv_size and req->preferred_send_size to a signed
int before computing min_t(int, ...). A maliciously provided
preferred_send_size of 0x80000000 will return as smaller than
max_recv_size, and then be used to set the maximum allowed
alowed receive size for the next message.

By sending a second message with a large value (>1420 bytes)
the attacker can then achieve a heap buffer overflow.

This fix replaces min_t(int, ...) with min_t(u32)

Fixes: 0626e664 ("cifsd: add server handler for central processing and tranport layers")
Signed-off-by: default avatarNicholas Carlini <nicholas@carlini.com>
Reviewed-by: default avatarStefan Metzmacher <metze@samba.org>
Acked-by: default avatarStefan Metzmacher <metze@samba.org>
Acked-by: default avatarNamjae Jeon <linkinjeon@kernel.org>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent c5794709
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -2540,9 +2540,9 @@ static int smb_direct_prepare(struct ksmbd_transport *t)
		goto put;

	req = (struct smbdirect_negotiate_req *)recvmsg->packet;
	sp->max_recv_size = min_t(int, sp->max_recv_size,
	sp->max_recv_size = min_t(u32, sp->max_recv_size,
				  le32_to_cpu(req->preferred_send_size));
	sp->max_send_size = min_t(int, sp->max_send_size,
	sp->max_send_size = min_t(u32, sp->max_send_size,
				  le32_to_cpu(req->max_receive_size));
	sp->max_fragmented_send_size =
		le32_to_cpu(req->max_fragmented_size);