Incorrect checks in MHI drivers may crash the system.
Fix these checks so that MHI drivers will handle the
errors gracefully.
Change-Id: I462263799c2e76573300ed43b51e39ecba42914b
Signed-off-by: Tony Truong <truong@codeaurora.org>
} else {
rmnet_log(MSG_CRITICAL,
"Invalid data in MHI callback, quitting\n");
+ return;
}
switch (cb_info->cb_reason) {
uintptr_t d_wp = 0, d_rp = 0, ring_size = 0;
int r;
- if (0 == ring->el_size || NULL == ring
+ if (NULL == ring || 0 == ring->el_size
|| NULL == ring->base || 0 == ring->len) {
mhi_log(MHI_MSG_ERROR, "Bad input parameters, quitting.\n");
return -EINVAL;
uintptr_t d_wp = 0, d_rp = 0, ring_size = 0;
int r;
- if (0 == ring->el_size || NULL == ring ||
+ if (NULL == ring || 0 == ring->el_size ||
NULL == ring->base || 0 == ring->len)
return -EINVAL;
uintptr_t ring_size = 0;
int r = 0;
- if (0 == ring->el_size || NULL == ring ||
+ if (NULL == ring || 0 == ring->el_size ||
NULL == ring->base || 0 == ring->len) {
mhi_log(MHI_MSG_ERROR, "Bad input parameters, quitting.\n");
return -EINVAL;
void mhi_link_state_cb(struct msm_pcie_notify *notify)
{
int ret_val = 0;
- struct mhi_pcie_dev_info *mhi_pcie_dev = notify->data;
+ struct mhi_pcie_dev_info *mhi_pcie_dev;
struct mhi_device_ctxt *mhi_dev_ctxt = NULL;
int r = 0;
"Incomplete handle received\n");
return;
}
+
+ mhi_pcie_dev = notify->data;
mhi_dev_ctxt = &mhi_pcie_dev->mhi_ctxt;
switch (notify->event) {
case MSM_PCIE_EVENT_LINKDOWN:
*offp = (u32)(*offp) % MHI_MAX_CHANNELS;
while (!valid_chan) {
- client_handle = mhi_dev_ctxt->client_handle_list[*offp];
if (*offp == (MHI_MAX_CHANNELS - 1))
msleep(1000);
if (!VALID_CHAN_NR(*offp) ||
!cc_list[*offp].mhi_trb_ring_base_addr ||
- !client_handle) {
+ !mhi_dev_ctxt->client_handle_list[*offp]) {
*offp += 1;
*offp = (u32)(*offp) % MHI_MAX_CHANNELS;
continue;
}
+ client_handle = mhi_dev_ctxt->client_handle_list[*offp];
valid_chan = 1;
}
struct file *file_handle)
{
struct uci_client *uci_handle = file_handle->private_data;
- struct mhi_uci_ctxt_t *uci_ctxt = uci_handle->uci_ctxt;
+ struct mhi_uci_ctxt_t *uci_ctxt;
u32 nr_in_bufs = 0;
int in_chan = 0;
int i = 0;
u32 buf_size = 0;
+
+ if (uci_handle == NULL)
+ return -EINVAL;
+
+ uci_ctxt = uci_handle->uci_ctxt;
in_chan = iminor(mhi_inode) + 1;
nr_in_bufs = uci_ctxt->chan_attrib[in_chan].nr_trbs;
buf_size = uci_ctxt->chan_attrib[in_chan].max_packet_size;
- if (uci_handle == NULL)
- return -EINVAL;
if (atomic_sub_return(1, &uci_handle->ref_count) == 0) {
uci_log(UCI_DBG_ERROR,
"Last client left, closing channel 0x%x\n",
u32 client_index;
struct mhi_result *result;
- if (!cb_info)
+ if (!cb_info || !cb_info->result) {
uci_log(UCI_DBG_CRITICAL, "Bad CB info from MHI.\n");
- if (cb_info->result) {
- chan_nr = (uintptr_t)cb_info->result->user_data;
- client_index = CHAN_TO_CLIENT(chan_nr);
- uci_handle =
- &uci_ctxt.client_handles[client_index];
+ return;
}
+
+ chan_nr = (uintptr_t)cb_info->result->user_data;
+ client_index = CHAN_TO_CLIENT(chan_nr);
+ uci_handle = &uci_ctxt.client_handles[client_index];
+
switch (cb_info->cb_reason) {
case MHI_CB_MHI_ENABLED:
atomic_set(&uci_handle->mhi_disabled, 0);