OSDN Git Service

diag: dci: Prevent task deallocation and possible resource leak
authorManoj Prabhu B <bmanoj@codeaurora.org>
Tue, 12 Mar 2019 07:23:24 +0000 (12:53 +0530)
committerManoj Prabhu B <bmanoj@codeaurora.org>
Wed, 13 Mar 2019 05:27:09 +0000 (10:57 +0530)
Prevent DCI clients' task structs from being deallocated to provide
diag driver a chance to clean up its dci client list. Also update
dci client list pid reference count properly to prevent any resource
leakage.

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

index 4051521..f2eb9b2 100644 (file)
@@ -1537,6 +1537,7 @@ void diag_dci_notify_client(int peripheral_mask, int data, int proc)
                                        DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
                                                "diag: dci client with pid = %d Exited..\n",
                                                entry->tgid);
+                                       put_pid(pid_struct);
                                        mutex_unlock(&driver->dci_mutex);
                                        return;
                                }
@@ -1551,9 +1552,12 @@ void diag_dci_notify_client(int peripheral_mask, int data, int proc)
                                        if (stat)
                                                pr_err("diag: Err sending dci signal to client, signal data: 0x%x, stat: %d\n",
                                                        info.si_int, stat);
-                               } else
+                               } else {
                                        pr_err("diag: client data is corrupted, signal data: 0x%x, stat: %d\n",
                                                info.si_int, stat);
+                               }
+                               put_task_struct(dci_task);
+                               put_pid(pid_struct);
                        }
                }
        }
@@ -2305,11 +2309,18 @@ struct diag_dci_client_tbl *dci_lookup_client_entry_pid(int tgid)
                        DIAG_LOG(DIAG_DEBUG_DCI,
                                "diag: valid task doesn't exist for pid = %d\n",
                                entry->tgid);
+                       put_pid(pid_struct);
                        continue;
                }
-               if (task_s == entry->client)
-                       if (entry->client->tgid == tgid)
+               if (task_s == entry->client) {
+                       if (entry->client->tgid == tgid) {
+                               put_task_struct(task_s);
+                               put_pid(pid_struct);
                                return entry;
+                       }
+               }
+               put_task_struct(task_s);
+               put_pid(pid_struct);
        }
        return NULL;
 }
@@ -2939,6 +2950,7 @@ int diag_dci_register_client(struct diag_dci_reg_tbl_t *reg_entry)
 
        mutex_lock(&driver->dci_mutex);
 
+       get_task_struct(current);
        new_entry->client = current;
        new_entry->tgid = current->tgid;
        new_entry->client_info.notification_list =
index 5deeac9..520f553 100644 (file)
@@ -3342,20 +3342,32 @@ exit:
                                DIAG_LOG(DIAG_DEBUG_DCI,
                                "diag: valid task doesn't exist for pid = %d\n",
                                entry->tgid);
+                               put_pid(pid_struct);
                                continue;
                        }
-                       if (task_s == entry->client)
-                               if (entry->client->tgid != current->tgid)
+                       if (task_s == entry->client) {
+                               if (entry->client->tgid != current->tgid) {
+                                       put_task_struct(task_s);
+                                       put_pid(pid_struct);
                                        continue;
-                       if (!entry->in_service)
+                               }
+                       }
+                       if (!entry->in_service) {
+                               put_task_struct(task_s);
+                               put_pid(pid_struct);
                                continue;
+                       }
                        if (copy_to_user(buf + ret, &data_type, sizeof(int))) {
+                               put_task_struct(task_s);
+                               put_pid(pid_struct);
                                mutex_unlock(&driver->dci_mutex);
                                goto end;
                        }
                        ret += sizeof(int);
                        if (copy_to_user(buf + ret, &entry->client_info.token,
                                sizeof(int))) {
+                               put_task_struct(task_s);
+                               put_pid(pid_struct);
                                mutex_unlock(&driver->dci_mutex);
                                goto end;
                        }
@@ -3367,9 +3379,13 @@ exit:
                        atomic_dec(&driver->data_ready_notif[index]);
                        mutex_unlock(&driver->diagchar_mutex);
                        if (exit_stat == 1) {
+                               put_task_struct(task_s);
+                               put_pid(pid_struct);
                                mutex_unlock(&driver->dci_mutex);
                                goto end;
                        }
+                       put_task_struct(task_s);
+                       put_pid(pid_struct);
                }
                mutex_unlock(&driver->dci_mutex);
                goto end;