misc: tegra-profiler: fix stop error
Igor Nabirushkin [Mon, 13 Apr 2015 13:00:37 +0000 (17:00 +0400)]
Do not verify the existence of profiled process after
start of session.
It fixes the stop error on non-rooted devices when
application is terminated during the profile session.

Bug 1634968

Change-Id: I5384e6de3c7ff9791033d344b02acba9a729157b
Signed-off-by: Igor Nabirushkin <inabirushkin@nvidia.com>
Reviewed-on: http://git-master/r/730898
Reviewed-by: Dmitry Antipov <dantipov@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Sachin Nikam <snikam@nvidia.com>

drivers/misc/tegra-profiler/comm.c
drivers/misc/tegra-profiler/comm.h
drivers/misc/tegra-profiler/main.c
drivers/misc/tegra-profiler/version.h

index 2d70f63..80c8461 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * drivers/misc/tegra-profiler/comm.c
  *
- * Copyright (c) 2015, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2013-2015, NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -54,8 +54,6 @@ struct quadd_comm_ctx {
        int nr_users;
 
        int params_ok;
-       pid_t process_pid;
-       uid_t debug_app_uid;
 
        wait_queue_head_t read_wait;
 
@@ -251,31 +249,6 @@ static struct quadd_comm_data_interface comm_data = {
        .is_active = is_active,
 };
 
-static int check_access_permission(void)
-{
-       struct task_struct *task;
-
-       if (capable(CAP_SYS_ADMIN))
-               return 0;
-
-       if (!comm_ctx.params_ok || comm_ctx.process_pid == 0)
-               return -EACCES;
-
-       rcu_read_lock();
-       task = pid_task(find_vpid(comm_ctx.process_pid), PIDTYPE_PID);
-       rcu_read_unlock();
-       if (!task)
-               return -EACCES;
-
-       if (current_fsuid() != task_uid(task) &&
-           task_uid(task) != comm_ctx.debug_app_uid) {
-               pr_err("Permission denied, owner/task uids: %u/%u\n",
-                          current_fsuid(), task_uid(task));
-               return -EACCES;
-       }
-       return 0;
-}
-
 static struct quadd_mmap_area *
 find_mmap(unsigned long vm_start)
 {
@@ -449,17 +422,18 @@ device_ioctl(struct file *file,
        struct quadd_sections extabs;
        struct quadd_mmap_rb_info mmap_rb;
 
+       mutex_lock(&comm_ctx.io_mutex);
+
        if (ioctl_num != IOCTL_SETUP &&
            ioctl_num != IOCTL_GET_CAP &&
            ioctl_num != IOCTL_GET_STATE &&
            ioctl_num != IOCTL_GET_VERSION) {
-               err = check_access_permission();
-               if (err)
-                       return err;
+               if (!comm_ctx.params_ok) {
+                       err = -EACCES;
+                       goto error_out;
+               }
        }
 
-       mutex_lock(&comm_ctx.io_mutex);
-
        switch (ioctl_num) {
        case IOCTL_SETUP:
                if (atomic_read(&comm_ctx.active)) {
@@ -467,6 +441,7 @@ device_ioctl(struct file *file,
                        err = -EBUSY;
                        goto error_out;
                }
+               comm_ctx.params_ok = 0;
 
                user_params = vmalloc(sizeof(*user_params));
                if (!user_params) {
@@ -482,15 +457,12 @@ device_ioctl(struct file *file,
                        goto error_out;
                }
 
-               err = comm_ctx.control->set_parameters(user_params,
-                                                      &comm_ctx.debug_app_uid);
+               err = comm_ctx.control->set_parameters(user_params);
                if (err) {
                        pr_err("error: setup failed\n");
                        vfree(user_params);
                        goto error_out;
                }
-               comm_ctx.params_ok = 1;
-               comm_ctx.process_pid = user_params->pids[0];
 
                if (user_params->reserved[QUADD_PARAM_IDX_SIZE_OF_RB] == 0) {
                        pr_err("error: too old version of daemon\n");
@@ -499,6 +471,8 @@ device_ioctl(struct file *file,
                        goto error_out;
                }
 
+               comm_ctx.params_ok = 1;
+
                pr_info("setup success: freq/mafreq: %u/%u, backtrace: %d, pid: %d\n",
                        user_params->freq,
                        user_params->ma_freq,
@@ -550,13 +524,6 @@ device_ioctl(struct file *file,
 
        case IOCTL_START:
                if (!atomic_cmpxchg(&comm_ctx.active, 0, 1)) {
-                       if (!comm_ctx.params_ok) {
-                               pr_err("error: params failed\n");
-                               atomic_set(&comm_ctx.active, 0);
-                               err = -EFAULT;
-                               goto error_out;
-                       }
-
                        err = comm_ctx.control->start();
                        if (err) {
                                pr_err("error: start failed\n");
@@ -824,7 +791,6 @@ static int comm_init(void)
        atomic_set(&comm_ctx.active, 0);
 
        comm_ctx.params_ok = 0;
-       comm_ctx.process_pid = 0;
        comm_ctx.nr_users = 0;
 
        init_waitqueue_head(&comm_ctx.read_wait);
index c89acd7..d04e04f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * drivers/misc/tegra-profiler/comm.h
  *
- * Copyright (c) 2015, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2013-2015, NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -54,8 +54,7 @@ struct quadd_mmap_area {
 struct quadd_comm_control_interface {
        int (*start)(void);
        void (*stop)(void);
-       int (*set_parameters)(struct quadd_parameters *param,
-                             uid_t *debug_app_uid);
+       int (*set_parameters)(struct quadd_parameters *param);
        void (*get_capabilities)(struct quadd_comm_cap *cap);
        void (*get_state)(struct quadd_module_state *state);
        int (*set_extab)(struct quadd_sections *extabs,
index d323697..80a2b73 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * drivers/misc/tegra-profiler/main.c
  *
- * Copyright (c) 2015, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2013-2015, NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -178,9 +178,10 @@ validate_freq(unsigned int freq)
 }
 
 static int
-set_parameters(struct quadd_parameters *p, uid_t *debug_app_uid)
+set_parameters(struct quadd_parameters *p)
 {
        int i, err, uid = 0;
+       uid_t task_uid, current_uid;
        int pmu_events_id[QUADD_MAX_COUNTERS];
        int pl310_events_id;
        int nr_pmu = 0, nr_pl310 = 0;
@@ -188,54 +189,54 @@ set_parameters(struct quadd_parameters *p, uid_t *debug_app_uid)
        u64 *low_addr_p;
 
        if (!validate_freq(p->freq)) {
-               pr_err("%s: incorrect frequency: %u\n", __func__, p->freq);
+               pr_err("error: incorrect frequency: %u\n", p->freq);
                return -EINVAL;
        }
 
-       ctx.param = *p;
-
-       for (i = 0; i < ARRAY_SIZE(p->reserved); i++)
-               ctx.param.reserved[i] = p->reserved[i];
-
        /* Currently only one process */
        if (p->nr_pids != 1)
                return -EINVAL;
 
        p->package_name[sizeof(p->package_name) - 1] = '\0';
 
+       ctx.param = *p;
+
        rcu_read_lock();
        task = pid_task(find_vpid(p->pids[0]), PIDTYPE_PID);
        rcu_read_unlock();
        if (!task) {
-               pr_err("Process not found: %u\n", p->pids[0]);
+               pr_err("error: process not found: %u\n", p->pids[0]);
                return -ESRCH;
        }
 
-       pr_info("owner/task uids: %u/%u\n", current_fsuid(), task_uid(task));
+       current_uid = current_fsuid();
+       task_uid = task_uid(task);
+       pr_info("owner/task uids: %u/%u\n", current_uid, task_uid);
+
        if (!capable(CAP_SYS_ADMIN)) {
-               if (current_fsuid() != task_uid(task)) {
+               if (current_uid != task_uid) {
+                       pr_info("package: %s\n", p->package_name);
+
                        uid = quadd_auth_is_debuggable((char *)p->package_name);
                        if (uid < 0) {
-                               pr_err("Error: QuadD security service\n");
+                               pr_err("error: tegra profiler security service\n");
                                return uid;
                        } else if (uid == 0) {
-                               pr_err("Error: app is not debuggable\n");
+                               pr_err("error: app is not debuggable\n");
                                return -EACCES;
                        }
+                       pr_info("app is debuggable, uid: %u\n", uid);
 
-                       *debug_app_uid = uid;
-                       pr_info("debug_app_uid: %u\n", uid);
+                       if (task_uid != uid) {
+                               pr_err("error: uids are not matched\n");
+                               return -EACCES;
+                       }
                }
                ctx.collect_kernel_ips = 0;
        } else {
                ctx.collect_kernel_ips = 1;
        }
 
-       for (i = 0; i < p->nr_pids; i++)
-               ctx.param.pids[i] = p->pids[i];
-
-       ctx.param.nr_pids = p->nr_pids;
-
        for (i = 0; i < p->nr_events; i++) {
                int event = p->events[i];
 
index 53e1e06..7fdf4c4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * drivers/misc/tegra-profiler/hrt.h
  *
- * Copyright (c) 2015, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2013-2015, NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -18,7 +18,7 @@
 #ifndef __QUADD_VERSION_H
 #define __QUADD_VERSION_H
 
-#define QUADD_MODULE_VERSION           "1.101"
+#define QUADD_MODULE_VERSION           "1.102"
 #define QUADD_MODULE_BRANCH            "Dev"
 
 #endif /* __QUADD_VERSION_H */