| From 2675990b4bea3d985bd09d02d9e3a0f2d17fab21 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 24 Mar 2023 10:13:04 -0600 |
| Subject: bus: mhi: host: Range check CHDBOFF and ERDBOFF |
| |
| From: Jeffrey Hugo <quic_jhugo@quicinc.com> |
| |
| [ Upstream commit 6a0c637bfee69a74c104468544d9f2a6579626d0 ] |
| |
| If the value read from the CHDBOFF and ERDBOFF registers is outside the |
| range of the MHI register space then an invalid address might be computed |
| which later causes a kernel panic. Range check the read value to prevent |
| a crash due to bad data from the device. |
| |
| Fixes: 6cd330ae76ff ("bus: mhi: core: Add support for ringing channel/event ring doorbells") |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com> |
| Reviewed-by: Pranjal Ramajor Asha Kanojiya <quic_pkanojiy@quicinc.com> |
| Reviewed-by: Manivannan Sadhasivam <mani@kernel.org> |
| Link: https://lore.kernel.org/r/1679674384-27209-1-git-send-email-quic_jhugo@quicinc.com |
| Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/bus/mhi/host/init.c | 12 ++++++++++++ |
| 1 file changed, 12 insertions(+) |
| |
| diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c |
| index 0d0386f67ffe2..2cc48f96afdbc 100644 |
| --- a/drivers/bus/mhi/host/init.c |
| +++ b/drivers/bus/mhi/host/init.c |
| @@ -498,6 +498,12 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl) |
| return -EIO; |
| } |
| |
| + if (val >= mhi_cntrl->reg_len - (8 * MHI_DEV_WAKE_DB)) { |
| + dev_err(dev, "CHDB offset: 0x%x is out of range: 0x%zx\n", |
| + val, mhi_cntrl->reg_len - (8 * MHI_DEV_WAKE_DB)); |
| + return -ERANGE; |
| + } |
| + |
| /* Setup wake db */ |
| mhi_cntrl->wake_db = base + val + (8 * MHI_DEV_WAKE_DB); |
| mhi_write_reg(mhi_cntrl, mhi_cntrl->wake_db, 4, 0); |
| @@ -517,6 +523,12 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl) |
| return -EIO; |
| } |
| |
| + if (val >= mhi_cntrl->reg_len - (8 * mhi_cntrl->total_ev_rings)) { |
| + dev_err(dev, "ERDB offset: 0x%x is out of range: 0x%zx\n", |
| + val, mhi_cntrl->reg_len - (8 * mhi_cntrl->total_ev_rings)); |
| + return -ERANGE; |
| + } |
| + |
| /* Setup event db address for each ev_ring */ |
| mhi_event = mhi_cntrl->mhi_event; |
| for (i = 0; i < mhi_cntrl->total_ev_rings; i++, val += 8, mhi_event++) { |
| -- |
| 2.40.1 |
| |