Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ffc61ccb authored by Sachin Prabhu's avatar Sachin Prabhu Committed by Steve French
Browse files

Initialise mid_q_entry before putting it on the pending queue



A user reported a crash in cifs_demultiplex_thread() caused by an
incorrectly set mid_q_entry->callback() function. It appears that the
callback assignment made in cifs_call_async() was not flushed back to
memory suggesting that a memory barrier was required here. Changing the
code to make sure that the mid_q_entry structure was completely
initialised before it was added to the pending queue fixes the problem.

Signed-off-by: default avatarSachin Prabhu <sprabhu@redhat.com>
Reviewed-by: default avatarJeff Layton <jlayton@redhat.com>
Reviewed-by: default avatarShirish Pargaonkar <shirishpargaonkar@gmail.com>
Signed-off-by: default avatarSteve French <smfrench@gmail.com>
parent 055c9fa8
Loading
Loading
Loading
Loading
+14 −12
Original line number Diff line number Diff line
@@ -365,18 +365,16 @@ cifs_setup_async_request(struct TCP_Server_Info *server, struct kvec *iov,
	if (mid == NULL)
		return -ENOMEM;

	/* put it on the pending_mid_q */
	spin_lock(&GlobalMid_Lock);
	list_add_tail(&mid->qhead, &server->pending_mid_q);
	spin_unlock(&GlobalMid_Lock);

	rc = cifs_sign_smb2(iov, nvec, server, &mid->sequence_number);
	if (rc)
		delete_mid(mid);
	*ret_mid = mid;
	if (rc) {
		DeleteMidQEntry(mid);
		return rc;
	}

	*ret_mid = mid;
	return 0;
}

/*
 * Send a SMB request and set the callback function in the mid to handle
 * the result. Caller is responsible for dealing with timeouts.
@@ -407,17 +405,21 @@ cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov,
	mid->callback_data = cbdata;
	mid->mid_state = MID_REQUEST_SUBMITTED;

	/* put it on the pending_mid_q */
	spin_lock(&GlobalMid_Lock);
	list_add_tail(&mid->qhead, &server->pending_mid_q);
	spin_unlock(&GlobalMid_Lock);


	cifs_in_send_inc(server);
	rc = smb_sendv(server, iov, nvec);
	cifs_in_send_dec(server);
	cifs_save_when_sent(mid);
	mutex_unlock(&server->srv_mutex);

	if (rc)
		goto out_err;
	if (rc == 0)
		return 0;

	return rc;
out_err:
	delete_mid(mid);
	add_credits(server, 1);
	wake_up(&server->request_q);