mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
smb: server: let recv_done() avoid touching data_transfer after cleanup/move
[ Upstream commit a6c015b7ac2d8c5233337e5793f50d04fac17669 ]
Calling enqueue_reassembly() and wake_up_interruptible(&t->wait_reassembly_queue)
or put_receive_buffer() means the recvmsg/data_transfer pointer might
get re-used by another thread, which means these should be
the last operations before calling return.
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Fixes: 0626e6641f ("cifsd: add server handler for central processing and tranport layers")
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
66110b35be
commit
c29dbc44fb
@@ -580,16 +580,11 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
||||
else
|
||||
t->full_packet_received = true;
|
||||
|
||||
enqueue_reassembly(t, recvmsg, (int)data_length);
|
||||
wake_up_interruptible(&t->wait_reassembly_queue);
|
||||
|
||||
spin_lock(&t->receive_credit_lock);
|
||||
receive_credits = --(t->recv_credits);
|
||||
avail_recvmsg_count = t->count_avail_recvmsg;
|
||||
spin_unlock(&t->receive_credit_lock);
|
||||
} else {
|
||||
put_recvmsg(t, recvmsg);
|
||||
|
||||
spin_lock(&t->receive_credit_lock);
|
||||
receive_credits = --(t->recv_credits);
|
||||
avail_recvmsg_count = ++(t->count_avail_recvmsg);
|
||||
@@ -611,6 +606,13 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
||||
if (is_receive_credit_post_required(receive_credits, avail_recvmsg_count))
|
||||
mod_delayed_work(smb_direct_wq,
|
||||
&t->post_recv_credits_work, 0);
|
||||
|
||||
if (data_length) {
|
||||
enqueue_reassembly(t, recvmsg, (int)data_length);
|
||||
wake_up_interruptible(&t->wait_reassembly_queue);
|
||||
} else
|
||||
put_recvmsg(t, recvmsg);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user