aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-09-01 18:55:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-09-01 18:55:56 -0400
commit511a8cdb650544b7efd1bbccf7967d3153aee5f6 (patch)
tree9e97e173ca7fb552e4994dd527dcff396acfdcfb
parent7d1ce606a37922879cbe40a6122047827105a332 (diff)
parent5efc244346f9f338765da3d592f7947b0afdc4b5 (diff)
Merge branch 'stable-4.8' of git://git.infradead.org/users/pcmoore/audit
Pull audit fixes from Paul Moore: "Two small patches to fix some bugs with the audit-by-executable functionality we introduced back in v4.3 (both patches are marked for the stable folks)" * 'stable-4.8' of git://git.infradead.org/users/pcmoore/audit: audit: fix exe_file access in audit_exe_compare mm: introduce get_task_exe_file
-rw-r--r--fs/proc/base.c7
-rw-r--r--include/linux/mm.h1
-rw-r--r--kernel/audit_watch.c8
-rw-r--r--kernel/fork.c23
4 files changed, 30 insertions, 9 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 54e270262979..ac0df4dde823 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 = {
1556static int proc_exe_link(struct dentry *dentry, struct path *exe_path) 1556static int proc_exe_link(struct dentry *dentry, struct path *exe_path)
1557{ 1557{
1558 struct task_struct *task; 1558 struct task_struct *task;
1559 struct mm_struct *mm;
1560 struct file *exe_file; 1559 struct file *exe_file;
1561 1560
1562 task = get_proc_task(d_inode(dentry)); 1561 task = get_proc_task(d_inode(dentry));
1563 if (!task) 1562 if (!task)
1564 return -ENOENT; 1563 return -ENOENT;
1565 mm = get_task_mm(task); 1564 exe_file = get_task_exe_file(task);
1566 put_task_struct(task); 1565 put_task_struct(task);
1567 if (!mm)
1568 return -ENOENT;
1569 exe_file = get_mm_exe_file(mm);
1570 mmput(mm);
1571 if (exe_file) { 1566 if (exe_file) {
1572 *exe_path = exe_file->f_path; 1567 *exe_path = exe_file->f_path;
1573 path_get(&exe_file->f_path); 1568 path_get(&exe_file->f_path);
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 08ed53eeedd5..ef815b9cd426 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);
2014 2014
2015extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file); 2015extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file);
2016extern struct file *get_mm_exe_file(struct mm_struct *mm); 2016extern struct file *get_mm_exe_file(struct mm_struct *mm);
2017extern struct file *get_task_exe_file(struct task_struct *task);
2017 2018
2018extern bool may_expand_vm(struct mm_struct *, vm_flags_t, unsigned long npages); 2019extern bool may_expand_vm(struct mm_struct *, vm_flags_t, unsigned long npages);
2019extern void vm_stat_account(struct mm_struct *, vm_flags_t, long npages); 2020extern void vm_stat_account(struct mm_struct *, vm_flags_t, long npages);
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index d6709eb70970..0d302a87f21b 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -19,6 +19,7 @@
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#include <linux/file.h>
22#include <linux/kernel.h> 23#include <linux/kernel.h>
23#include <linux/audit.h> 24#include <linux/audit.h>
24#include <linux/kthread.h> 25#include <linux/kthread.h>
@@ -544,10 +545,11 @@ int audit_exe_compare(struct task_struct *tsk, struct audit_fsnotify_mark *mark)
544 unsigned long ino; 545 unsigned long ino;
545 dev_t dev; 546 dev_t dev;
546 547
547 rcu_read_lock(); 548 exe_file = get_task_exe_file(tsk);
548 exe_file = rcu_dereference(tsk->mm->exe_file); 549 if (!exe_file)
550 return 0;
549 ino = exe_file->f_inode->i_ino; 551 ino = exe_file->f_inode->i_ino;
550 dev = exe_file->f_inode->i_sb->s_dev; 552 dev = exe_file->f_inode->i_sb->s_dev;
551 rcu_read_unlock(); 553 fput(exe_file);
552 return audit_mark_compare(mark, ino, dev); 554 return audit_mark_compare(mark, ino, dev);
553} 555}
diff --git a/kernel/fork.c b/kernel/fork.c
index aaf782327bf3..36c0daa03c60 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -799,6 +799,29 @@ struct file *get_mm_exe_file(struct mm_struct *mm)
799EXPORT_SYMBOL(get_mm_exe_file); 799EXPORT_SYMBOL(get_mm_exe_file);
800 800
801/** 801/**
802 * get_task_exe_file - acquire a reference to the task's executable file
803 *
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 */
808struct 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 return exe_file;
821}
822EXPORT_SYMBOL(get_task_exe_file);
823
824/**
802 * get_task_mm - acquire a reference to the task's mm 825 * get_task_mm - acquire a reference to the task's mm
803 * 826 *
804 * Returns %NULL if the task has no mm. Checks PF_KTHREAD (meaning 827 * Returns %NULL if the task has no mm. Checks PF_KTHREAD (meaning