forked from rubenslte/android_kernel_samsung_msm8226
msm: kgsl: Compare pid pointer instead of TGID for a new process
There is a possibility of sharing process_private between two unrelated processes due to PID wrapping. In kgsl_process_private_new(), instead of checking numeric TGID, compare the unique pid pointer of the current process with that of the existing processes in kgsl process list to allow sharing of process_private data judiciously. Also, in all required functions get TGID/PID of a process from its struct pid. Issue: SEC-3014 Change-Id: I0e3d5d79275cdb3f3c304fb36322ad56b0d0b227 Signed-off-by: Archana Sriram <apsrir@codeaurora.org> Signed-off-by: Harshitha Sai Neelati <hsaine@codeaurora.org> (cherry-picked from commit https://source.codeaurora.org/quic/la/kernel/msm-3.10/commit/?id=44b87e44158f6890b4cd468d21646bf25465766f)
This commit is contained in:
committed by
Francescodario Cuzzocrea
parent
eb922bef67
commit
f9a569c25e
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2015,2020, 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
|
||||
@@ -1084,7 +1084,7 @@ static inline const char *_kgsl_context_comm(struct kgsl_context *context)
|
||||
#define pr_fault(_d, _c, fmt, args...) \
|
||||
dev_err((_d)->dev, "%s[%d]: " fmt, \
|
||||
_kgsl_context_comm((_c)->context), \
|
||||
(_c)->context->proc_priv->pid, ##args)
|
||||
pid_nr((_c)->context->proc_priv->pid), ##args)
|
||||
|
||||
|
||||
static void adreno_fault_header(struct kgsl_device *device,
|
||||
|
||||
@@ -420,7 +420,7 @@ static void transfer_results(struct kgsl_device *device,
|
||||
} else {
|
||||
struct adreno_context *adreno_ctxt =
|
||||
ADRENO_CONTEXT(k_ctxt);
|
||||
pid = k_ctxt->proc_priv->pid; /* pid */
|
||||
pid = pid_nr(k_ctxt->proc_priv->pid); /* pid */
|
||||
tid = k_ctxt->tid; /* tid creator */
|
||||
client_type = adreno_ctxt->type << 16;
|
||||
}
|
||||
|
||||
+13
-7
@@ -904,6 +904,7 @@ static void kgsl_destroy_process_private(struct kref *kref)
|
||||
if (private->debug_root)
|
||||
debugfs_remove_recursive(private->debug_root);
|
||||
|
||||
put_pid(private->pid);
|
||||
idr_destroy(&private->mem_idr);
|
||||
kgsl_mmu_putpagetable(private->pagetable);
|
||||
|
||||
@@ -938,7 +939,7 @@ struct kgsl_process_private *kgsl_process_private_find(pid_t pid)
|
||||
|
||||
mutex_lock(&kgsl_driver.process_mutex);
|
||||
list_for_each_entry(p, &kgsl_driver.process_list, list) {
|
||||
if (p->pid == pid) {
|
||||
if (pid_nr(p->pid) == pid) {
|
||||
if (kgsl_process_private_get(p))
|
||||
private = p;
|
||||
break;
|
||||
@@ -955,13 +956,16 @@ struct kgsl_process_private *kgsl_process_private_find(pid_t pid)
|
||||
static struct kgsl_process_private *kgsl_process_private_new(void)
|
||||
{
|
||||
struct kgsl_process_private *private;
|
||||
struct pid *cur_pid = get_task_pid(current->group_leader, PIDTYPE_PID);
|
||||
|
||||
/* Search in the process list */
|
||||
mutex_lock(&kgsl_driver.process_mutex);
|
||||
list_for_each_entry(private, &kgsl_driver.process_list, list) {
|
||||
if (private->pid == task_tgid_nr(current)) {
|
||||
if (!kgsl_process_private_get(private))
|
||||
if (private->pid == cur_pid) {
|
||||
if (!kgsl_process_private_get(private)) {
|
||||
put_pid(cur_pid);
|
||||
private = NULL;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@@ -973,7 +977,7 @@ static struct kgsl_process_private *kgsl_process_private_new(void)
|
||||
|
||||
kref_init(&private->refcount);
|
||||
|
||||
private->pid = task_tgid_nr(current);
|
||||
private->pid = cur_pid;
|
||||
spin_lock_init(&private->mem_lock);
|
||||
mutex_init(&private->process_private_mutex);
|
||||
/* Add the newly created process struct obj to the process list */
|
||||
@@ -1016,8 +1020,10 @@ kgsl_get_process_private(struct kgsl_device *device)
|
||||
pt_name = task_tgid_nr(current);
|
||||
private->pagetable =
|
||||
kgsl_mmu_getpagetable(&device->mmu, pt_name);
|
||||
if (private->pagetable == NULL)
|
||||
if (private->pagetable == NULL) {
|
||||
put_pid(private->pid);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (kgsl_process_init_sysfs(device, private))
|
||||
@@ -2662,7 +2668,7 @@ static long _sharedmem_free_entry(struct kgsl_mem_entry *entry)
|
||||
|
||||
trace_kgsl_mem_free(entry);
|
||||
|
||||
kgsl_memfree_add(entry->priv->pid, entry->memdesc.gpuaddr,
|
||||
kgsl_memfree_add(pid_nr(entry->priv->pid), entry->memdesc.gpuaddr,
|
||||
entry->memdesc.size, entry->memdesc.flags);
|
||||
|
||||
/*
|
||||
@@ -4140,7 +4146,7 @@ kgsl_get_unmapped_area(struct file *file, unsigned long addr,
|
||||
if (IS_ERR_VALUE(ret))
|
||||
KGSL_MEM_ERR(device,
|
||||
"pid %d pgoff %lx len %ld failed error %ld\n",
|
||||
private->pid, pgoff, len, ret);
|
||||
pid_nr(private->pid), pgoff, len, ret);
|
||||
put:
|
||||
kgsl_mem_entry_put(entry);
|
||||
return ret;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2002,2008-2014, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2002,2008-2014,2020, 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
|
||||
@@ -309,7 +309,7 @@ kgsl_process_init_debugfs(struct kgsl_process_private *private)
|
||||
int ret = 0;
|
||||
struct dentry *dentry;
|
||||
|
||||
snprintf(name, sizeof(name), "%d", private->pid);
|
||||
snprintf(name, sizeof(name), "%d", pid_nr(private->pid));
|
||||
|
||||
private->debug_root = debugfs_create_dir(name, proc_d_debugfs);
|
||||
|
||||
@@ -327,7 +327,8 @@ kgsl_process_init_debugfs(struct kgsl_process_private *private)
|
||||
* success.
|
||||
*/
|
||||
dentry = debugfs_create_file("mem", 0444, private->debug_root,
|
||||
(void *) ((unsigned long) private->pid), &process_mem_fops);
|
||||
(void *) ((unsigned long) pid_nr(private->pid)),
|
||||
&process_mem_fops);
|
||||
|
||||
if (IS_ERR(dentry)) {
|
||||
ret = PTR_ERR(dentry);
|
||||
|
||||
@@ -436,7 +436,7 @@ struct kgsl_context {
|
||||
* struct kgsl_process_private - Private structure for a KGSL process (across
|
||||
* all devices)
|
||||
* @priv: Internal flags, use KGSL_PROCESS_* values
|
||||
* @pid: ID for the task owner of the process
|
||||
* @pid: Identification structure for the task owner of the process
|
||||
* @comm: task name of the process
|
||||
* @mem_lock: Spinlock to protect the process memory lists
|
||||
* @refcount: kref object for reference counting the process
|
||||
@@ -450,7 +450,7 @@ struct kgsl_context {
|
||||
*/
|
||||
struct kgsl_process_private {
|
||||
unsigned long priv;
|
||||
pid_t pid;
|
||||
struct pid *pid;
|
||||
char comm[TASK_COMM_LEN];
|
||||
spinlock_t mem_lock;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2011-2014,2016,2020, 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
|
||||
@@ -193,7 +193,7 @@ static void _prev_entry(struct kgsl_process_private *priv,
|
||||
ret->size = entry->memdesc.size;
|
||||
ret->flags = entry->memdesc.flags;
|
||||
ret->priv = entry->memdesc.priv;
|
||||
ret->pid = priv->pid;
|
||||
ret->pid = pid_nr(priv->pid);
|
||||
}
|
||||
|
||||
node = rb_next(&entry->node);
|
||||
@@ -227,7 +227,7 @@ static void _next_entry(struct kgsl_process_private *priv,
|
||||
ret->size = entry->memdesc.size;
|
||||
ret->flags = entry->memdesc.flags;
|
||||
ret->priv = entry->memdesc.priv;
|
||||
ret->pid = priv->pid;
|
||||
ret->pid = pid_nr(priv->pid);
|
||||
}
|
||||
|
||||
node = rb_prev(&entry->node);
|
||||
|
||||
@@ -176,7 +176,7 @@ kgsl_process_init_sysfs(struct kgsl_device *device,
|
||||
unsigned char name[16];
|
||||
int i, ret = 0;
|
||||
|
||||
snprintf(name, sizeof(name), "%d", private->pid);
|
||||
snprintf(name, sizeof(name), "%d", pid_nr(private->pid));
|
||||
|
||||
ret = kobject_init_and_add(&private->kobj, &ktype_mem_entry,
|
||||
kgsl_driver.prockobj, name);
|
||||
|
||||
@@ -338,7 +338,7 @@ TRACE_EVENT(kgsl_mem_alloc,
|
||||
TP_fast_assign(
|
||||
__entry->gpuaddr = mem_entry->memdesc.gpuaddr;
|
||||
__entry->size = mem_entry->memdesc.size;
|
||||
__entry->tgid = mem_entry->priv->pid;
|
||||
__entry->tgid = pid_nr(mem_entry->priv->pid);
|
||||
kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage),
|
||||
mem_entry->memdesc.flags);
|
||||
__entry->id = mem_entry->id;
|
||||
@@ -435,7 +435,7 @@ TRACE_EVENT(kgsl_mem_map,
|
||||
__entry->size = mem_entry->memdesc.size;
|
||||
__entry->fd = fd;
|
||||
__entry->type = mem_entry->memtype;
|
||||
__entry->tgid = mem_entry->priv->pid;
|
||||
__entry->tgid = pid_nr(mem_entry->priv->pid);
|
||||
kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage),
|
||||
mem_entry->memdesc.flags);
|
||||
__entry->id = mem_entry->id;
|
||||
@@ -469,7 +469,7 @@ TRACE_EVENT(kgsl_mem_free,
|
||||
__entry->gpuaddr = mem_entry->memdesc.gpuaddr;
|
||||
__entry->size = mem_entry->memdesc.size;
|
||||
__entry->type = mem_entry->memtype;
|
||||
__entry->tgid = mem_entry->priv->pid;
|
||||
__entry->tgid = pid_nr(mem_entry->priv->pid);
|
||||
kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage),
|
||||
mem_entry->memdesc.flags);
|
||||
__entry->id = mem_entry->id;
|
||||
@@ -500,7 +500,7 @@ TRACE_EVENT(kgsl_mem_sync_cache,
|
||||
TP_fast_assign(
|
||||
__entry->gpuaddr = mem_entry->memdesc.gpuaddr;
|
||||
__entry->size = mem_entry->memdesc.size;
|
||||
__entry->tgid = mem_entry->priv->pid;
|
||||
__entry->tgid = pid_nr(mem_entry->priv->pid);
|
||||
__entry->id = mem_entry->id;
|
||||
kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage),
|
||||
mem_entry->memdesc.flags);
|
||||
|
||||
Reference in New Issue
Block a user