mirror of
https://github.com/torvalds/linux.git
synced 2026-06-04 20:46:48 +02:00
smb: client: let recv_done() avoid touching data_transfer after cleanup/move
Calling enqueue_reassembly() and wake_up_interruptible(&info->wait_reassembly_queue)
or put_receive_buffer() means the response/data_transfer pointer might
get re-used by another thread, which means these should be
the last operations before calling return.
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.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:
parent
bdd7afc6dc
commit
24eff17887
|
|
@ -479,10 +479,6 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
|||
data_transfer = smbd_response_payload(response);
|
||||
data_length = le32_to_cpu(data_transfer->data_length);
|
||||
|
||||
/*
|
||||
* If this is a packet with data playload place the data in
|
||||
* reassembly queue and wake up the reading thread
|
||||
*/
|
||||
if (data_length) {
|
||||
if (info->full_packet_received)
|
||||
response->first_segment = true;
|
||||
|
|
@ -491,16 +487,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
|||
info->full_packet_received = false;
|
||||
else
|
||||
info->full_packet_received = true;
|
||||
|
||||
enqueue_reassembly(
|
||||
info,
|
||||
response,
|
||||
data_length);
|
||||
} else
|
||||
put_receive_buffer(info, response);
|
||||
|
||||
if (data_length)
|
||||
wake_up_interruptible(&info->wait_reassembly_queue);
|
||||
}
|
||||
|
||||
atomic_dec(&info->receive_credits);
|
||||
info->receive_credit_target =
|
||||
|
|
@ -528,6 +515,16 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
|||
info->keep_alive_requested = KEEP_ALIVE_PENDING;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is a packet with data playload place the data in
|
||||
* reassembly queue and wake up the reading thread
|
||||
*/
|
||||
if (data_length) {
|
||||
enqueue_reassembly(info, response, data_length);
|
||||
wake_up_interruptible(&info->wait_reassembly_queue);
|
||||
} else
|
||||
put_receive_buffer(info, response);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user