bus: mhi: misc: Add check for dev_rp if it is iommu range or not

er_ctxt->rp pointer is updated by MDM which is untrusted to HLOS,
it could be arbitrary value.

If there is security issue on MDM, and updated pointer which is not
align then driver will never come out of loop where checking against
dev_rp != rp.

So added check to make sure it is in the buffer range & aligned to 128bit.

Bug: 303101658
CRs-Fixed: 3545432
Change-Id: Ib484e07f2c75fcd657a4ccc648a3a20de3edeebc
Signed-off-by: Krishna chaitanya chundru <quic_krichai@quicinc.com>
Signed-off-by: Paras Sharma <quic_parass@quicinc.com>
Signed-off-by: Pindar Yang <pindaryang@google.com>
diff --git a/drivers/bus/mhi/core/mhi_internal.h b/drivers/bus/mhi/core/mhi_internal.h
index f078adc..001a944 100644
--- a/drivers/bus/mhi/core/mhi_internal.h
+++ b/drivers/bus/mhi/core/mhi_internal.h
@@ -808,6 +808,12 @@
 	pm_wakeup_hard_event(&mhi_cntrl->mhi_dev->dev);
 }
 
+static inline bool is_valid_ring_ptr(struct mhi_ring *ring, dma_addr_t addr)
+{
+	return ((addr >= ring->iommu_base &&
+		addr < ring->iommu_base + ring->len) && (addr % 16 == 0));
+}
+
 /* queue transfer buffer */
 int mhi_gen_tre(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan,
 		void *buf, void *cb, size_t buf_len, enum MHI_FLAGS flags);
diff --git a/drivers/bus/mhi/core/mhi_main.c b/drivers/bus/mhi/core/mhi_main.c
index de4cfdb..946b24e 100644
--- a/drivers/bus/mhi/core/mhi_main.c
+++ b/drivers/bus/mhi/core/mhi_main.c
@@ -1385,6 +1385,13 @@
 	int ret = 0;
 
 	spin_lock_bh(&mhi_event->lock);
+	if (!is_valid_ring_ptr(ev_ring, er_ctxt->rp)) {
+		MHI_ERR(
+			"Event ring rp points outside of the event ring or unalign rp %llx\n",
+			er_ctxt->rp);
+		spin_unlock_bh(&mhi_event->lock);
+		return 0;
+	}
 	dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp);
 	if (ev_ring->rp == dev_rp) {
 		spin_unlock_bh(&mhi_event->lock);
@@ -1477,8 +1484,15 @@
 	int result, ret = 0;
 
 	spin_lock_bh(&mhi_event->lock);
-	dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp);
+	if (!is_valid_ring_ptr(ev_ring, er_ctxt->rp)) {
+		MHI_ERR(
+			"Event ring rp points outside of the event ring or unalign rp %llx\n",
+			er_ctxt->rp);
+		spin_unlock_bh(&mhi_event->lock);
+		return 0;
+	}
 
+	dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp);
 	if (ev_ring->rp == dev_rp) {
 		spin_unlock_bh(&mhi_event->lock);
 		goto exit_bw_scale_process;