mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 18:09:56 +00:00
smb: client: let recv_done verify data_offset, data_length and remaining_data_length
This is inspired by the related server fixes.
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Fixes: f198186aa9 ("CIFS: SMBD: Establish SMB Direct connection")
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
committed by
Steve French
parent
f83ec76bf2
commit
f57e53ea25
@@ -453,9 +453,12 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
|||||||
struct smbdirect_recv_io *response =
|
struct smbdirect_recv_io *response =
|
||||||
container_of(wc->wr_cqe, struct smbdirect_recv_io, cqe);
|
container_of(wc->wr_cqe, struct smbdirect_recv_io, cqe);
|
||||||
struct smbdirect_socket *sc = response->socket;
|
struct smbdirect_socket *sc = response->socket;
|
||||||
|
struct smbdirect_socket_parameters *sp = &sc->parameters;
|
||||||
struct smbd_connection *info =
|
struct smbd_connection *info =
|
||||||
container_of(sc, struct smbd_connection, socket);
|
container_of(sc, struct smbd_connection, socket);
|
||||||
int data_length = 0;
|
u32 data_offset = 0;
|
||||||
|
u32 data_length = 0;
|
||||||
|
u32 remaining_data_length = 0;
|
||||||
|
|
||||||
log_rdma_recv(INFO, "response=0x%p type=%d wc status=%d wc opcode %d byte_len=%d pkey_index=%u\n",
|
log_rdma_recv(INFO, "response=0x%p type=%d wc status=%d wc opcode %d byte_len=%d pkey_index=%u\n",
|
||||||
response, sc->recv_io.expected, wc->status, wc->opcode,
|
response, sc->recv_io.expected, wc->status, wc->opcode,
|
||||||
@@ -487,7 +490,22 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
|||||||
/* SMBD data transfer packet */
|
/* SMBD data transfer packet */
|
||||||
case SMBDIRECT_EXPECT_DATA_TRANSFER:
|
case SMBDIRECT_EXPECT_DATA_TRANSFER:
|
||||||
data_transfer = smbdirect_recv_io_payload(response);
|
data_transfer = smbdirect_recv_io_payload(response);
|
||||||
|
|
||||||
|
if (wc->byte_len <
|
||||||
|
offsetof(struct smbdirect_data_transfer, padding))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
remaining_data_length = le32_to_cpu(data_transfer->remaining_data_length);
|
||||||
|
data_offset = le32_to_cpu(data_transfer->data_offset);
|
||||||
data_length = le32_to_cpu(data_transfer->data_length);
|
data_length = le32_to_cpu(data_transfer->data_length);
|
||||||
|
if (wc->byte_len < data_offset ||
|
||||||
|
(u64)wc->byte_len < (u64)data_offset + data_length)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (remaining_data_length > sp->max_fragmented_recv_size ||
|
||||||
|
data_length > sp->max_fragmented_recv_size ||
|
||||||
|
(u64)remaining_data_length + (u64)data_length > (u64)sp->max_fragmented_recv_size)
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (data_length) {
|
if (data_length) {
|
||||||
if (sc->recv_io.reassembly.full_packet_received)
|
if (sc->recv_io.reassembly.full_packet_received)
|
||||||
|
|||||||
Reference in New Issue
Block a user