From: Greg Kroah-Hartman Date: Sun, 22 Apr 2018 10:05:21 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v3.18.106~21 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1f3ca0ce1190a6582585571bf0652e92f95ede11;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: autofs-mount-point-create-should-honour-passed-in-mode.patch don-t-leak-mnt_internal-away-from-internal-mounts.patch hypfs_kill_super-deal-with-failed-allocations.patch jffs2_kill_sb-deal-with-failed-allocations.patch mm-allow-gfp_-fs-io-for-page_cache_read-page-cache-allocation.patch mm-filemap.c-fix-null-pointer-in-page_cache_tree_insert.patch rpc_pipefs-fix-double-dput.patch --- diff --git a/queue-4.4/autofs-mount-point-create-should-honour-passed-in-mode.patch b/queue-4.4/autofs-mount-point-create-should-honour-passed-in-mode.patch new file mode 100644 index 00000000000..092cbb1fb0d --- /dev/null +++ b/queue-4.4/autofs-mount-point-create-should-honour-passed-in-mode.patch @@ -0,0 +1,40 @@ +From 1e6306652ba18723015d1b4967fe9de55f042499 Mon Sep 17 00:00:00 2001 +From: Ian Kent +Date: Fri, 20 Apr 2018 14:55:59 -0700 +Subject: autofs: mount point create should honour passed in mode + +From: Ian Kent + +commit 1e6306652ba18723015d1b4967fe9de55f042499 upstream. + +The autofs file system mkdir inode operation blindly sets the created +directory mode to S_IFDIR | 0555, ingoring the passed in mode, which can +cause selinux dac_override denials. + +But the function also checks if the caller is the daemon (as no-one else +should be able to do anything here) so there's no point in not honouring +the passed in mode, allowing the daemon to set appropriate mode when +required. + +Link: http://lkml.kernel.org/r/152361593601.8051.14014139124905996173.stgit@pluto.themaw.net +Signed-off-by: Ian Kent +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/autofs4/root.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/autofs4/root.c ++++ b/fs/autofs4/root.c +@@ -746,7 +746,7 @@ static int autofs4_dir_mkdir(struct inod + + autofs4_del_active(dentry); + +- inode = autofs4_get_inode(dir->i_sb, S_IFDIR | 0555); ++ inode = autofs4_get_inode(dir->i_sb, S_IFDIR | mode); + if (!inode) + return -ENOMEM; + d_add(dentry, inode); diff --git a/queue-4.4/don-t-leak-mnt_internal-away-from-internal-mounts.patch b/queue-4.4/don-t-leak-mnt_internal-away-from-internal-mounts.patch new file mode 100644 index 00000000000..34290154b0a --- /dev/null +++ b/queue-4.4/don-t-leak-mnt_internal-away-from-internal-mounts.patch @@ -0,0 +1,37 @@ +From 16a34adb9392b2fe4195267475ab5b472e55292c Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Thu, 19 Apr 2018 22:03:08 -0400 +Subject: Don't leak MNT_INTERNAL away from internal mounts + +From: Al Viro + +commit 16a34adb9392b2fe4195267475ab5b472e55292c upstream. + +We want it only for the stuff created by SB_KERNMOUNT mounts, *not* for +their copies. As it is, creating a deep stack of bindings of /proc/*/ns/* +somewhere in a new namespace and exiting yields a stack overflow. + +Cc: stable@kernel.org +Reported-by: Alexander Aring +Bisected-by: Kirill Tkhai +Tested-by: Kirill Tkhai +Tested-by: Alexander Aring +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/namespace.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -1018,7 +1018,8 @@ static struct mount *clone_mnt(struct mo + goto out_free; + } + +- mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~(MNT_WRITE_HOLD|MNT_MARKED); ++ mnt->mnt.mnt_flags = old->mnt.mnt_flags; ++ mnt->mnt.mnt_flags &= ~(MNT_WRITE_HOLD|MNT_MARKED|MNT_INTERNAL); + /* Don't allow unprivileged users to change mount flags */ + if (flag & CL_UNPRIVILEGED) { + mnt->mnt.mnt_flags |= MNT_LOCK_ATIME; diff --git a/queue-4.4/hypfs_kill_super-deal-with-failed-allocations.patch b/queue-4.4/hypfs_kill_super-deal-with-failed-allocations.patch new file mode 100644 index 00000000000..8e330b23836 --- /dev/null +++ b/queue-4.4/hypfs_kill_super-deal-with-failed-allocations.patch @@ -0,0 +1,31 @@ +From a24cd490739586a7d2da3549a1844e1d7c4f4fc4 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Mon, 2 Apr 2018 23:50:31 -0400 +Subject: hypfs_kill_super(): deal with failed allocations + +From: Al Viro + +commit a24cd490739586a7d2da3549a1844e1d7c4f4fc4 upstream. + +hypfs_fill_super() might fail to allocate sbi; hypfs_kill_super() +should not oops on that. + +Cc: stable@vger.kernel.org +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/hypfs/inode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/s390/hypfs/inode.c ++++ b/arch/s390/hypfs/inode.c +@@ -318,7 +318,7 @@ static void hypfs_kill_super(struct supe + + if (sb->s_root) + hypfs_delete_tree(sb->s_root); +- if (sb_info->update_file) ++ if (sb_info && sb_info->update_file) + hypfs_remove(sb_info->update_file); + kfree(sb->s_fs_info); + sb->s_fs_info = NULL; diff --git a/queue-4.4/jffs2_kill_sb-deal-with-failed-allocations.patch b/queue-4.4/jffs2_kill_sb-deal-with-failed-allocations.patch new file mode 100644 index 00000000000..9fdb42400f8 --- /dev/null +++ b/queue-4.4/jffs2_kill_sb-deal-with-failed-allocations.patch @@ -0,0 +1,31 @@ +From c66b23c2840446a82c389e4cb1a12eb2a71fa2e4 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Mon, 2 Apr 2018 23:56:44 -0400 +Subject: jffs2_kill_sb(): deal with failed allocations + +From: Al Viro + +commit c66b23c2840446a82c389e4cb1a12eb2a71fa2e4 upstream. + +jffs2_fill_super() might fail to allocate jffs2_sb_info; +jffs2_kill_sb() must survive that. + +Cc: stable@kernel.org +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/jffs2/super.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/jffs2/super.c ++++ b/fs/jffs2/super.c +@@ -345,7 +345,7 @@ static void jffs2_put_super (struct supe + static void jffs2_kill_sb(struct super_block *sb) + { + struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); +- if (!(sb->s_flags & MS_RDONLY)) ++ if (c && !(sb->s_flags & MS_RDONLY)) + jffs2_stop_garbage_collect_thread(c); + kill_mtd_super(sb); + kfree(c); diff --git a/queue-4.4/mm-allow-gfp_-fs-io-for-page_cache_read-page-cache-allocation.patch b/queue-4.4/mm-allow-gfp_-fs-io-for-page_cache_read-page-cache-allocation.patch new file mode 100644 index 00000000000..d33bc3114ea --- /dev/null +++ b/queue-4.4/mm-allow-gfp_-fs-io-for-page_cache_read-page-cache-allocation.patch @@ -0,0 +1,162 @@ +From c20cd45eb01748f0fba77a504f956b000df4ea73 Mon Sep 17 00:00:00 2001 +From: Michal Hocko +Date: Thu, 14 Jan 2016 15:20:12 -0800 +Subject: mm: allow GFP_{FS,IO} for page_cache_read page cache allocation + +From: Michal Hocko + +commit c20cd45eb01748f0fba77a504f956b000df4ea73 upstream. + +page_cache_read has been historically using page_cache_alloc_cold to +allocate a new page. This means that mapping_gfp_mask is used as the +base for the gfp_mask. Many filesystems are setting this mask to +GFP_NOFS to prevent from fs recursion issues. page_cache_read is called +from the vm_operations_struct::fault() context during the page fault. +This context doesn't need the reclaim protection normally. + +ceph and ocfs2 which call filemap_fault from their fault handlers seem +to be OK because they are not taking any fs lock before invoking generic +implementation. xfs which takes XFS_MMAPLOCK_SHARED is safe from the +reclaim recursion POV because this lock serializes truncate and punch +hole with the page faults and it doesn't get involved in the reclaim. + +There is simply no reason to deliberately use a weaker allocation +context when a __GFP_FS | __GFP_IO can be used. The GFP_NOFS protection +might be even harmful. There is a push to fail GFP_NOFS allocations +rather than loop within allocator indefinitely with a very limited +reclaim ability. Once we start failing those requests the OOM killer +might be triggered prematurely because the page cache allocation failure +is propagated up the page fault path and end up in +pagefault_out_of_memory. + +We cannot play with mapping_gfp_mask directly because that would be racy +wrt. parallel page faults and it might interfere with other users who +really rely on NOFS semantic from the stored gfp_mask. The mask is also +inode proper so it would even be a layering violation. What we can do +instead is to push the gfp_mask into struct vm_fault and allow fs layer +to overwrite it should the callback need to be called with a different +allocation context. + +Initialize the default to (mapping_gfp_mask | __GFP_FS | __GFP_IO) +because this should be safe from the page fault path normally. Why do +we care about mapping_gfp_mask at all then? Because this doesn't hold +only reclaim protection flags but it also might contain zone and +movability restrictions (GFP_DMA32, __GFP_MOVABLE and others) so we have +to respect those. + +Signed-off-by: Michal Hocko +Reported-by: Tetsuo Handa +Acked-by: Jan Kara +Acked-by: Vlastimil Babka +Cc: Tetsuo Handa +Cc: Mel Gorman +Cc: Dave Chinner +Cc: Mark Fasheh +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/mm.h | 4 ++++ + mm/filemap.c | 9 ++++----- + mm/memory.c | 17 +++++++++++++++++ + 3 files changed, 25 insertions(+), 5 deletions(-) + +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -225,10 +225,14 @@ extern pgprot_t protection_map[16]; + * ->fault function. The vma's ->fault is responsible for returning a bitmask + * of VM_FAULT_xxx flags that give details about how the fault was handled. + * ++ * MM layer fills up gfp_mask for page allocations but fault handler might ++ * alter it if its implementation requires a different allocation context. ++ * + * pgoff should be used in favour of virtual_address, if possible. + */ + struct vm_fault { + unsigned int flags; /* FAULT_FLAG_xxx flags */ ++ gfp_t gfp_mask; /* gfp mask to be used for allocations */ + pgoff_t pgoff; /* Logical page offset based on vma */ + void __user *virtual_address; /* Faulting virtual address */ + +--- a/mm/filemap.c ++++ b/mm/filemap.c +@@ -1827,19 +1827,18 @@ EXPORT_SYMBOL(generic_file_read_iter); + * This adds the requested page to the page cache if it isn't already there, + * and schedules an I/O to read in its contents from disk. + */ +-static int page_cache_read(struct file *file, pgoff_t offset) ++static int page_cache_read(struct file *file, pgoff_t offset, gfp_t gfp_mask) + { + struct address_space *mapping = file->f_mapping; + struct page *page; + int ret; + + do { +- page = page_cache_alloc_cold(mapping); ++ page = __page_cache_alloc(gfp_mask|__GFP_COLD); + if (!page) + return -ENOMEM; + +- ret = add_to_page_cache_lru(page, mapping, offset, +- mapping_gfp_constraint(mapping, GFP_KERNEL)); ++ ret = add_to_page_cache_lru(page, mapping, offset, gfp_mask & GFP_KERNEL); + if (ret == 0) + ret = mapping->a_ops->readpage(file, page); + else if (ret == -EEXIST) +@@ -2020,7 +2019,7 @@ no_cached_page: + * We're only likely to ever get here if MADV_RANDOM is in + * effect. + */ +- error = page_cache_read(file, offset); ++ error = page_cache_read(file, offset, vmf->gfp_mask); + + /* + * The page we want has now been added to the page cache. +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -1990,6 +1990,20 @@ static inline void cow_user_page(struct + copy_user_highpage(dst, src, va, vma); + } + ++static gfp_t __get_fault_gfp_mask(struct vm_area_struct *vma) ++{ ++ struct file *vm_file = vma->vm_file; ++ ++ if (vm_file) ++ return mapping_gfp_mask(vm_file->f_mapping) | __GFP_FS | __GFP_IO; ++ ++ /* ++ * Special mappings (e.g. VDSO) do not have any file so fake ++ * a default GFP_KERNEL for them. ++ */ ++ return GFP_KERNEL; ++} ++ + /* + * Notify the address space that the page is about to become writable so that + * it can prohibit this or wait for the page to get into an appropriate state. +@@ -2005,6 +2019,7 @@ static int do_page_mkwrite(struct vm_are + vmf.virtual_address = (void __user *)(address & PAGE_MASK); + vmf.pgoff = page->index; + vmf.flags = FAULT_FLAG_WRITE|FAULT_FLAG_MKWRITE; ++ vmf.gfp_mask = __get_fault_gfp_mask(vma); + vmf.page = page; + vmf.cow_page = NULL; + +@@ -2770,6 +2785,7 @@ static int __do_fault(struct vm_area_str + vmf.pgoff = pgoff; + vmf.flags = flags; + vmf.page = NULL; ++ vmf.gfp_mask = __get_fault_gfp_mask(vma); + vmf.cow_page = cow_page; + + ret = vma->vm_ops->fault(vma, &vmf); +@@ -2936,6 +2952,7 @@ static void do_fault_around(struct vm_ar + vmf.pgoff = pgoff; + vmf.max_pgoff = max_pgoff; + vmf.flags = flags; ++ vmf.gfp_mask = __get_fault_gfp_mask(vma); + vma->vm_ops->map_pages(vma, &vmf); + } + diff --git a/queue-4.4/mm-filemap.c-fix-null-pointer-in-page_cache_tree_insert.patch b/queue-4.4/mm-filemap.c-fix-null-pointer-in-page_cache_tree_insert.patch new file mode 100644 index 00000000000..5dd5a515a95 --- /dev/null +++ b/queue-4.4/mm-filemap.c-fix-null-pointer-in-page_cache_tree_insert.patch @@ -0,0 +1,80 @@ +From abc1be13fd113ddef5e2d807a466286b864caed3 Mon Sep 17 00:00:00 2001 +From: Matthew Wilcox +Date: Fri, 20 Apr 2018 14:56:20 -0700 +Subject: mm/filemap.c: fix NULL pointer in page_cache_tree_insert() + +From: Matthew Wilcox + +commit abc1be13fd113ddef5e2d807a466286b864caed3 upstream. + +f2fs specifies the __GFP_ZERO flag for allocating some of its pages. +Unfortunately, the page cache also uses the mapping's GFP flags for +allocating radix tree nodes. It always masked off the __GFP_HIGHMEM +flag, and masks off __GFP_ZERO in some paths, but not all. That causes +radix tree nodes to be allocated with a NULL list_head, which causes +backtraces like: + + __list_del_entry+0x30/0xd0 + list_lru_del+0xac/0x1ac + page_cache_tree_insert+0xd8/0x110 + +The __GFP_DMA and __GFP_DMA32 flags would also be able to sneak through +if they are ever used. Fix them all by using GFP_RECLAIM_MASK at the +innermost location, and remove it from earlier in the callchain. + +Link: http://lkml.kernel.org/r/20180411060320.14458-2-willy@infradead.org +Fixes: 449dd6984d0e ("mm: keep page cache radix tree nodes in check") +Signed-off-by: Matthew Wilcox +Reported-by: Chris Fries +Debugged-by: Minchan Kim +Acked-by: Johannes Weiner +Acked-by: Michal Hocko +Reviewed-by: Jan Kara +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/filemap.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/mm/filemap.c ++++ b/mm/filemap.c +@@ -571,7 +571,7 @@ int replace_page_cache_page(struct page + VM_BUG_ON_PAGE(!PageLocked(new), new); + VM_BUG_ON_PAGE(new->mapping, new); + +- error = radix_tree_preload(gfp_mask & ~__GFP_HIGHMEM); ++ error = radix_tree_preload(gfp_mask & GFP_RECLAIM_MASK); + if (!error) { + struct address_space *mapping = old->mapping; + void (*freepage)(struct page *); +@@ -630,7 +630,7 @@ static int __add_to_page_cache_locked(st + return error; + } + +- error = radix_tree_maybe_preload(gfp_mask & ~__GFP_HIGHMEM); ++ error = radix_tree_maybe_preload(gfp_mask & GFP_RECLAIM_MASK); + if (error) { + if (!huge) + mem_cgroup_cancel_charge(page, memcg); +@@ -1192,8 +1192,7 @@ no_page: + if (fgp_flags & FGP_ACCESSED) + __SetPageReferenced(page); + +- err = add_to_page_cache_lru(page, mapping, offset, +- gfp_mask & GFP_RECLAIM_MASK); ++ err = add_to_page_cache_lru(page, mapping, offset, gfp_mask); + if (unlikely(err)) { + page_cache_release(page); + page = NULL; +@@ -1838,7 +1837,7 @@ static int page_cache_read(struct file * + if (!page) + return -ENOMEM; + +- ret = add_to_page_cache_lru(page, mapping, offset, gfp_mask & GFP_KERNEL); ++ ret = add_to_page_cache_lru(page, mapping, offset, gfp_mask); + if (ret == 0) + ret = mapping->a_ops->readpage(file, page); + else if (ret == -EEXIST) diff --git a/queue-4.4/rpc_pipefs-fix-double-dput.patch b/queue-4.4/rpc_pipefs-fix-double-dput.patch new file mode 100644 index 00000000000..93298569a77 --- /dev/null +++ b/queue-4.4/rpc_pipefs-fix-double-dput.patch @@ -0,0 +1,31 @@ +From 4a3877c4cedd95543f8726b0a98743ed8db0c0fb Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Tue, 3 Apr 2018 01:15:46 -0400 +Subject: rpc_pipefs: fix double-dput() + +From: Al Viro + +commit 4a3877c4cedd95543f8726b0a98743ed8db0c0fb upstream. + +if we ever hit rpc_gssd_dummy_depopulate() dentry passed to +it has refcount equal to 1. __rpc_rmpipe() drops it and +dput() done after that hits an already freed dentry. + +Cc: stable@kernel.org +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + net/sunrpc/rpc_pipe.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/sunrpc/rpc_pipe.c ++++ b/net/sunrpc/rpc_pipe.c +@@ -1375,6 +1375,7 @@ rpc_gssd_dummy_depopulate(struct dentry + struct dentry *clnt_dir = pipe_dentry->d_parent; + struct dentry *gssd_dir = clnt_dir->d_parent; + ++ dget(pipe_dentry); + __rpc_rmpipe(d_inode(clnt_dir), pipe_dentry); + __rpc_depopulate(clnt_dir, gssd_dummy_info_file, 0, 1); + __rpc_depopulate(gssd_dir, gssd_dummy_clnt_dir, 0, 1); diff --git a/queue-4.4/series b/queue-4.4/series index ad17e481b2a..81bcbb5f2cb 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -85,3 +85,10 @@ mips-memset.s-fix-return-of-__clear_user-from-lpartial_fixup.patch mips-memset.s-fix-clobber-of-v1-in-last_fixup.patch powerpc-eeh-fix-enabling-bridge-mmio-windows.patch powerpc-lib-fix-off-by-one-in-alternate-feature-patching.patch +jffs2_kill_sb-deal-with-failed-allocations.patch +hypfs_kill_super-deal-with-failed-allocations.patch +rpc_pipefs-fix-double-dput.patch +don-t-leak-mnt_internal-away-from-internal-mounts.patch +autofs-mount-point-create-should-honour-passed-in-mode.patch +mm-allow-gfp_-fs-io-for-page_cache_read-page-cache-allocation.patch +mm-filemap.c-fix-null-pointer-in-page_cache_tree_insert.patch