diag: Validate memory device client's process descriptor

This fix checks for valid process descriptor of a
memory device client before exporting information
from diag driver to memory device client's read buffer
for reliable data transfer.

CRs-Fixed: 2016396
Change-Id: I45aeb8fc9e2f6a678d48bbfcbb77c501adbbfce0
Signed-off-by: Gopikrishna Mogasati <gmogas@codeaurora.org>
This commit is contained in:
Gopikrishna Mogasati 2017-05-02 02:53:54 +05:30
parent 5d78c03af8
commit b18e24a6f4

View file

@ -252,6 +252,7 @@ int diag_md_copy_to_user(char __user *buf, int *pret, size_t buf_size,
uint8_t drain_again = 0;
uint8_t peripheral = 0;
struct diag_md_session_t *session_info = NULL;
struct pid *pid_struct = NULL;
mutex_lock(&driver->diagfwd_untag_mutex);
@ -278,6 +279,14 @@ int diag_md_copy_to_user(char __user *buf, int *pret, size_t buf_size,
if ((info && (info->peripheral_mask &
MD_PERIPHERAL_MASK(peripheral)) == 0))
goto drop_data;
pid_struct = find_get_pid(session_info->pid);
if (!pid_struct) {
err = -ESRCH;
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
"diag: No such md_session_map[%d] with pid = %d err=%d exists..\n",
peripheral, session_info->pid, err);
goto drop_data;
}
/*
* If the data is from remote processor, copy the remote
* token first
@ -297,27 +306,35 @@ int diag_md_copy_to_user(char __user *buf, int *pret, size_t buf_size,
}
if (i > 0) {
remote_token = diag_get_remote(i);
err = copy_to_user(buf + ret, &remote_token,
if (get_pid_task(pid_struct, PIDTYPE_PID)) {
err = copy_to_user(buf + ret,
&remote_token,
sizeof(int));
if (err)
goto drop_data;
ret += sizeof(int);
}
}
/* Copy the length of data being passed */
if (get_pid_task(pid_struct, PIDTYPE_PID)) {
err = copy_to_user(buf + ret,
(void *)&(entry->len),
sizeof(int));
if (err)
goto drop_data;
ret += sizeof(int);
}
/* Copy the length of data being passed */
err = copy_to_user(buf + ret, (void *)&(entry->len),
sizeof(int));
if (err)
goto drop_data;
ret += sizeof(int);
/* Copy the actual data being passed */
err = copy_to_user(buf + ret, (void *)entry->buf,
if (get_pid_task(pid_struct, PIDTYPE_PID)) {
err = copy_to_user(buf + ret,
(void *)entry->buf,
entry->len);
if (err)
goto drop_data;
ret += entry->len;
}
/*
* The data is now copied to the user space client,
* Notify that the write is complete and delete its
@ -339,7 +356,15 @@ drop_data:
}
*pret = ret;
err = copy_to_user(buf + sizeof(int), (void *)&num_data, sizeof(int));
if (pid_struct && get_pid_task(pid_struct, PIDTYPE_PID)) {
err = copy_to_user(buf + sizeof(int),
(void *)&num_data,
sizeof(int));
} else {
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
"diag: md_session_map[%d] with pid = %d Exited..\n",
peripheral, driver->md_session_map[peripheral]->pid);
}
diag_ws_on_copy_complete(DIAG_WS_MUX);
if (drain_again)
chk_logging_wakeup();