[linux] 04/07: vfs: Commit to never having executables on proc and sysfs

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Tue Mar 14 14:16:59 UTC 2017


This is an automated email from the git hooks/post-receive script.

benh pushed a commit to branch jessie-security
in repository linux.

commit ccfdfd24acb9d4c92c8dbbaaf04b779201d76e3c
Author: Ben Hutchings <ben at decadent.org.uk>
Date:   Tue Mar 14 01:21:36 2017 +0000

    vfs: Commit to never having executables on proc and sysfs
    
    This also adds the flag we need to fix CVE-2016-10044.
---
 debian/changelog                                   |   1 +
 ...to-never-having-exectuables-on-proc-and-s.patch | 183 +++++++++++++++++++++
 debian/patches/series                              |   1 +
 3 files changed, 185 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 9b521aa..9c16219 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -4,6 +4,7 @@ linux (3.16.39-1+deb8u3) UNRELEASED; urgency=medium
   * mbcache: Reschedule before restarting iteration in mb_cache_entry_alloc()
     (mitigates CVE-2015-8952)
   * mnt: Add a per mount namespace limit on the number of mounts (CVE-2016-6213)
+  * vfs: Commit to never having executables on proc and sysfs
 
  -- Ben Hutchings <ben at decadent.org.uk>  Mon, 13 Mar 2017 23:29:39 +0000
 
diff --git a/debian/patches/bugfix/all/vfs-commit-to-never-having-exectuables-on-proc-and-s.patch b/debian/patches/bugfix/all/vfs-commit-to-never-having-exectuables-on-proc-and-s.patch
new file mode 100644
index 0000000..e0f854b
--- /dev/null
+++ b/debian/patches/bugfix/all/vfs-commit-to-never-having-exectuables-on-proc-and-s.patch
@@ -0,0 +1,183 @@
+From: "Eric W. Biederman" <ebiederm at xmission.com>
+Date: Mon, 29 Jun 2015 14:42:03 -0500
+Subject: vfs: Commit to never having exectuables on proc and sysfs.
+Origin: https://git.kernel.org/linus/90f8572b0f021fdd1baa68e00a8c30482ee9e5f4
+
+Today proc and sysfs do not contain any executable files.  Several
+applications today mount proc or sysfs without noexec and nosuid and
+then depend on there being no exectuables files on proc or sysfs.
+Having any executable files show on proc or sysfs would cause
+a user space visible regression, and most likely security problems.
+
+Therefore commit to never allowing executables on proc and sysfs by
+adding a new flag to mark them as filesystems without executables and
+enforce that flag.
+
+Test the flag where MNT_NOEXEC is tested today, so that the only user
+visible effect will be that exectuables will be treated as if the
+execute bit is cleared.
+
+The filesystems proc and sysfs do not currently incoporate any
+executable files so this does not result in any user visible effects.
+
+This makes it unnecessary to vet changes to proc and sysfs tightly for
+adding exectuable files or changes to chattr that would modify
+existing files, as no matter what the individual file say they will
+not be treated as exectuable files by the vfs.
+
+Not having to vet changes to closely is important as without this we
+are only one proc_create call (or another goof up in the
+implementation of notify_change) from having problematic executables
+on proc.  Those mistakes are all too easy to make and would create
+a situation where there are security issues or the assumptions of
+some program having to be broken (and cause userspace regressions).
+
+Signed-off-by: "Eric W. Biederman" <ebiederm at xmission.com>
+[bwh: Backported to 3.16: we don't have super_block::s_iflags; use
+ file_system_type::fs_flags instead]
+---
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -98,6 +98,12 @@ static inline void put_binfmt(struct lin
+ 	module_put(fmt->module);
+ }
+ 
++bool path_noexec(const struct path *path)
++{
++	return (path->mnt->mnt_flags & MNT_NOEXEC) ||
++	       (path->mnt->mnt_sb->s_type->fs_flags & FS_NOEXEC);
++}
++
+ #ifdef CONFIG_USELIB
+ /*
+  * Note that a shared library must be both readable and executable due to
+@@ -132,7 +138,7 @@ SYSCALL_DEFINE1(uselib, const char __use
+ 		goto exit;
+ 
+ 	error = -EACCES;
+-	if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
++	if (path_noexec(&file->f_path))
+ 		goto exit;
+ 
+ 	fsnotify_open(file);
+@@ -773,7 +779,7 @@ static struct file *do_open_exec(struct
+ 	if (!S_ISREG(file_inode(file)->i_mode))
+ 		goto exit;
+ 
+-	if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
++	if (path_noexec(&file->f_path))
+ 		goto exit;
+ 
+ 	fsnotify_open(file);
+--- a/fs/open.c
++++ b/fs/open.c
+@@ -361,7 +361,7 @@ retry:
+ 		 * with the "noexec" flag.
+ 		 */
+ 		res = -EACCES;
+-		if (path.mnt->mnt_flags & MNT_NOEXEC)
++		if (path_noexec(&path))
+ 			goto out_path_release;
+ 	}
+ 
+--- a/fs/proc/root.c
++++ b/fs/proc/root.c
+@@ -161,7 +161,7 @@ static struct file_system_type proc_fs_t
+ 	.name		= "proc",
+ 	.mount		= proc_mount,
+ 	.kill_sb	= proc_kill_sb,
+-	.fs_flags	= FS_USERNS_VISIBLE | FS_USERNS_MOUNT,
++	.fs_flags	= FS_USERNS_VISIBLE | FS_USERNS_MOUNT | FS_NOEXEC,
+ };
+ 
+ void __init proc_root_init(void)
+--- a/fs/sysfs/mount.c
++++ b/fs/sysfs/mount.c
+@@ -40,6 +40,7 @@ static struct dentry *sysfs_mount(struct
+ 				SYSFS_MAGIC, &new_sb, ns);
+ 	if (IS_ERR(root) || !new_sb)
+ 		kobj_ns_drop(KOBJ_NS_TYPE_NET, ns);
++
+ 	return root;
+ }
+ 
+@@ -55,7 +56,7 @@ static struct file_system_type sysfs_fs_
+ 	.name		= "sysfs",
+ 	.mount		= sysfs_mount,
+ 	.kill_sb	= sysfs_kill_sb,
+-	.fs_flags	= FS_USERNS_VISIBLE | FS_USERNS_MOUNT,
++	.fs_flags	= FS_USERNS_VISIBLE | FS_USERNS_MOUNT | FS_NOEXEC,
+ };
+ 
+ int __init sysfs_init(void)
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1794,6 +1794,7 @@ struct file_system_type {
+ #define FS_USERNS_MOUNT		8	/* Can be mounted by userns root */
+ #define FS_USERNS_DEV_MOUNT	16 /* A userns mount does not imply MNT_NODEV */
+ #define FS_USERNS_VISIBLE	32	/* FS must already be visible */
++#define FS_NOEXEC		64	/* Ignore executables on this fs */
+ #define FS_RENAME_DOES_D_MOVE	32768	/* FS will handle d_move() during rename() internally. */
+ 	struct dentry *(*mount) (struct file_system_type *, int,
+ 		       const char *, void *);
+@@ -2810,4 +2811,6 @@ static inline bool dir_relax(struct inod
+ 	return !IS_DEADDIR(inode);
+ }
+ 
++extern bool path_noexec(const struct path *path);
++
+ #endif /* _LINUX_FS_H */
+--- a/kernel/sys.c
++++ b/kernel/sys.c
+@@ -1646,8 +1646,7 @@ static int prctl_set_mm_exe_file(struct
+ 	 * overall picture.
+ 	 */
+ 	err = -EACCES;
+-	if (!S_ISREG(inode->i_mode)	||
+-	    exe.file->f_path.mnt->mnt_flags & MNT_NOEXEC)
++	if (!S_ISREG(inode->i_mode) || path_noexec(&exe.file->f_path))
+ 		goto exit;
+ 
+ 	err = inode_permission(inode, MAY_EXEC);
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -1250,7 +1250,7 @@ unsigned long do_mmap_pgoff(struct file
+ 	 *  mounted, in which case we dont add PROT_EXEC.)
+ 	 */
+ 	if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
+-		if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
++		if (!(file && path_noexec(&file->f_path)))
+ 			prot |= PROT_EXEC;
+ 
+ 	if (!len)
+@@ -1322,7 +1322,7 @@ unsigned long do_mmap_pgoff(struct file
+ 		case MAP_PRIVATE:
+ 			if (!(file->f_mode & FMODE_READ))
+ 				return -EACCES;
+-			if (file->f_path.mnt->mnt_flags & MNT_NOEXEC) {
++			if (path_noexec(&file->f_path)) {
+ 				if (vm_flags & VM_EXEC)
+ 					return -EPERM;
+ 				vm_flags &= ~VM_MAYEXEC;
+--- a/mm/nommu.c
++++ b/mm/nommu.c
+@@ -1043,7 +1043,7 @@ static int validate_mmap_request(struct
+ 
+ 		/* handle executable mappings and implied executable
+ 		 * mappings */
+-		if (file->f_path.mnt->mnt_flags & MNT_NOEXEC) {
++		if (path_noexec(&file->f_path)) {
+ 			if (prot & PROT_EXEC)
+ 				return -EPERM;
+ 		} else if ((prot & PROT_READ) && !(prot & PROT_EXEC)) {
+--- a/security/security.c
++++ b/security/security.c
+@@ -737,7 +737,7 @@ static inline unsigned long mmap_prot(st
+ 	 * ditto if it's not on noexec mount, except that on !MMU we need
+ 	 * BDI_CAP_EXEC_MMAP (== VM_MAYEXEC) in this case
+ 	 */
+-	if (!(file->f_path.mnt->mnt_flags & MNT_NOEXEC)) {
++	if (!path_noexec(&file->f_path)) {
+ #ifndef CONFIG_MMU
+ 		unsigned long caps = 0;
+ 		struct address_space *mapping = file->f_mapping;
diff --git a/debian/patches/series b/debian/patches/series
index 143f7b0..7fb6f16 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -707,6 +707,7 @@ bugfix/all/irda-fix-lockdep-annotations-in-hashbin_delete.patch
 bugfix/all/timer-restrict-timer_stats-to-initial-pid-namespace.patch
 bugfix/all/mbcache-reschedule-before-restarting-iteration-in-mb_cache_entry_alloc.patch
 bugfix/all/mnt-add-a-per-mount-namespace-limit-on-the-number-of.patch
+bugfix/all/vfs-commit-to-never-having-exectuables-on-proc-and-s.patch
 
 # Fix ABI changes
 debian/of-fix-abi-changes.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/kernel/linux.git



More information about the Kernel-svn-changes mailing list