OSDN Git Service

diag: Validate memory device client's process descriptor
authorGopikrishna Mogasati <gmogas@codeaurora.org>
Mon, 1 May 2017 21:23:54 +0000 (02:53 +0530)
committerGopikrishna Mogasati <gmogas@codeaurora.org>
Thu, 4 May 2017 15:16:47 +0000 (20:46 +0530)
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>
drivers/char/diag/diag_memorydevice.c

index bd34e6c..a5d92c5 100644 (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,
-                                                  sizeof(int));
+                               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,
-                                          entry->len);
-                       if (err)
-                               goto drop_data;
-                       ret += entry->len;
-
+                       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();