diag: Fix for possible dci stale entries

This patch provides the protection to dci client
entries from corruption.

CRs-Fixed: 984942 992683
Change-Id: Ifcd9f14dc03d9e42a31b3e126839489881e98303
Signed-off-by: Manoj Prabhu B <bmanoj@codeaurora.org>
This commit is contained in:
Manoj Prabhu B 2016-05-18 16:48:36 +05:30 committed by Kyle Yan
parent e46c4c92c5
commit af4cf780a2
2 changed files with 40 additions and 10 deletions

View file

@ -1392,6 +1392,7 @@ void diag_dci_channel_open_work(struct work_struct *work)
* which log entries in the cumulative logs that need
* to be updated on the peripheral.
*/
mutex_lock(&driver->dci_mutex);
list_for_each_safe(start, temp, &driver->dci_client_list) {
entry = list_entry(start, struct diag_dci_client_tbl, track);
if (entry->client_info.token != DCI_LOCAL_PROC)
@ -1403,6 +1404,7 @@ void diag_dci_channel_open_work(struct work_struct *work)
client_log_mask_ptr += 514;
}
}
mutex_unlock(&driver->dci_mutex);
mutex_lock(&dci_log_mask_mutex);
/* Update the appropriate dirty bits in the cumulative mask */
@ -2888,8 +2890,6 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry)
if (!entry)
return DIAG_DCI_NOT_SUPPORTED;
mutex_lock(&driver->dci_mutex);
token = entry->client_info.token;
/*
* Remove the entry from the list before freeing the buffers
@ -3000,8 +3000,6 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry)
}
queue_work(driver->diag_real_time_wq, &driver->diag_real_time_work);
mutex_unlock(&driver->dci_mutex);
return DIAG_DCI_NO_ERROR;
}

View file

@ -421,9 +421,11 @@ static int diag_remove_client_entry(struct file *file)
* This will specially help in case of ungraceful exit of any DCI client
* This call will remove any pending registrations of such client
*/
mutex_lock(&driver->dci_mutex);
dci_entry = dci_lookup_client_entry_pid(current->tgid);
if (dci_entry)
diag_dci_deinit_client(dci_entry);
mutex_unlock(&driver->dci_mutex);
diag_close_logging_process(current->tgid);
@ -1982,32 +1984,46 @@ long diagchar_compat_ioctl(struct file *filp,
mutex_unlock(&driver->dci_mutex);
return DIAG_DCI_NOT_SUPPORTED;
}
mutex_unlock(&driver->dci_mutex);
result = diag_dci_deinit_client(dci_client);
mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_SUPPORT:
result = diag_ioctl_dci_support(ioarg);
break;
case DIAG_IOCTL_DCI_HEALTH_STATS:
mutex_lock(&driver->dci_mutex);
result = diag_ioctl_dci_health_stats(ioarg);
mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_LOG_STATUS:
mutex_lock(&driver->dci_mutex);
result = diag_ioctl_dci_log_status(ioarg);
mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_EVENT_STATUS:
mutex_lock(&driver->dci_mutex);
result = diag_ioctl_dci_event_status(ioarg);
mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_CLEAR_LOGS:
mutex_lock(&driver->dci_mutex);
if (copy_from_user((void *)&client_id, (void __user *)ioarg,
sizeof(int)))
sizeof(int))) {
mutex_unlock(&driver->dci_mutex);
return -EFAULT;
}
result = diag_dci_clear_log_mask(client_id);
mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_CLEAR_EVENTS:
mutex_lock(&driver->dci_mutex);
if (copy_from_user(&client_id, (void __user *)ioarg,
sizeof(int)))
sizeof(int))) {
mutex_unlock(&driver->dci_mutex);
return -EFAULT;
}
result = diag_dci_clear_event_mask(client_id);
mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_LSM_DEINIT:
result = diag_ioctl_lsm_deinit();
@ -2029,7 +2045,9 @@ long diagchar_compat_ioctl(struct file *filp,
result = 1;
break;
case DIAG_IOCTL_VOTE_REAL_TIME:
mutex_lock(&driver->dci_mutex);
result = diag_ioctl_vote_real_time(ioarg);
mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_GET_REAL_TIME:
result = diag_ioctl_get_real_time(ioarg);
@ -2091,32 +2109,44 @@ long diagchar_ioctl(struct file *filp,
mutex_unlock(&driver->dci_mutex);
return DIAG_DCI_NOT_SUPPORTED;
}
mutex_unlock(&driver->dci_mutex);
result = diag_dci_deinit_client(dci_client);
mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_SUPPORT:
result = diag_ioctl_dci_support(ioarg);
break;
case DIAG_IOCTL_DCI_HEALTH_STATS:
mutex_lock(&driver->dci_mutex);
result = diag_ioctl_dci_health_stats(ioarg);
mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_LOG_STATUS:
mutex_lock(&driver->dci_mutex);
result = diag_ioctl_dci_log_status(ioarg);
mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_EVENT_STATUS:
result = diag_ioctl_dci_event_status(ioarg);
break;
case DIAG_IOCTL_DCI_CLEAR_LOGS:
mutex_lock(&driver->dci_mutex);
if (copy_from_user((void *)&client_id, (void __user *)ioarg,
sizeof(int)))
sizeof(int))) {
mutex_unlock(&driver->dci_mutex);
return -EFAULT;
}
result = diag_dci_clear_log_mask(client_id);
mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_CLEAR_EVENTS:
mutex_lock(&driver->dci_mutex);
if (copy_from_user(&client_id, (void __user *)ioarg,
sizeof(int)))
sizeof(int))) {
mutex_unlock(&driver->dci_mutex);
return -EFAULT;
}
result = diag_dci_clear_event_mask(client_id);
mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_LSM_DEINIT:
result = diag_ioctl_lsm_deinit();
@ -2138,7 +2168,9 @@ long diagchar_ioctl(struct file *filp,
result = 1;
break;
case DIAG_IOCTL_VOTE_REAL_TIME:
mutex_lock(&driver->dci_mutex);
result = diag_ioctl_vote_real_time(ioarg);
mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_GET_REAL_TIME:
result = diag_ioctl_get_real_time(ioarg);