OSDN Git Service

diag: dci: Validate dci client entries prior read
authorManoj Prabhu B <bmanoj@codeaurora.org>
Thu, 13 Dec 2018 09:14:16 +0000 (14:44 +0530)
committerManoj Prabhu B <bmanoj@codeaurora.org>
Fri, 22 Feb 2019 07:16:57 +0000 (12:46 +0530)
Validate the dci entries and its task structure before
accessing structure members to prevent copying dci data to
invalid entries.

Change-Id: I07c59ef0705bc52a8268b0dc984ebfa9d26d178e
Signed-off-by: Manoj Prabhu B <bmanoj@codeaurora.org>
drivers/char/diag/diag_dci.c
drivers/char/diag/diagchar_core.c

index b0b36d0..0858b85 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -2296,8 +2296,8 @@ struct diag_dci_client_tbl *dci_lookup_client_entry_pid(int tgid)
                pid_struct = find_get_pid(entry->tgid);
                if (!pid_struct) {
                        DIAG_LOG(DIAG_DEBUG_DCI,
-                               "diag: valid pid doesn't exist for pid = %d\n",
-                               entry->tgid);
+                       "diag: Exited pid (%d) doesn't match dci client of pid (%d)\n",
+                       tgid, entry->tgid);
                        continue;
                }
                task_s = get_pid_task(pid_struct, PIDTYPE_PID);
index d6c92d6..ae1d669 100644 (file)
@@ -583,8 +583,8 @@ static int diag_remove_client_entry(struct file *file)
 static int diagchar_close(struct inode *inode, struct file *file)
 {
        int ret;
-       DIAG_LOG(DIAG_DEBUG_USERSPACE, "diag: process exit %s\n",
-               current->comm);
+       DIAG_LOG(DIAG_DEBUG_USERSPACE, "diag: %s process exit with pid = %d\n",
+               current->comm, current->tgid);
        ret = diag_remove_client_entry(file);
        mutex_lock(&driver->diag_maskclear_mutex);
        driver->mask_clear = 0;
@@ -3124,6 +3124,8 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
        int exit_stat = 0;
        int write_len = 0;
        struct diag_md_session_t *session_info = NULL;
+       struct pid *pid_struct = NULL;
+       struct task_struct *task_s = NULL;
 
        mutex_lock(&driver->diagchar_mutex);
        for (i = 0; i < driver->num_clients; i++)
@@ -3331,8 +3333,19 @@ exit:
                list_for_each_safe(start, temp, &driver->dci_client_list) {
                        entry = list_entry(start, struct diag_dci_client_tbl,
                                                                        track);
-                       if (entry->client->tgid != current->tgid)
+                       pid_struct = find_get_pid(entry->tgid);
+                       if (!pid_struct)
                                continue;
+                       task_s = get_pid_task(pid_struct, PIDTYPE_PID);
+                       if (!task_s) {
+                               DIAG_LOG(DIAG_DEBUG_DCI,
+                               "diag: valid task doesn't exist for pid = %d\n",
+                               entry->tgid);
+                               continue;
+                       }
+                       if (task_s == entry->client)
+                               if (entry->client->tgid != current->tgid)
+                                       continue;
                        if (!entry->in_service)
                                continue;
                        if (copy_to_user(buf + ret, &data_type, sizeof(int))) {