Commit d5ff8b7b authored by Qiang Yu's avatar Qiang Yu Committed by Guan Jing
Browse files

bus: mhi: host: Drop chan lock before queuing buffers

stable inclusion
from stable-v5.10.209
commit 20a6dea2d1c68d4e03c6bb50bc12e72e226b5c0e
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I97NHA
CVE: CVE-2023-52493

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=20a6dea2d1c68d4e03c6bb50bc12e72e226b5c0e



--------------------------------

Ensure read and write locks for the channel are not taken in succession by
dropping the read lock from parse_xfer_event() such that a callback given
to client can potentially queue buffers and acquire the write lock in that
process. Any queueing of buffers should be done without channel read lock
acquired as it can result in multiple locks and a soft lockup.

Cc: <stable@vger.kernel.org> # 5.7
Fixes: 1d3173a3 ("bus: mhi: core: Add support for processing events from client device")
Signed-off-by: default avatarQiang Yu <quic_qianyu@quicinc.com>
Reviewed-by: default avatarJeffrey Hugo <quic_jhugo@quicinc.com>
Tested-by: default avatarJeffrey Hugo <quic_jhugo@quicinc.com>
Reviewed-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Link: https://lore.kernel.org/r/1702276972-41296-3-git-send-email-quic_qianyu@quicinc.com


[mani: added fixes tag and cc'ed stable]
Signed-off-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarGuan Jing <guanjing6@huawei.com>
parent b670dd90
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -570,6 +570,8 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl,
			mhi_del_ring_element(mhi_cntrl, tre_ring);
			local_rp = tre_ring->rp;

			read_unlock_bh(&mhi_chan->lock);

			/* notify client */
			mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result);

@@ -592,6 +594,8 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl,
					kfree(buf_info->cb_buf);
				}
			}

			read_lock_bh(&mhi_chan->lock);
		}
		break;
	} /* CC_EOT */