]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 26 Aug 2018 06:17:38 +0000 (08:17 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 26 Aug 2018 06:17:38 +0000 (08:17 +0200)
added patches:
ovl-do-d_type-check-only-if-work-dir-creation-was-successful.patch
ovl-ensure-upper-filesystem-supports-d_type.patch
ovl-warn-instead-of-error-if-d_type-is-not-supported.patch
x86-mm-fix-use-after-free-of-ldt_struct.patch

queue-4.4/ovl-do-d_type-check-only-if-work-dir-creation-was-successful.patch [new file with mode: 0644]
queue-4.4/ovl-ensure-upper-filesystem-supports-d_type.patch [new file with mode: 0644]
queue-4.4/ovl-warn-instead-of-error-if-d_type-is-not-supported.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/x86-mm-fix-use-after-free-of-ldt_struct.patch [new file with mode: 0644]

diff --git a/queue-4.4/ovl-do-d_type-check-only-if-work-dir-creation-was-successful.patch b/queue-4.4/ovl-do-d_type-check-only-if-work-dir-creation-was-successful.patch
new file mode 100644 (file)
index 0000000..62cfa1f
--- /dev/null
@@ -0,0 +1,55 @@
+From 21765194cecf2e4514ad75244df459f188140a0f Mon Sep 17 00:00:00 2001
+From: Vivek Goyal <vgoyal@redhat.com>
+Date: Fri, 20 May 2016 09:04:26 -0400
+Subject: ovl: Do d_type check only if work dir creation was successful
+
+From: Vivek Goyal <vgoyal@redhat.com>
+
+commit 21765194cecf2e4514ad75244df459f188140a0f upstream.
+
+d_type check requires successful creation of workdir as iterates
+through work dir and expects work dir to be present in it. If that's
+not the case, this check will always return d_type not supported even
+if underlying filesystem might be supporting it.
+
+So don't do this check if work dir creation failed in previous step.
+
+Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: SZ Lin (林上智) <sz.lin@moxa.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/overlayfs/super.c |   19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -1058,16 +1058,19 @@ static int ovl_fill_super(struct super_b
+               /*
+                * Upper should support d_type, else whiteouts are visible.
+                * Given workdir and upper are on same fs, we can do
+-               * iterate_dir() on workdir.
++               * iterate_dir() on workdir. This check requires successful
++               * creation of workdir in previous step.
+                */
+-              err = ovl_check_d_type_supported(&workpath);
+-              if (err < 0)
+-                      goto out_put_workdir;
++              if (ufs->workdir) {
++                      err = ovl_check_d_type_supported(&workpath);
++                      if (err < 0)
++                              goto out_put_workdir;
+-              if (!err) {
+-                      pr_err("overlayfs: upper fs needs to support d_type.\n");
+-                      err = -EINVAL;
+-                      goto out_put_workdir;
++                      if (!err) {
++                              pr_err("overlayfs: upper fs needs to support d_type.\n");
++                              err = -EINVAL;
++                              goto out_put_workdir;
++                      }
+               }
+       }
diff --git a/queue-4.4/ovl-ensure-upper-filesystem-supports-d_type.patch b/queue-4.4/ovl-ensure-upper-filesystem-supports-d_type.patch
new file mode 100644 (file)
index 0000000..ea5c039
--- /dev/null
@@ -0,0 +1,116 @@
+From 45aebeaf4f67468f76bedf62923a576a519a9b68 Mon Sep 17 00:00:00 2001
+From: Vivek Goyal <vgoyal@redhat.com>
+Date: Mon, 22 Feb 2016 09:28:34 -0500
+Subject: ovl: Ensure upper filesystem supports d_type
+
+From: Vivek Goyal <vgoyal@redhat.com>
+
+commit 45aebeaf4f67468f76bedf62923a576a519a9b68 upstream.
+
+In some instances xfs has been created with ftype=0 and there if a file
+on lower fs is removed, overlay leaves a whiteout in upper fs but that
+whiteout does not get filtered out and is visible to overlayfs users.
+
+And reason it does not get filtered out because upper filesystem does
+not report file type of whiteout as DT_CHR during iterate_dir().
+
+So it seems to be a requirement that upper filesystem support d_type for
+overlayfs to work properly. Do this check during mount and fail if d_type
+is not supported.
+
+Suggested-by: Dave Chinner <dchinner@redhat.com>
+Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: SZ Lin (林上智) <sz.lin@moxa.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/overlayfs/overlayfs.h |    1 +
+ fs/overlayfs/readdir.c   |   37 +++++++++++++++++++++++++++++++++++++
+ fs/overlayfs/super.c     |   15 +++++++++++++++
+ 3 files changed, 53 insertions(+)
+
+--- a/fs/overlayfs/overlayfs.h
++++ b/fs/overlayfs/overlayfs.h
+@@ -163,6 +163,7 @@ extern const struct file_operations ovl_
+ int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list);
+ void ovl_cleanup_whiteouts(struct dentry *upper, struct list_head *list);
+ void ovl_cache_free(struct list_head *list);
++int ovl_check_d_type_supported(struct path *realpath);
+ /* inode.c */
+ int ovl_setattr(struct dentry *dentry, struct iattr *attr);
+--- a/fs/overlayfs/readdir.c
++++ b/fs/overlayfs/readdir.c
+@@ -43,6 +43,7 @@ struct ovl_readdir_data {
+       struct ovl_cache_entry *first_maybe_whiteout;
+       int count;
+       int err;
++      bool d_type_supported;
+ };
+ struct ovl_dir_file {
+@@ -581,3 +582,39 @@ void ovl_cleanup_whiteouts(struct dentry
+       }
+       mutex_unlock(&upper->d_inode->i_mutex);
+ }
++
++static int ovl_check_d_type(struct dir_context *ctx, const char *name,
++                        int namelen, loff_t offset, u64 ino,
++                        unsigned int d_type)
++{
++      struct ovl_readdir_data *rdd =
++              container_of(ctx, struct ovl_readdir_data, ctx);
++
++      /* Even if d_type is not supported, DT_DIR is returned for . and .. */
++      if (!strncmp(name, ".", namelen) || !strncmp(name, "..", namelen))
++              return 0;
++
++      if (d_type != DT_UNKNOWN)
++              rdd->d_type_supported = true;
++
++      return 0;
++}
++
++/*
++ * Returns 1 if d_type is supported, 0 not supported/unknown. Negative values
++ * if error is encountered.
++ */
++int ovl_check_d_type_supported(struct path *realpath)
++{
++      int err;
++      struct ovl_readdir_data rdd = {
++              .ctx.actor = ovl_check_d_type,
++              .d_type_supported = false,
++      };
++
++      err = ovl_dir_read(realpath, &rdd);
++      if (err)
++              return err;
++
++      return rdd.d_type_supported;
++}
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -1054,6 +1054,21 @@ static int ovl_fill_super(struct super_b
+                       sb->s_flags |= MS_RDONLY;
+                       ufs->workdir = NULL;
+               }
++
++              /*
++               * Upper should support d_type, else whiteouts are visible.
++               * Given workdir and upper are on same fs, we can do
++               * iterate_dir() on workdir.
++               */
++              err = ovl_check_d_type_supported(&workpath);
++              if (err < 0)
++                      goto out_put_workdir;
++
++              if (!err) {
++                      pr_err("overlayfs: upper fs needs to support d_type.\n");
++                      err = -EINVAL;
++                      goto out_put_workdir;
++              }
+       }
+       err = -ENOMEM;
diff --git a/queue-4.4/ovl-warn-instead-of-error-if-d_type-is-not-supported.patch b/queue-4.4/ovl-warn-instead-of-error-if-d_type-is-not-supported.patch
new file mode 100644 (file)
index 0000000..2139c63
--- /dev/null
@@ -0,0 +1,56 @@
+From e7c0b5991dd1be7b6f6dc2b54a15a0f47b64b007 Mon Sep 17 00:00:00 2001
+From: Vivek Goyal <vgoyal@redhat.com>
+Date: Fri, 1 Jul 2016 10:02:44 -0400
+Subject: ovl: warn instead of error if d_type is not supported
+
+From: Vivek Goyal <vgoyal@redhat.com>
+
+commit e7c0b5991dd1be7b6f6dc2b54a15a0f47b64b007 upstream.
+
+overlay needs underlying fs to support d_type. Recently I put in a
+patch in to detect this condition and started failing mount if
+underlying fs did not support d_type.
+
+But this breaks existing configurations over kernel upgrade. Those who
+are running docker (partially broken configuration) with xfs not
+supporting d_type, are surprised that after kernel upgrade docker does
+not run anymore.
+
+https://github.com/docker/docker/issues/22937#issuecomment-229881315
+
+So instead of erroring out, detect broken configuration and warn
+about it. This should allow existing docker setups to continue
+working after kernel upgrade.
+
+Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Fixes: 45aebeaf4f67 ("ovl: Ensure upper filesystem supports d_type")
+Cc: <stable@vger.kernel.org> 4.6
+Signed-off-by: SZ Lin (林上智) <sz.lin@moxa.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/overlayfs/super.c |   12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -1066,11 +1066,13 @@ static int ovl_fill_super(struct super_b
+                       if (err < 0)
+                               goto out_put_workdir;
+-                      if (!err) {
+-                              pr_err("overlayfs: upper fs needs to support d_type.\n");
+-                              err = -EINVAL;
+-                              goto out_put_workdir;
+-                      }
++                      /*
++                       * We allowed this configuration and don't want to
++                       * break users over kernel upgrade. So warn instead
++                       * of erroring out.
++                       */
++                      if (!err)
++                              pr_warn("overlayfs: upper fs needs to support d_type.\n");
+               }
+       }
index 9f0b713081ffc0ecd2f5c0677be4c3823471bc96..0d93f562464298d65be44c45287f2be4364ac996 100644 (file)
@@ -1 +1,5 @@
 x86-mm-pat-fix-l1tf-stable-backport-for-cpa.patch
+x86-mm-fix-use-after-free-of-ldt_struct.patch
+ovl-ensure-upper-filesystem-supports-d_type.patch
+ovl-do-d_type-check-only-if-work-dir-creation-was-successful.patch
+ovl-warn-instead-of-error-if-d_type-is-not-supported.patch
diff --git a/queue-4.4/x86-mm-fix-use-after-free-of-ldt_struct.patch b/queue-4.4/x86-mm-fix-use-after-free-of-ldt_struct.patch
new file mode 100644 (file)
index 0000000..3c5d48c
--- /dev/null
@@ -0,0 +1,174 @@
+From ccd5b3235180eef3cfec337df1c8554ab151b5cc Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Thu, 24 Aug 2017 10:50:29 -0700
+Subject: x86/mm: Fix use-after-free of ldt_struct
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit ccd5b3235180eef3cfec337df1c8554ab151b5cc upstream.
+
+The following commit:
+
+  39a0526fb3f7 ("x86/mm: Factor out LDT init from context init")
+
+renamed init_new_context() to init_new_context_ldt() and added a new
+init_new_context() which calls init_new_context_ldt().  However, the
+error code of init_new_context_ldt() was ignored.  Consequently, if a
+memory allocation in alloc_ldt_struct() failed during a fork(), the
+->context.ldt of the new task remained the same as that of the old task
+(due to the memcpy() in dup_mm()).  ldt_struct's are not intended to be
+shared, so a use-after-free occurred after one task exited.
+
+Fix the bug by making init_new_context() pass through the error code of
+init_new_context_ldt().
+
+This bug was found by syzkaller, which encountered the following splat:
+
+    BUG: KASAN: use-after-free in free_ldt_struct.part.2+0x10a/0x150 arch/x86/kernel/ldt.c:116
+    Read of size 4 at addr ffff88006d2cb7c8 by task kworker/u9:0/3710
+
+    CPU: 1 PID: 3710 Comm: kworker/u9:0 Not tainted 4.13.0-rc4-next-20170811 #2
+    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
+    Call Trace:
+     __dump_stack lib/dump_stack.c:16 [inline]
+     dump_stack+0x194/0x257 lib/dump_stack.c:52
+     print_address_description+0x73/0x250 mm/kasan/report.c:252
+     kasan_report_error mm/kasan/report.c:351 [inline]
+     kasan_report+0x24e/0x340 mm/kasan/report.c:409
+     __asan_report_load4_noabort+0x14/0x20 mm/kasan/report.c:429
+     free_ldt_struct.part.2+0x10a/0x150 arch/x86/kernel/ldt.c:116
+     free_ldt_struct arch/x86/kernel/ldt.c:173 [inline]
+     destroy_context_ldt+0x60/0x80 arch/x86/kernel/ldt.c:171
+     destroy_context arch/x86/include/asm/mmu_context.h:157 [inline]
+     __mmdrop+0xe9/0x530 kernel/fork.c:889
+     mmdrop include/linux/sched/mm.h:42 [inline]
+     exec_mmap fs/exec.c:1061 [inline]
+     flush_old_exec+0x173c/0x1ff0 fs/exec.c:1291
+     load_elf_binary+0x81f/0x4ba0 fs/binfmt_elf.c:855
+     search_binary_handler+0x142/0x6b0 fs/exec.c:1652
+     exec_binprm fs/exec.c:1694 [inline]
+     do_execveat_common.isra.33+0x1746/0x22e0 fs/exec.c:1816
+     do_execve+0x31/0x40 fs/exec.c:1860
+     call_usermodehelper_exec_async+0x457/0x8f0 kernel/umh.c:100
+     ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431
+
+    Allocated by task 3700:
+     save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59
+     save_stack+0x43/0xd0 mm/kasan/kasan.c:447
+     set_track mm/kasan/kasan.c:459 [inline]
+     kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:551
+     kmem_cache_alloc_trace+0x136/0x750 mm/slab.c:3627
+     kmalloc include/linux/slab.h:493 [inline]
+     alloc_ldt_struct+0x52/0x140 arch/x86/kernel/ldt.c:67
+     write_ldt+0x7b7/0xab0 arch/x86/kernel/ldt.c:277
+     sys_modify_ldt+0x1ef/0x240 arch/x86/kernel/ldt.c:307
+     entry_SYSCALL_64_fastpath+0x1f/0xbe
+
+    Freed by task 3700:
+     save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59
+     save_stack+0x43/0xd0 mm/kasan/kasan.c:447
+     set_track mm/kasan/kasan.c:459 [inline]
+     kasan_slab_free+0x71/0xc0 mm/kasan/kasan.c:524
+     __cache_free mm/slab.c:3503 [inline]
+     kfree+0xca/0x250 mm/slab.c:3820
+     free_ldt_struct.part.2+0xdd/0x150 arch/x86/kernel/ldt.c:121
+     free_ldt_struct arch/x86/kernel/ldt.c:173 [inline]
+     destroy_context_ldt+0x60/0x80 arch/x86/kernel/ldt.c:171
+     destroy_context arch/x86/include/asm/mmu_context.h:157 [inline]
+     __mmdrop+0xe9/0x530 kernel/fork.c:889
+     mmdrop include/linux/sched/mm.h:42 [inline]
+     __mmput kernel/fork.c:916 [inline]
+     mmput+0x541/0x6e0 kernel/fork.c:927
+     copy_process.part.36+0x22e1/0x4af0 kernel/fork.c:1931
+     copy_process kernel/fork.c:1546 [inline]
+     _do_fork+0x1ef/0xfb0 kernel/fork.c:2025
+     SYSC_clone kernel/fork.c:2135 [inline]
+     SyS_clone+0x37/0x50 kernel/fork.c:2129
+     do_syscall_64+0x26c/0x8c0 arch/x86/entry/common.c:287
+     return_from_SYSCALL_64+0x0/0x7a
+
+Here is a C reproducer:
+
+    #include <asm/ldt.h>
+    #include <pthread.h>
+    #include <signal.h>
+    #include <stdlib.h>
+    #include <sys/syscall.h>
+    #include <sys/wait.h>
+    #include <unistd.h>
+
+    static void *fork_thread(void *_arg)
+    {
+        fork();
+    }
+
+    int main(void)
+    {
+        struct user_desc desc = { .entry_number = 8191 };
+
+        syscall(__NR_modify_ldt, 1, &desc, sizeof(desc));
+
+        for (;;) {
+            if (fork() == 0) {
+                pthread_t t;
+
+                srand(getpid());
+                pthread_create(&t, NULL, fork_thread, NULL);
+                usleep(rand() % 10000);
+                syscall(__NR_exit_group, 0);
+            }
+            wait(NULL);
+        }
+    }
+
+Note: the reproducer takes advantage of the fact that alloc_ldt_struct()
+may use vmalloc() to allocate a large ->entries array, and after
+commit:
+
+  5d17a73a2ebe ("vmalloc: back off when the current task is killed")
+
+it is possible for userspace to fail a task's vmalloc() by
+sending a fatal signal, e.g. via exit_group().  It would be more
+difficult to reproduce this bug on kernels without that commit.
+
+This bug only affected kernels with CONFIG_MODIFY_LDT_SYSCALL=y.
+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: <stable@vger.kernel.org> [v4.6+]
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Andy Lutomirski <luto@amacapital.net>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Brian Gerst <brgerst@gmail.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Denys Vlasenko <dvlasenk@redhat.com>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: linux-mm@kvack.org
+Fixes: 39a0526fb3f7 ("x86/mm: Factor out LDT init from context init")
+Link: http://lkml.kernel.org/r/20170824175029.76040-1-ebiggers3@gmail.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/mmu_context.h |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/arch/x86/include/asm/mmu_context.h
++++ b/arch/x86/include/asm/mmu_context.h
+@@ -109,8 +109,7 @@ static inline int init_new_context(struc
+                                  struct mm_struct *mm)
+ {
+       mm->context.ctx_id = atomic64_inc_return(&last_mm_ctx_id);
+-      init_new_context_ldt(tsk, mm);
+-      return 0;
++      return init_new_context_ldt(tsk, mm);
+ }
+ static inline void destroy_context(struct mm_struct *mm)
+ {