From 3ec2f427e6f82b9b8f9b18dd2c758b864385df39 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Fri, 3 Jan 2014 20:42:18 +0900 Subject: drm/i915: Fix refcount leak and possible NULL pointerdereference. Since get_pid_task() grabs a reference on the task_struct, we have to drop the refcount after reading that task's comm name. Use pid_task() with RCU instead. Also, avoid directly reading like pid_task()->comm because pid_task() will return NULL if the task have already exit()ed. This patch fixes both problems. Signed-off-by: Tetsuo Handa Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/i915_debugfs.c') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 6294ffdcc0a..6fe7934b289 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -404,16 +404,26 @@ static int i915_gem_object_info(struct seq_file *m, void* data) seq_putc(m, '\n'); list_for_each_entry_reverse(file, &dev->filelist, lhead) { struct file_stats stats; + struct task_struct *task; memset(&stats, 0, sizeof(stats)); idr_for_each(&file->object_idr, per_file_stats, &stats); + /* + * Although we have a valid reference on file->pid, that does + * not guarantee that the task_struct who called get_pid() is + * still alive (e.g. get_pid(current) => fork() => exit()). + * Therefore, we need to protect this ->comm access using RCU. + */ + rcu_read_lock(); + task = pid_task(file->pid, PIDTYPE_PID); seq_printf(m, "%s: %u objects, %zu bytes (%zu active, %zu inactive, %zu unbound)\n", - get_pid_task(file->pid, PIDTYPE_PID)->comm, + task ? task->comm : "", stats.count, stats.total, stats.active, stats.inactive, stats.unbound); + rcu_read_unlock(); } mutex_unlock(&dev->struct_mutex); -- cgit v1.2.3