Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1468042 > unrolled thread

[PATCH 0/2] introduce get_task_exe_file and use it to fix audit_exe_compare

Started byMateusz Guzik <mguzik@redhat.com>
First post2016-08-22 23:00 +0200
Last post2016-08-23 10:50 +0200
Articles 4 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 0/2] introduce get_task_exe_file and use it to fix audit_exe_compare Mateusz Guzik <mguzik@redhat.com> - 2016-08-22 23:00 +0200
    [PATCH 1/2] mm: introduce get_task_exe_file Mateusz Guzik <mguzik@redhat.com> - 2016-08-22 23:00 +0200
    [PATCH 2/2] audit: fix exe_file access in audit_exe_compare Mateusz Guzik <mguzik@redhat.com> - 2016-08-22 23:00 +0200
    Re: [PATCH 0/2] introduce get_task_exe_file and use it to fix  audit_exe_compare Konstantin Khlebnikov <khlebnikov@yandex-team.ru> - 2016-08-23 10:50 +0200

#1468042 — [PATCH 0/2] introduce get_task_exe_file and use it to fix audit_exe_compare

FromMateusz Guzik <mguzik@redhat.com>
Date2016-08-22 23:00 +0200
Subject[PATCH 0/2] introduce get_task_exe_file and use it to fix audit_exe_compare
Message-ID<s94u5-2Ol-19@gated-at.bofh.it>
audit_exe_compare directly accesses mm->exe_file without making sure the
object is stable. Fixing it using current primitives results in
partially duplicating what proc_exe_link is doing.

As such, introduce a trivial helper which can be used in both places and
fix the func.

Mateusz Guzik (2):
  mm: introduce get_task_exe_file
  audit: fix exe_file access in audit_exe_compare

 fs/proc/base.c       |  7 +------
 include/linux/mm.h   |  1 +
 kernel/audit_watch.c |  8 +++++---
 kernel/fork.c        | 24 ++++++++++++++++++++++++
 4 files changed, 31 insertions(+), 9 deletions(-)

-- 
1.8.3.1

[toc] | [next] | [standalone]


#1468046 — [PATCH 1/2] mm: introduce get_task_exe_file

FromMateusz Guzik <mguzik@redhat.com>
Date2016-08-22 23:00 +0200
Subject[PATCH 1/2] mm: introduce get_task_exe_file
Message-ID<s94u6-2Ol-29@gated-at.bofh.it>
In reply to#1468042
For more convenient access if one has a pointer to the task.

As a minor nit take advantage of the fact that only task lock + rcu are
needed to safely grab ->exe_file. This saves mm refcount dance.

Use the helper in proc_exe_link.

Signed-off-by: Mateusz Guzik <mguzik@redhat.com>
---
 fs/proc/base.c     |  7 +------
 include/linux/mm.h |  1 +
 kernel/fork.c      | 24 ++++++++++++++++++++++++
 3 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 2ed41cb..ebccdc1 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1556,18 +1556,13 @@ static const struct file_operations proc_pid_set_comm_operations = {
 static int proc_exe_link(struct dentry *dentry, struct path *exe_path)
 {
 	struct task_struct *task;
-	struct mm_struct *mm;
 	struct file *exe_file;
 
 	task = get_proc_task(d_inode(dentry));
 	if (!task)
 		return -ENOENT;
-	mm = get_task_mm(task);
+	exe_file = get_task_exe_file(task);
 	put_task_struct(task);
-	if (!mm)
-		return -ENOENT;
-	exe_file = get_mm_exe_file(mm);
-	mmput(mm);
 	if (exe_file) {
 		*exe_path = exe_file->f_path;
 		path_get(&exe_file->f_path);
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 9d85402..f4e639e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2014,6 +2014,7 @@ extern void mm_drop_all_locks(struct mm_struct *mm);
 
 extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file);
 extern struct file *get_mm_exe_file(struct mm_struct *mm);
+extern struct file *get_task_exe_file(struct task_struct *task);
 
 extern bool may_expand_vm(struct mm_struct *, vm_flags_t, unsigned long npages);
 extern void vm_stat_account(struct mm_struct *, vm_flags_t, long npages);
diff --git a/kernel/fork.c b/kernel/fork.c
index 6fe775c..84a636d 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -800,6 +800,30 @@ struct file *get_mm_exe_file(struct mm_struct *mm)
 EXPORT_SYMBOL(get_mm_exe_file);
 
 /**
+ * get_task_exe_file - acquire a reference to the task's executable file
+ *
+ * Returns %NULL if task's mm (if any) has no associated executable file or
+ * this is a kernel thread with borrowed mm (see the comment above get_task_mm).
+ * User must release file via fput().
+ */
+struct file *get_task_exe_file(struct task_struct *task)
+{
+	struct file *exe_file = NULL;
+	struct mm_struct *mm;
+
+	task_lock(task);
+	mm = task->mm;
+	if (mm) {
+		if (!(task->flags & PF_KTHREAD))
+			exe_file = get_mm_exe_file(mm);
+	}
+	task_unlock(task);
+out:
+	return exe_file;
+}
+EXPORT_SYMBOL(get_task_exe_file);
+
+/**
  * get_task_mm - acquire a reference to the task's mm
  *
  * Returns %NULL if the task has no mm.  Checks PF_KTHREAD (meaning
-- 
1.8.3.1

[toc] | [prev] | [next] | [standalone]


#1468053 — [PATCH 2/2] audit: fix exe_file access in audit_exe_compare

FromMateusz Guzik <mguzik@redhat.com>
Date2016-08-22 23:00 +0200
Subject[PATCH 2/2] audit: fix exe_file access in audit_exe_compare
Message-ID<s94u6-2Ol-53@gated-at.bofh.it>
In reply to#1468042
Prior to the change the function would blindly deference mm, exe_file
and exe_file->f_inode, each of which could have been NULL or freed.

Use get_task_exe_file to safely obtain stable exe_file.

Signed-off-by: Mateusz Guzik <mguzik@redhat.com>
---
 kernel/audit_watch.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index d6709eb..0d302a8 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/file.h>
 #include <linux/kernel.h>
 #include <linux/audit.h>
 #include <linux/kthread.h>
@@ -544,10 +545,11 @@ int audit_exe_compare(struct task_struct *tsk, struct audit_fsnotify_mark *mark)
 	unsigned long ino;
 	dev_t dev;
 
-	rcu_read_lock();
-	exe_file = rcu_dereference(tsk->mm->exe_file);
+	exe_file = get_task_exe_file(tsk);
+	if (!exe_file)
+		return 0;
 	ino = exe_file->f_inode->i_ino;
 	dev = exe_file->f_inode->i_sb->s_dev;
-	rcu_read_unlock();
+	fput(exe_file);
 	return audit_mark_compare(mark, ino, dev);
 }
-- 
1.8.3.1

[toc] | [prev] | [next] | [standalone]


#1468388 — Re: [PATCH 0/2] introduce get_task_exe_file and use it to fix audit_exe_compare

FromKonstantin Khlebnikov <khlebnikov@yandex-team.ru>
Date2016-08-23 10:50 +0200
SubjectRe: [PATCH 0/2] introduce get_task_exe_file and use it to fix audit_exe_compare
Message-ID<s9fzb-1v0-17@gated-at.bofh.it>
In reply to#1468042
On 22.08.2016 23:51, Mateusz Guzik wrote:
> audit_exe_compare directly accesses mm->exe_file without making sure the
> object is stable. Fixing it using current primitives results in
> partially duplicating what proc_exe_link is doing.
>
> As such, introduce a trivial helper which can be used in both places and
> fix the func.

Looks good. Except trivial warning that test bot found.

Acked-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>

>
> Mateusz Guzik (2):
>   mm: introduce get_task_exe_file
>   audit: fix exe_file access in audit_exe_compare
>
>  fs/proc/base.c       |  7 +------
>  include/linux/mm.h   |  1 +
>  kernel/audit_watch.c |  8 +++++---
>  kernel/fork.c        | 24 ++++++++++++++++++++++++
>  4 files changed, 31 insertions(+), 9 deletions(-)
>


-- 
Konstantin

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web