diff options
author | Igor Nabirushkin <inabirushkin@nvidia.com> | 2015-04-13 17:00:37 +0400 |
---|---|---|
committer | Winnie Hsu <whsu@nvidia.com> | 2015-05-29 14:29:15 -0700 |
commit | 41e526efda84af5850e664dc5bfbe4eedbc1435e (patch) | |
tree | 8c03b41ee9cf9047ec397afa064d9e0d669206b9 /drivers/misc | |
parent | c0854f72231631dbc278572ecb5d568053ff97a8 (diff) |
misc: tegra-profiler: fix stop error
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
(cherry picked from commit 79fcedbbf7fbc984ec8b95900ee49af0a9be590b)
Reviewed-on: http://git-master/r/748093
GVS: Gerrit_Virtual_Submit
Reviewed-by: Andrey Trachenko <atrachenko@nvidia.com>
Reviewed-by: Winnie Hsu <whsu@nvidia.com>
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/tegra-profiler/comm.c | 56 | ||||
-rw-r--r-- | drivers/misc/tegra-profiler/comm.h | 5 | ||||
-rw-r--r-- | drivers/misc/tegra-profiler/main.c | 41 | ||||
-rw-r--r-- | drivers/misc/tegra-profiler/version.h | 4 |
4 files changed, 36 insertions, 70 deletions
diff --git a/drivers/misc/tegra-profiler/comm.c b/drivers/misc/tegra-profiler/comm.c index 2d70f6318d3e..80c84614081a 100644 --- a/drivers/misc/tegra-profiler/comm.c +++ b/drivers/misc/tegra-profiler/comm.c @@ -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); diff --git a/drivers/misc/tegra-profiler/comm.h b/drivers/misc/tegra-profiler/comm.h index c89acd7db904..d04e04fdcd22 100644 --- a/drivers/misc/tegra-profiler/comm.h +++ b/drivers/misc/tegra-profiler/comm.h @@ -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, diff --git a/drivers/misc/tegra-profiler/main.c b/drivers/misc/tegra-profiler/main.c index d3236970e27a..80a2b7317ac9 100644 --- a/drivers/misc/tegra-profiler/main.c +++ b/drivers/misc/tegra-profiler/main.c @@ -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]; diff --git a/drivers/misc/tegra-profiler/version.h b/drivers/misc/tegra-profiler/version.h index 53e1e063e6bc..7fdf4c4bfadf 100644 --- a/drivers/misc/tegra-profiler/version.h +++ b/drivers/misc/tegra-profiler/version.h @@ -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 */ |