Skip to content

Commit 581fb78

Browse files
metze-sambagregkh
authored andcommitted
smb: client: let recv_done verify data_offset, data_length and remaining_data_length
[ Upstream commit f57e53e ] This is inspired by the related server fixes. Cc: Tom Talpey <[email protected]> Cc: Long Li <[email protected]> Cc: [email protected] Cc: [email protected] Reviewed-by: Namjae Jeon <[email protected]> Fixes: f198186 ("CIFS: SMBD: Establish SMB Direct connection") Signed-off-by: Stefan Metzmacher <[email protected]> Signed-off-by: Steve French <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent cbda551 commit 581fb78

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

fs/smb/client/smbdirect.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,9 +446,12 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
446446
struct smbdirect_recv_io *response =
447447
container_of(wc->wr_cqe, struct smbdirect_recv_io, cqe);
448448
struct smbdirect_socket *sc = response->socket;
449+
struct smbdirect_socket_parameters *sp = &sc->parameters;
449450
struct smbd_connection *info =
450451
container_of(sc, struct smbd_connection, socket);
451-
int data_length = 0;
452+
u32 data_offset = 0;
453+
u32 data_length = 0;
454+
u32 remaining_data_length = 0;
452455

453456
log_rdma_recv(INFO, "response=0x%p type=%d wc status=%d wc opcode %d byte_len=%d pkey_index=%u\n",
454457
response, sc->recv_io.expected, wc->status, wc->opcode,
@@ -480,7 +483,22 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
480483
/* SMBD data transfer packet */
481484
case SMBDIRECT_EXPECT_DATA_TRANSFER:
482485
data_transfer = smbdirect_recv_io_payload(response);
486+
487+
if (wc->byte_len <
488+
offsetof(struct smbdirect_data_transfer, padding))
489+
goto error;
490+
491+
remaining_data_length = le32_to_cpu(data_transfer->remaining_data_length);
492+
data_offset = le32_to_cpu(data_transfer->data_offset);
483493
data_length = le32_to_cpu(data_transfer->data_length);
494+
if (wc->byte_len < data_offset ||
495+
(u64)wc->byte_len < (u64)data_offset + data_length)
496+
goto error;
497+
498+
if (remaining_data_length > sp->max_fragmented_recv_size ||
499+
data_length > sp->max_fragmented_recv_size ||
500+
(u64)remaining_data_length + (u64)data_length > (u64)sp->max_fragmented_recv_size)
501+
goto error;
484502

485503
if (data_length) {
486504
if (info->full_packet_received)

0 commit comments

Comments
 (0)