Linux-audit Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] introduce get_task_exe_file and use it to fix audit_exe_compare
@ 2016-08-22 20:51 Mateusz Guzik
  2016-08-22 20:51 ` [PATCH 1/2] mm: introduce get_task_exe_file Mateusz Guzik
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Mateusz Guzik @ 2016-08-22 20:51 UTC (permalink / raw)
  To: Konstantin Khlebnikov, Richard Guy Briggs
  Cc: ebiederm, oleg, sgrubb, pmoore, eparis, luto, linux-audit,
	linux-kernel, Al Viro

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] mm: introduce get_task_exe_file
  2016-08-22 20:51 [PATCH 0/2] introduce get_task_exe_file and use it to fix audit_exe_compare Mateusz Guzik
@ 2016-08-22 20:51 ` Mateusz Guzik
  2016-08-22 21:49   ` kbuild test robot
  2016-08-22 20:51 ` [PATCH 2/2] audit: fix exe_file access in audit_exe_compare Mateusz Guzik
  2016-08-23  8:34 ` [PATCH 0/2] introduce get_task_exe_file and use it to fix audit_exe_compare Konstantin Khlebnikov
  2 siblings, 1 reply; 5+ messages in thread
From: Mateusz Guzik @ 2016-08-22 20:51 UTC (permalink / raw)
  To: Konstantin Khlebnikov, Richard Guy Briggs
  Cc: ebiederm, oleg, sgrubb, pmoore, eparis, luto, linux-audit,
	linux-kernel, Al Viro

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

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] audit: fix exe_file access in audit_exe_compare
  2016-08-22 20:51 [PATCH 0/2] introduce get_task_exe_file and use it to fix audit_exe_compare Mateusz Guzik
  2016-08-22 20:51 ` [PATCH 1/2] mm: introduce get_task_exe_file Mateusz Guzik
@ 2016-08-22 20:51 ` Mateusz Guzik
  2016-08-23  8:34 ` [PATCH 0/2] introduce get_task_exe_file and use it to fix audit_exe_compare Konstantin Khlebnikov
  2 siblings, 0 replies; 5+ messages in thread
From: Mateusz Guzik @ 2016-08-22 20:51 UTC (permalink / raw)
  To: Konstantin Khlebnikov, Richard Guy Briggs
  Cc: ebiederm, oleg, sgrubb, pmoore, eparis, luto, linux-audit,
	linux-kernel, Al Viro

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

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] mm: introduce get_task_exe_file
  2016-08-22 20:51 ` [PATCH 1/2] mm: introduce get_task_exe_file Mateusz Guzik
@ 2016-08-22 21:49   ` kbuild test robot
  0 siblings, 0 replies; 5+ messages in thread
From: kbuild test robot @ 2016-08-22 21:49 UTC (permalink / raw)
  To: Mateusz Guzik
  Cc: kbuild-all, Konstantin Khlebnikov, Richard Guy Briggs, ebiederm,
	oleg, sgrubb, pmoore, eparis, luto, linux-audit, linux-kernel,
	Al Viro

[-- Attachment #1: Type: text/plain, Size: 2119 bytes --]

Hi Mateusz,

[auto build test WARNING on linus/master]
[also build test WARNING on v4.8-rc3 next-20160822]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
[Suggest to use git(>=2.9.0) format-patch --base=<commit> (or --base=auto for convenience) to record what (public, well-known) commit your patch series was built on]
[Check https://git-scm.com/docs/git-format-patch for more information]

url:    https://github.com/0day-ci/linux/commits/Mateusz-Guzik/mm-introduce-get_task_exe_file/20160823-045421
config: sparc64-allyesconfig (attached as .config)
compiler: sparc64-linux-gnu-gcc (Debian 5.4.0-6) 5.4.0 20160609
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=sparc64 

All warnings (new ones prefixed by >>):

   kernel/fork.c: In function 'get_task_exe_file':
>> kernel/fork.c:820:1: warning: label 'out' defined but not used [-Wunused-label]
    out:
    ^

vim +/out +820 kernel/fork.c

   804	 * Returns %NULL if task's mm (if any) has no associated executable file or
   805	 * this is a kernel thread with borrowed mm (see the comment above get_task_mm).
   806	 * User must release file via fput().
   807	 */
   808	struct file *get_task_exe_file(struct task_struct *task)
   809	{
   810		struct file *exe_file = NULL;
   811		struct mm_struct *mm;
   812	
   813		task_lock(task);
   814		mm = task->mm;
   815		if (mm) {
   816			if (!(task->flags & PF_KTHREAD))
   817				exe_file = get_mm_exe_file(mm);
   818		}
   819		task_unlock(task);
 > 820	out:
   821		return exe_file;
   822	}
   823	EXPORT_SYMBOL(get_task_exe_file);
   824	
   825	/**
   826	 * get_task_mm - acquire a reference to the task's mm
   827	 *
   828	 * Returns %NULL if the task has no mm.  Checks PF_KTHREAD (meaning

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 47053 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/2] introduce get_task_exe_file and use it to fix audit_exe_compare
  2016-08-22 20:51 [PATCH 0/2] introduce get_task_exe_file and use it to fix audit_exe_compare Mateusz Guzik
  2016-08-22 20:51 ` [PATCH 1/2] mm: introduce get_task_exe_file Mateusz Guzik
  2016-08-22 20:51 ` [PATCH 2/2] audit: fix exe_file access in audit_exe_compare Mateusz Guzik
@ 2016-08-23  8:34 ` Konstantin Khlebnikov
  2 siblings, 0 replies; 5+ messages in thread
From: Konstantin Khlebnikov @ 2016-08-23  8:34 UTC (permalink / raw)
  To: Mateusz Guzik, Richard Guy Briggs
  Cc: ebiederm, oleg, sgrubb, pmoore, eparis, luto, linux-audit,
	linux-kernel, Al Viro

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-08-23  8:34 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-08-22 20:51 [PATCH 0/2] introduce get_task_exe_file and use it to fix audit_exe_compare Mateusz Guzik
2016-08-22 20:51 ` [PATCH 1/2] mm: introduce get_task_exe_file Mateusz Guzik
2016-08-22 21:49   ` kbuild test robot
2016-08-22 20:51 ` [PATCH 2/2] audit: fix exe_file access in audit_exe_compare Mateusz Guzik
2016-08-23  8:34 ` [PATCH 0/2] introduce get_task_exe_file and use it to fix audit_exe_compare Konstantin Khlebnikov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox