Unverified Commit 8bb5e053 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!15075 v4 Fix CVE-2023-52572 in openEuler-1.0-LTS

Merge Pull Request from: @ci-robot 
 
PR sync from: Wang Zhaolong <wangzhaolong1@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/NGMOIYRJQUXE5YV65NUCN4DB7Y5NMLMM/ 
V1 -> V2:
In the compound_send_recv(), correct the credits[i] update condition
MID_RESPONSE_RECEIVED to MID_RESPONSE_READY.

V2 -> V3:
Correct conflicts and Signed-off-by information.

V3 -> V4
Correct conflicts information.

Zhang Xiaoxu (1):
  cifs: Fix UAF in cifs_demultiplex_thread()


-- 
2.34.3
 
https://gitee.com/src-openeuler/kernel/issues/I95AUA 
 
Link:https://gitee.com/openeuler/kernel/pulls/15075

 

Reviewed-by: default avatarYuan Can <yuancan@huawei.com>
Signed-off-by: default avatarYuan Can <yuancan@huawei.com>
parents 510cec00 ab99c6eb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1597,6 +1597,7 @@ static inline bool is_retryable_error(int error)
#define   MID_RETRY_NEEDED      8 /* session closed while this request out */
#define   MID_RESPONSE_MALFORMED 0x10
#define   MID_SHUTDOWN		 0x20
#define   MID_RESPONSE_READY 0x40 /* ready for other process handle the rsp */

/* Flags */
#define   MID_WAIT_CANCELLED	 1 /* Cancelled while waiting for response */
+2 −1
Original line number Diff line number Diff line
@@ -1080,7 +1080,8 @@ cifs_demultiplex_thread(void *p)
			if (mids[i] != NULL) {
				mids[i]->resp_buf_size = server->pdu_size;
				if ((mids[i]->mid_flags & MID_WAIT_CANCELLED) &&
				    mids[i]->mid_state == MID_RESPONSE_RECEIVED &&
				    (mids[i]->mid_state == MID_RESPONSE_RECEIVED ||
				     mids[i]->mid_state == MID_RESPONSE_READY) &&
				    server->ops->handle_cancelled_mid)
					server->ops->handle_cancelled_mid(
							mids[i]->resp_buf,
+21 −11
Original line number Diff line number Diff line
@@ -46,6 +46,8 @@
void
cifs_wake_up_task(struct mid_q_entry *mid)
{
	if (mid->mid_state == MID_RESPONSE_RECEIVED)
		mid->mid_state = MID_RESPONSE_READY;
	wake_up_process(mid->callback_data);
}

@@ -561,7 +563,8 @@ wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
	int error;

	error = wait_event_freezekillable_unsafe(server->response_q,
				    midQ->mid_state != MID_REQUEST_SUBMITTED);
				    midQ->mid_state != MID_REQUEST_SUBMITTED &&
				    midQ->mid_state != MID_RESPONSE_RECEIVED);
	if (error < 0)
		return -ERESTARTSYS;

@@ -699,7 +702,7 @@ cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)

	spin_lock(&GlobalMid_Lock);
	switch (mid->mid_state) {
	case MID_RESPONSE_RECEIVED:
	case MID_RESPONSE_READY:
		spin_unlock(&GlobalMid_Lock);
		return rc;
	case MID_RETRY_NEEDED:
@@ -790,6 +793,8 @@ cifs_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
static void
cifs_noop_callback(struct mid_q_entry *mid)
{
	if (mid->mid_state == MID_RESPONSE_RECEIVED)
		mid->mid_state = MID_RESPONSE_READY;
}

int
@@ -912,7 +917,8 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
				 midQ[i]->mid);
			send_cancel(ses->server, &rqst[i], midQ[i]);
			spin_lock(&GlobalMid_Lock);
			if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED) {
			if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED ||
			    midQ[i]->mid_state == MID_RESPONSE_RECEIVED) {
				midQ[i]->mid_flags |= MID_WAIT_CANCELLED;
				midQ[i]->callback = DeleteMidQEntry;
				cancelled_mid[i] = true;
@@ -923,7 +929,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,

	for (i = 0; i < num_rqst; i++)
		if (!cancelled_mid[i] && midQ[i]->resp_buf
		    && (midQ[i]->mid_state == MID_RESPONSE_RECEIVED))
		    && (midQ[i]->mid_state == MID_RESPONSE_READY))
			credits[i] = ses->server->ops->get_credits(midQ[i]);

	for (i = 0; i < num_rqst; i++) {
@@ -938,7 +944,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
		}

		if (!midQ[i]->resp_buf ||
		    midQ[i]->mid_state != MID_RESPONSE_RECEIVED) {
		    midQ[i]->mid_state != MID_RESPONSE_READY) {
			rc = -EIO;
			cifs_dbg(FYI, "Bad MID state?\n");
			goto out;
@@ -1118,7 +1124,8 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
	if (rc != 0) {
		send_cancel(ses->server, &rqst, midQ);
		spin_lock(&GlobalMid_Lock);
		if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
		if (midQ->mid_state == MID_REQUEST_SUBMITTED ||
		    midQ->mid_state == MID_RESPONSE_RECEIVED) {
			/* no longer considered to be "in-flight" */
			midQ->callback = DeleteMidQEntry;
			spin_unlock(&GlobalMid_Lock);
@@ -1135,7 +1142,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
	}

	if (!midQ->resp_buf || !out_buf ||
	    midQ->mid_state != MID_RESPONSE_RECEIVED) {
	    midQ->mid_state != MID_RESPONSE_READY) {
		rc = -EIO;
		cifs_dbg(VFS, "Bad MID state?\n");
		goto out;
@@ -1254,13 +1261,15 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,

	/* Wait for a reply - allow signals to interrupt. */
	rc = wait_event_interruptible(ses->server->response_q,
		(!(midQ->mid_state == MID_REQUEST_SUBMITTED)) ||
		(!(midQ->mid_state == MID_REQUEST_SUBMITTED ||
		   midQ->mid_state == MID_RESPONSE_RECEIVED)) ||
		((ses->server->tcpStatus != CifsGood) &&
		 (ses->server->tcpStatus != CifsNew)));

	/* Were we interrupted by a signal ? */
	if ((rc == -ERESTARTSYS) &&
		(midQ->mid_state == MID_REQUEST_SUBMITTED) &&
		(midQ->mid_state == MID_REQUEST_SUBMITTED ||
		 midQ->mid_state == MID_RESPONSE_RECEIVED) &&
		((ses->server->tcpStatus == CifsGood) ||
		 (ses->server->tcpStatus == CifsNew))) {

@@ -1290,7 +1299,8 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
		if (rc) {
			send_cancel(ses->server, &rqst, midQ);
			spin_lock(&GlobalMid_Lock);
			if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
			if (midQ->mid_state == MID_REQUEST_SUBMITTED ||
			    midQ->mid_state == MID_RESPONSE_RECEIVED) {
				/* no longer considered to be "in-flight" */
				midQ->callback = DeleteMidQEntry;
				spin_unlock(&GlobalMid_Lock);
@@ -1308,7 +1318,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
		return rc;

	/* rcvd frame is ok */
	if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_RECEIVED) {
	if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_READY) {
		rc = -EIO;
		cifs_dbg(VFS, "Bad MID state?\n");
		goto out;