summaryrefslogtreecommitdiff
path: root/drivers/misc
diff options
context:
space:
mode:
authorIgor Nabirushkin <inabirushkin@nvidia.com>2015-04-13 17:00:37 +0400
committerWinnie Hsu <whsu@nvidia.com>2015-05-29 14:29:15 -0700
commit41e526efda84af5850e664dc5bfbe4eedbc1435e (patch)
tree8c03b41ee9cf9047ec397afa064d9e0d669206b9 /drivers/misc
parentc0854f72231631dbc278572ecb5d568053ff97a8 (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.c56
-rw-r--r--drivers/misc/tegra-profiler/comm.h5
-rw-r--r--drivers/misc/tegra-profiler/main.c41
-rw-r--r--drivers/misc/tegra-profiler/version.h4
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 */