--- /dev/null
+From d0ffb805b729322626639336986bc83fc2e60871 Mon Sep 17 00:00:00 2001
+From: "H. Peter Anvin (Intel)" <hpa@zytor.com>
+Date: Mon, 22 Oct 2018 09:19:05 -0700
+Subject: arch/alpha, termios: implement BOTHER, IBSHIFT and termios2
+
+From: H. Peter Anvin (Intel) <hpa@zytor.com>
+
+commit d0ffb805b729322626639336986bc83fc2e60871 upstream.
+
+Alpha has had c_ispeed and c_ospeed, but still set speeds in c_cflags
+using arbitrary flags. Because BOTHER is not defined, the general
+Linux code doesn't allow setting arbitrary baud rates, and because
+CBAUDEX == 0, we can have an array overrun of the baud_rate[] table in
+drivers/tty/tty_baudrate.c if (c_cflags & CBAUD) == 037.
+
+Resolve both problems by #defining BOTHER to 037 on Alpha.
+
+However, userspace still needs to know if setting BOTHER is actually
+safe given legacy kernels (does anyone actually care about that on
+Alpha anymore?), so enable the TCGETS2/TCSETS*2 ioctls on Alpha, even
+though they use the same structure. Define struct termios2 just for
+compatibility; it is the exact same structure as struct termios. In a
+future patchset, this will be cleaned up so the uapi headers are
+usable from libc.
+
+Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
+Cc: Jiri Slaby <jslaby@suse.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Richard Henderson <rth@twiddle.net>
+Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
+Cc: Matt Turner <mattst88@gmail.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Kate Stewart <kstewart@linuxfoundation.org>
+Cc: Philippe Ombredanne <pombredanne@nexb.com>
+Cc: Eugene Syromiatnikov <esyr@redhat.com>
+Cc: <linux-alpha@vger.kernel.org>
+Cc: <linux-serial@vger.kernel.org>
+Cc: Johan Hovold <johan@kernel.org>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/alpha/include/asm/termios.h | 8 +++++++-
+ arch/alpha/include/uapi/asm/ioctls.h | 5 +++++
+ arch/alpha/include/uapi/asm/termbits.h | 17 +++++++++++++++++
+ 3 files changed, 29 insertions(+), 1 deletion(-)
+
+--- a/arch/alpha/include/asm/termios.h
++++ b/arch/alpha/include/asm/termios.h
+@@ -72,9 +72,15 @@
+ })
+
+ #define user_termios_to_kernel_termios(k, u) \
+- copy_from_user(k, u, sizeof(struct termios))
++ copy_from_user(k, u, sizeof(struct termios2))
+
+ #define kernel_termios_to_user_termios(u, k) \
++ copy_to_user(u, k, sizeof(struct termios2))
++
++#define user_termios_to_kernel_termios_1(k, u) \
++ copy_from_user(k, u, sizeof(struct termios))
++
++#define kernel_termios_to_user_termios_1(u, k) \
+ copy_to_user(u, k, sizeof(struct termios))
+
+ #endif /* _ALPHA_TERMIOS_H */
+--- a/arch/alpha/include/uapi/asm/ioctls.h
++++ b/arch/alpha/include/uapi/asm/ioctls.h
+@@ -31,6 +31,11 @@
+ #define TCXONC _IO('t', 30)
+ #define TCFLSH _IO('t', 31)
+
++#define TCGETS2 _IOR('T', 42, struct termios2)
++#define TCSETS2 _IOW('T', 43, struct termios2)
++#define TCSETSW2 _IOW('T', 44, struct termios2)
++#define TCSETSF2 _IOW('T', 45, struct termios2)
++
+ #define TIOCSWINSZ _IOW('t', 103, struct winsize)
+ #define TIOCGWINSZ _IOR('t', 104, struct winsize)
+ #define TIOCSTART _IO('t', 110) /* start output, like ^Q */
+--- a/arch/alpha/include/uapi/asm/termbits.h
++++ b/arch/alpha/include/uapi/asm/termbits.h
+@@ -25,6 +25,19 @@ struct termios {
+ speed_t c_ospeed; /* output speed */
+ };
+
++/* Alpha has identical termios and termios2 */
++
++struct termios2 {
++ tcflag_t c_iflag; /* input mode flags */
++ tcflag_t c_oflag; /* output mode flags */
++ tcflag_t c_cflag; /* control mode flags */
++ tcflag_t c_lflag; /* local mode flags */
++ cc_t c_cc[NCCS]; /* control characters */
++ cc_t c_line; /* line discipline (== c_cc[19]) */
++ speed_t c_ispeed; /* input speed */
++ speed_t c_ospeed; /* output speed */
++};
++
+ /* Alpha has matching termios and ktermios */
+
+ struct ktermios {
+@@ -147,6 +160,7 @@ struct ktermios {
+ #define B3000000 00034
+ #define B3500000 00035
+ #define B4000000 00036
++#define BOTHER 00037
+
+ #define CSIZE 00001400
+ #define CS5 00000000
+@@ -164,6 +178,9 @@ struct ktermios {
+ #define CMSPAR 010000000000 /* mark or space (stick) parity */
+ #define CRTSCTS 020000000000 /* flow control */
+
++#define CIBAUD 07600000
++#define IBSHIFT 16
++
+ /* c_lflag bits */
+ #define ISIG 0x00000080
+ #define ICANON 0x00000100
--- /dev/null
+From 506481b20e818db40b6198815904ecd2d6daee64 Mon Sep 17 00:00:00 2001
+From: Robbie Ko <robbieko@synology.com>
+Date: Tue, 30 Oct 2018 18:04:04 +0800
+Subject: Btrfs: fix cur_offset in the error case for nocow
+
+From: Robbie Ko <robbieko@synology.com>
+
+commit 506481b20e818db40b6198815904ecd2d6daee64 upstream.
+
+When the cow_file_range fails, the related resources are unlocked
+according to the range [start..end), so the unlock cannot be repeated in
+run_delalloc_nocow.
+
+In some cases (e.g. cur_offset <= end && cow_start != -1), cur_offset is
+not updated correctly, so move the cur_offset update before
+cow_file_range.
+
+ kernel BUG at mm/page-writeback.c:2663!
+ Internal error: Oops - BUG: 0 [#1] SMP
+ CPU: 3 PID: 31525 Comm: kworker/u8:7 Tainted: P O
+ Hardware name: Realtek_RTD1296 (DT)
+ Workqueue: writeback wb_workfn (flush-btrfs-1)
+ task: ffffffc076db3380 ti: ffffffc02e9ac000 task.ti: ffffffc02e9ac000
+ PC is at clear_page_dirty_for_io+0x1bc/0x1e8
+ LR is at clear_page_dirty_for_io+0x14/0x1e8
+ pc : [<ffffffc00033c91c>] lr : [<ffffffc00033c774>] pstate: 40000145
+ sp : ffffffc02e9af4f0
+ Process kworker/u8:7 (pid: 31525, stack limit = 0xffffffc02e9ac020)
+ Call trace:
+ [<ffffffc00033c91c>] clear_page_dirty_for_io+0x1bc/0x1e8
+ [<ffffffbffc514674>] extent_clear_unlock_delalloc+0x1e4/0x210 [btrfs]
+ [<ffffffbffc4fb168>] run_delalloc_nocow+0x3b8/0x948 [btrfs]
+ [<ffffffbffc4fb948>] run_delalloc_range+0x250/0x3a8 [btrfs]
+ [<ffffffbffc514c0c>] writepage_delalloc.isra.21+0xbc/0x1d8 [btrfs]
+ [<ffffffbffc516048>] __extent_writepage+0xe8/0x248 [btrfs]
+ [<ffffffbffc51630c>] extent_write_cache_pages.isra.17+0x164/0x378 [btrfs]
+ [<ffffffbffc5185a8>] extent_writepages+0x48/0x68 [btrfs]
+ [<ffffffbffc4f5828>] btrfs_writepages+0x20/0x30 [btrfs]
+ [<ffffffc00033d758>] do_writepages+0x30/0x88
+ [<ffffffc0003ba0f4>] __writeback_single_inode+0x34/0x198
+ [<ffffffc0003ba6c4>] writeback_sb_inodes+0x184/0x3c0
+ [<ffffffc0003ba96c>] __writeback_inodes_wb+0x6c/0xc0
+ [<ffffffc0003bac20>] wb_writeback+0x1b8/0x1c0
+ [<ffffffc0003bb0f0>] wb_workfn+0x150/0x250
+ [<ffffffc0002b0014>] process_one_work+0x1dc/0x388
+ [<ffffffc0002b02f0>] worker_thread+0x130/0x500
+ [<ffffffc0002b6344>] kthread+0x10c/0x110
+ [<ffffffc000284590>] ret_from_fork+0x10/0x40
+ Code: d503201f a9025bb5 a90363b7 f90023b9 (d4210000)
+
+CC: stable@vger.kernel.org # 4.4+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Robbie Ko <robbieko@synology.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/inode.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -1548,12 +1548,11 @@ out_check:
+ }
+ btrfs_release_path(path);
+
+- if (cur_offset <= end && cow_start == (u64)-1) {
++ if (cur_offset <= end && cow_start == (u64)-1)
+ cow_start = cur_offset;
+- cur_offset = end;
+- }
+
+ if (cow_start != (u64)-1) {
++ cur_offset = end;
+ ret = cow_file_range(inode, locked_page, cow_start, end, end,
+ page_started, nr_written, 1, NULL);
+ if (ret)
--- /dev/null
+From ac765f83f1397646c11092a032d4f62c3d478b81 Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Mon, 5 Nov 2018 11:14:17 +0000
+Subject: Btrfs: fix data corruption due to cloning of eof block
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit ac765f83f1397646c11092a032d4f62c3d478b81 upstream.
+
+We currently allow cloning a range from a file which includes the last
+block of the file even if the file's size is not aligned to the block
+size. This is fine and useful when the destination file has the same size,
+but when it does not and the range ends somewhere in the middle of the
+destination file, it leads to corruption because the bytes between the EOF
+and the end of the block have undefined data (when there is support for
+discard/trimming they have a value of 0x00).
+
+Example:
+
+ $ mkfs.btrfs -f /dev/sdb
+ $ mount /dev/sdb /mnt
+
+ $ export foo_size=$((256 * 1024 + 100))
+ $ xfs_io -f -c "pwrite -S 0x3c 0 $foo_size" /mnt/foo
+ $ xfs_io -f -c "pwrite -S 0xb5 0 1M" /mnt/bar
+
+ $ xfs_io -c "reflink /mnt/foo 0 512K $foo_size" /mnt/bar
+
+ $ od -A d -t x1 /mnt/bar
+ 0000000 b5 b5 b5 b5 b5 b5 b5 b5 b5 b5 b5 b5 b5 b5 b5 b5
+ *
+ 0524288 3c 3c 3c 3c 3c 3c 3c 3c 3c 3c 3c 3c 3c 3c 3c 3c
+ *
+ 0786528 3c 3c 3c 3c 00 00 00 00 00 00 00 00 00 00 00 00
+ 0786544 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ *
+ 0790528 b5 b5 b5 b5 b5 b5 b5 b5 b5 b5 b5 b5 b5 b5 b5 b5
+ *
+ 1048576
+
+The bytes in the range from 786532 (512Kb + 256Kb + 100 bytes) to 790527
+(512Kb + 256Kb + 4Kb - 1) got corrupted, having now a value of 0x00 instead
+of 0xb5.
+
+This is similar to the problem we had for deduplication that got recently
+fixed by commit de02b9f6bb65 ("Btrfs: fix data corruption when
+deduplicating between different files").
+
+Fix this by not allowing such operations to be performed and return the
+errno -EINVAL to user space. This is what XFS is doing as well at the VFS
+level. This change however now makes us return -EINVAL instead of
+-EOPNOTSUPP for cases where the source range maps to an inline extent and
+the destination range's end is smaller then the destination file's size,
+since the detection of inline extents is done during the actual process of
+dropping file extent items (at __btrfs_drop_extents()). Returning the
+-EINVAL error is done early on and solely based on the input parameters
+(offsets and length) and destination file's size. This makes us consistent
+with XFS and anyone else supporting cloning since this case is now checked
+at a higher level in the VFS and is where the -EINVAL will be returned
+from starting with kernel 4.20 (the VFS changed was introduced in 4.20-rc1
+by commit 07d19dc9fbe9 ("vfs: avoid problematic remapping requests into
+partial EOF block"). So this change is more geared towards stable kernels,
+as it's unlikely the new VFS checks get removed intentionally.
+
+A test case for fstests follows soon, as well as an update to filter
+existing tests that expect -EOPNOTSUPP to accept -EINVAL as well.
+
+CC: <stable@vger.kernel.org> # 4.4+
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/ioctl.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -3911,9 +3911,17 @@ static noinline int btrfs_clone_files(st
+ goto out_unlock;
+ if (len == 0)
+ olen = len = src->i_size - off;
+- /* if we extend to eof, continue to block boundary */
+- if (off + len == src->i_size)
++ /*
++ * If we extend to eof, continue to block boundary if and only if the
++ * destination end offset matches the destination file's size, otherwise
++ * we would be corrupting data by placing the eof block into the middle
++ * of a file.
++ */
++ if (off + len == src->i_size) {
++ if (!IS_ALIGNED(len, bs) && destoff + len < inode->i_size)
++ goto out_unlock;
+ len = ALIGN(src->i_size, bs) - off;
++ }
+
+ if (len == 0) {
+ ret = 0;
--- /dev/null
+From 35b69a420bfb56b7b74cb635ea903db05e357bec Mon Sep 17 00:00:00 2001
+From: Michael Kelley <mikelley@microsoft.com>
+Date: Sun, 4 Nov 2018 03:48:54 +0000
+Subject: clockevents/drivers/i8253: Add support for PIT shutdown quirk
+
+From: Michael Kelley <mikelley@microsoft.com>
+
+commit 35b69a420bfb56b7b74cb635ea903db05e357bec upstream.
+
+Add support for platforms where pit_shutdown() doesn't work because of a
+quirk in the PIT emulation. On these platforms setting the counter register
+to zero causes the PIT to start running again, negating the shutdown.
+
+Provide a global variable that controls whether the counter register is
+zero'ed, which platform specific code can override.
+
+Signed-off-by: Michael Kelley <mikelley@microsoft.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: "gregkh@linuxfoundation.org" <gregkh@linuxfoundation.org>
+Cc: "devel@linuxdriverproject.org" <devel@linuxdriverproject.org>
+Cc: "daniel.lezcano@linaro.org" <daniel.lezcano@linaro.org>
+Cc: "virtualization@lists.linux-foundation.org" <virtualization@lists.linux-foundation.org>
+Cc: "jgross@suse.com" <jgross@suse.com>
+Cc: "akataria@vmware.com" <akataria@vmware.com>
+Cc: "olaf@aepfle.de" <olaf@aepfle.de>
+Cc: "apw@canonical.com" <apw@canonical.com>
+Cc: vkuznets <vkuznets@redhat.com>
+Cc: "jasowang@redhat.com" <jasowang@redhat.com>
+Cc: "marcelo.cerri@canonical.com" <marcelo.cerri@canonical.com>
+Cc: KY Srinivasan <kys@microsoft.com>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/1541303219-11142-2-git-send-email-mikelley@microsoft.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clocksource/i8253.c | 14 ++++++++++++--
+ include/linux/i8253.h | 1 +
+ 2 files changed, 13 insertions(+), 2 deletions(-)
+
+--- a/drivers/clocksource/i8253.c
++++ b/drivers/clocksource/i8253.c
+@@ -19,6 +19,13 @@
+ DEFINE_RAW_SPINLOCK(i8253_lock);
+ EXPORT_SYMBOL(i8253_lock);
+
++/*
++ * Handle PIT quirk in pit_shutdown() where zeroing the counter register
++ * restarts the PIT, negating the shutdown. On platforms with the quirk,
++ * platform specific code can set this to false.
++ */
++bool i8253_clear_counter_on_shutdown __ro_after_init = true;
++
+ #ifdef CONFIG_CLKSRC_I8253
+ /*
+ * Since the PIT overflows every tick, its not very useful
+@@ -108,8 +115,11 @@ static int pit_shutdown(struct clock_eve
+ raw_spin_lock(&i8253_lock);
+
+ outb_p(0x30, PIT_MODE);
+- outb_p(0, PIT_CH0);
+- outb_p(0, PIT_CH0);
++
++ if (i8253_clear_counter_on_shutdown) {
++ outb_p(0, PIT_CH0);
++ outb_p(0, PIT_CH0);
++ }
+
+ raw_spin_unlock(&i8253_lock);
+ return 0;
+--- a/include/linux/i8253.h
++++ b/include/linux/i8253.h
+@@ -21,6 +21,7 @@
+ #define PIT_LATCH ((PIT_TICK_RATE + HZ/2) / HZ)
+
+ extern raw_spinlock_t i8253_lock;
++extern bool i8253_clear_counter_on_shutdown;
+ extern struct clock_event_device i8253_clockevent;
+ extern void clockevent_i8253_init(bool oneshot);
+
--- /dev/null
+From 1823342a1f2b47a4e6f5667f67cd28ab6bc4d6cd Mon Sep 17 00:00:00 2001
+From: Guenter Roeck <linux@roeck-us.net>
+Date: Sun, 1 Jul 2018 13:56:54 -0700
+Subject: configfs: replace strncpy with memcpy
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+commit 1823342a1f2b47a4e6f5667f67cd28ab6bc4d6cd upstream.
+
+gcc 8.1.0 complains:
+
+fs/configfs/symlink.c:67:3: warning:
+ 'strncpy' output truncated before terminating nul copying as many
+ bytes from a string as its length
+fs/configfs/symlink.c: In function 'configfs_get_link':
+fs/configfs/symlink.c:63:13: note: length computed here
+
+Using strncpy() is indeed less than perfect since the length of data to
+be copied has already been determined with strlen(). Replace strncpy()
+with memcpy() to address the warning and optimize the code a little.
+
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu@cybertrust.co.jp>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/configfs/symlink.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/configfs/symlink.c
++++ b/fs/configfs/symlink.c
+@@ -64,7 +64,7 @@ static void fill_item_path(struct config
+
+ /* back up enough to print this bus id with '/' */
+ length -= cur;
+- strncpy(buffer + length,config_item_name(p),cur);
++ memcpy(buffer + length, config_item_name(p), cur);
+ *(buffer + --length) = '/';
+ }
+ }
--- /dev/null
+From 61a9c11e5e7a0dab5381afa5d9d4dd5ebf18f7a0 Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Sat, 3 Nov 2018 16:50:08 -0400
+Subject: ext4: add missing brelse() add_new_gdb_meta_bg()'s error path
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit 61a9c11e5e7a0dab5381afa5d9d4dd5ebf18f7a0 upstream.
+
+Fixes: 01f795f9e0d6 ("ext4: add online resizing support for meta_bg ...")
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org # 3.7
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/resize.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -899,6 +899,7 @@ static int add_new_gdb_meta_bg(struct su
+ sizeof(struct buffer_head *),
+ GFP_NOFS);
+ if (!n_group_desc) {
++ brelse(gdb_bh);
+ err = -ENOMEM;
+ ext4_warning(sb, "not enough memory for %lu groups",
+ gdb_num + 1);
+@@ -914,8 +915,6 @@ static int add_new_gdb_meta_bg(struct su
+ kvfree(o_group_desc);
+ BUFFER_TRACE(gdb_bh, "get_write_access");
+ err = ext4_journal_get_write_access(handle, gdb_bh);
+- if (unlikely(err))
+- brelse(gdb_bh);
+ return err;
+ }
+
--- /dev/null
+From cea5794122125bf67559906a0762186cf417099c Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Sat, 3 Nov 2018 16:22:10 -0400
+Subject: ext4: add missing brelse() in set_flexbg_block_bitmap()'s error path
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit cea5794122125bf67559906a0762186cf417099c upstream.
+
+Fixes: 33afdcc5402d ("ext4: add a function which sets up group blocks ...")
+Cc: stable@kernel.org # 3.3
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/resize.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -442,16 +442,18 @@ static int set_flexbg_block_bitmap(struc
+
+ BUFFER_TRACE(bh, "get_write_access");
+ err = ext4_journal_get_write_access(handle, bh);
+- if (err)
++ if (err) {
++ brelse(bh);
+ return err;
++ }
+ ext4_debug("mark block bitmap %#04llx (+%llu/%u)\n", block,
+ block - start, count2);
+ ext4_set_bits(bh->b_data, block - start, count2);
+
+ err = ext4_handle_dirty_metadata(handle, NULL, bh);
++ brelse(bh);
+ if (unlikely(err))
+ return err;
+- brelse(bh);
+ }
+
+ return 0;
--- /dev/null
+From ea0abbb648452cdb6e1734b702b6330a7448fcf8 Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Sat, 3 Nov 2018 17:11:19 -0400
+Subject: ext4: add missing brelse() update_backups()'s error path
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit ea0abbb648452cdb6e1734b702b6330a7448fcf8 upstream.
+
+Fixes: ac27a0ec112a ("ext4: initial copy of files from ext3")
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org # 2.6.19
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/resize.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1095,8 +1095,10 @@ static void update_backups(struct super_
+ backup_block, backup_block -
+ ext4_group_first_block_no(sb, group));
+ BUFFER_TRACE(bh, "get_write_access");
+- if ((err = ext4_journal_get_write_access(handle, bh)))
++ if ((err = ext4_journal_get_write_access(handle, bh))) {
++ brelse(bh);
+ break;
++ }
+ lock_buffer(bh);
+ memcpy(bh->b_data, data, size);
+ if (rest)
--- /dev/null
+From feaf264ce7f8d54582e2f66eb82dd9dd124c94f3 Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Tue, 6 Nov 2018 17:01:36 -0500
+Subject: ext4: avoid buffer leak in ext4_orphan_add() after prior errors
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit feaf264ce7f8d54582e2f66eb82dd9dd124c94f3 upstream.
+
+Fixes: d745a8c20c1f ("ext4: reduce contention on s_orphan_lock")
+Fixes: 6e3617e579e0 ("ext4: Handle non empty on-disk orphan link")
+Cc: Dmitry Monakhov <dmonakhov@gmail.com>
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org # 2.6.34
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/namei.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -2842,7 +2842,9 @@ int ext4_orphan_add(handle_t *handle, st
+ list_del_init(&EXT4_I(inode)->i_orphan);
+ mutex_unlock(&sbi->s_orphan_lock);
+ }
+- }
++ } else
++ brelse(iloc.bh);
++
+ jbd_debug(4, "superblock will point to %lu\n", inode->i_ino);
+ jbd_debug(4, "orphan inode %lu will point to %d\n",
+ inode->i_ino, NEXT_ORPHAN(inode));
--- /dev/null
+From 4f32c38b4662312dd3c5f113d8bdd459887fb773 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Tue, 6 Nov 2018 17:18:17 -0500
+Subject: ext4: avoid possible double brelse() in add_new_gdb() on error path
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 4f32c38b4662312dd3c5f113d8bdd459887fb773 upstream.
+
+Fixes: b40971426a83 ("ext4: add error checking to calls to ...")
+Reported-by: Vasily Averin <vvs@virtuozzo.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org # 2.6.38
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/resize.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -844,6 +844,7 @@ static int add_new_gdb(handle_t *handle,
+ err = ext4_handle_dirty_metadata(handle, NULL, gdb_bh);
+ if (unlikely(err)) {
+ ext4_std_error(sb, err);
++ iloc.bh = NULL;
+ goto exit_inode;
+ }
+ brelse(dind);
--- /dev/null
+From 9e4028935cca3f9ef9b6a90df9da6f1f94853536 Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Sat, 3 Nov 2018 16:13:17 -0400
+Subject: ext4: avoid potential extra brelse in setup_new_flex_group_blocks()
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit 9e4028935cca3f9ef9b6a90df9da6f1f94853536 upstream.
+
+Currently bh is set to NULL only during first iteration of for cycle,
+then this pointer is not cleared after end of using.
+Therefore rollback after errors can lead to extra brelse(bh) call,
+decrements bh counter and later trigger an unexpected warning in __brelse()
+
+Patch moves brelse() calls in body of cycle to exclude requirement of
+brelse() call in rollback.
+
+Fixes: 33afdcc5402d ("ext4: add a function which sets up group blocks ...")
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org # 3.3+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/resize.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -590,7 +590,6 @@ handle_bb:
+ bh = bclean(handle, sb, block);
+ if (IS_ERR(bh)) {
+ err = PTR_ERR(bh);
+- bh = NULL;
+ goto out;
+ }
+ overhead = ext4_group_overhead_blocks(sb, group);
+@@ -602,9 +601,9 @@ handle_bb:
+ ext4_mark_bitmap_end(group_data[i].blocks_count,
+ sb->s_blocksize * 8, bh->b_data);
+ err = ext4_handle_dirty_metadata(handle, NULL, bh);
++ brelse(bh);
+ if (err)
+ goto out;
+- brelse(bh);
+
+ handle_ib:
+ if (bg_flags[i] & EXT4_BG_INODE_UNINIT)
+@@ -619,18 +618,16 @@ handle_ib:
+ bh = bclean(handle, sb, block);
+ if (IS_ERR(bh)) {
+ err = PTR_ERR(bh);
+- bh = NULL;
+ goto out;
+ }
+
+ ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb),
+ sb->s_blocksize * 8, bh->b_data);
+ err = ext4_handle_dirty_metadata(handle, NULL, bh);
++ brelse(bh);
+ if (err)
+ goto out;
+- brelse(bh);
+ }
+- bh = NULL;
+
+ /* Mark group tables in block bitmap */
+ for (j = 0; j < GROUP_TABLE_COUNT; j++) {
+@@ -661,7 +658,6 @@ handle_ib:
+ }
+
+ out:
+- brelse(bh);
+ err2 = ext4_journal_stop(handle);
+ if (err2 && !err)
+ err = err2;
--- /dev/null
+From de59fae0043f07de5d25e02ca360f7d57bfa5866 Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Wed, 7 Nov 2018 22:36:23 -0500
+Subject: ext4: fix buffer leak in __ext4_read_dirblock() on error path
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit de59fae0043f07de5d25e02ca360f7d57bfa5866 upstream.
+
+Fixes: dc6982ff4db1 ("ext4: refactor code to read directory blocks ...")
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org # 3.9
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/namei.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -124,6 +124,7 @@ static struct buffer_head *__ext4_read_d
+ if (!is_dx_block && type == INDEX) {
+ ext4_error_inode(inode, func, line, block,
+ "directory leaf block found instead of index block");
++ brelse(bh);
+ return ERR_PTR(-EFSCORRUPTED);
+ }
+ if (!ext4_has_metadata_csum(inode->i_sb) ||
--- /dev/null
+From 6bdc9977fcdedf47118d2caf7270a19f4b6d8a8f Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Wed, 7 Nov 2018 11:10:21 -0500
+Subject: ext4: fix buffer leak in ext4_xattr_move_to_block() on error path
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit 6bdc9977fcdedf47118d2caf7270a19f4b6d8a8f upstream.
+
+Fixes: 3f2571c1f91f ("ext4: factor out xattr moving")
+Fixes: 6dd4ee7cab7e ("ext4: Expand extra_inodes space per ...")
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org # 2.6.23
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/xattr.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -1393,6 +1393,8 @@ out:
+ kfree(buffer);
+ if (is)
+ brelse(is->iloc.bh);
++ if (bs)
++ brelse(bs->bh);
+ kfree(is);
+ kfree(bs);
+
--- /dev/null
+From f348e2241fb73515d65b5d77dd9c174128a7fbf2 Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Tue, 6 Nov 2018 16:16:01 -0500
+Subject: ext4: fix missing cleanup if ext4_alloc_flex_bg_array() fails while resizing
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit f348e2241fb73515d65b5d77dd9c174128a7fbf2 upstream.
+
+Fixes: 117fff10d7f1 ("ext4: grow the s_flex_groups array as needed ...")
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org # 3.7
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/resize.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1990,7 +1990,7 @@ retry:
+
+ err = ext4_alloc_flex_bg_array(sb, n_group + 1);
+ if (err)
+- return err;
++ goto out;
+
+ err = ext4_mb_alloc_groupinfo(sb, n_group + 1);
+ if (err)
--- /dev/null
+From db6aee62406d9fbb53315fcddd81f1dc271d49fa Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Tue, 6 Nov 2018 16:20:40 -0500
+Subject: ext4: fix possible inode leak in the retry loop of ext4_resize_fs()
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit db6aee62406d9fbb53315fcddd81f1dc271d49fa upstream.
+
+Fixes: 1c6bd7173d66 ("ext4: convert file system to meta_bg if needed ...")
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org # 3.7
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/resize.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -2026,6 +2026,10 @@ retry:
+ n_blocks_count_retry = 0;
+ free_flex_gd(flex_gd);
+ flex_gd = NULL;
++ if (resize_inode) {
++ iput(resize_inode);
++ resize_inode = NULL;
++ }
+ goto retry;
+ }
+
--- /dev/null
+From af18e35bfd01e6d65a5e3ef84ffe8b252d1628c5 Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Wed, 7 Nov 2018 10:56:28 -0500
+Subject: ext4: fix possible leak of s_journal_flag_rwsem in error path
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit af18e35bfd01e6d65a5e3ef84ffe8b252d1628c5 upstream.
+
+Fixes: c8585c6fcaf2 ("ext4: fix races between changing inode journal ...")
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org # 4.7
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/super.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -4305,6 +4305,7 @@ failed_mount6:
+ percpu_counter_destroy(&sbi->s_freeinodes_counter);
+ percpu_counter_destroy(&sbi->s_dirs_counter);
+ percpu_counter_destroy(&sbi->s_dirtyclusters_counter);
++ percpu_free_rwsem(&sbi->s_journal_flag_rwsem);
+ failed_mount5:
+ ext4_ext_release(sb);
+ ext4_release_system_zone(sb);
--- /dev/null
+From 9e463084cdb22e0b56b2dfbc50461020409a5fd3 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Wed, 7 Nov 2018 10:32:53 -0500
+Subject: ext4: fix possible leak of sbi->s_group_desc_leak in error path
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 9e463084cdb22e0b56b2dfbc50461020409a5fd3 upstream.
+
+Fixes: bfe0a5f47ada ("ext4: add more mount time checks of the superblock")
+Reported-by: Vasily Averin <vvs@virtuozzo.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org # 4.18
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/super.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -3897,6 +3897,14 @@ static int ext4_fill_super(struct super_
+ sbi->s_groups_count = blocks_count;
+ sbi->s_blockfile_groups = min_t(ext4_group_t, sbi->s_groups_count,
+ (EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb)));
++ if (((u64)sbi->s_groups_count * sbi->s_inodes_per_group) !=
++ le32_to_cpu(es->s_inodes_count)) {
++ ext4_msg(sb, KERN_ERR, "inodes count not valid: %u vs %llu",
++ le32_to_cpu(es->s_inodes_count),
++ ((u64)sbi->s_groups_count * sbi->s_inodes_per_group));
++ ret = -EINVAL;
++ goto failed_mount;
++ }
+ db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) /
+ EXT4_DESC_PER_BLOCK(sb);
+ if (ext4_has_feature_meta_bg(sb)) {
+@@ -3916,14 +3924,6 @@ static int ext4_fill_super(struct super_
+ ret = -ENOMEM;
+ goto failed_mount;
+ }
+- if (((u64)sbi->s_groups_count * sbi->s_inodes_per_group) !=
+- le32_to_cpu(es->s_inodes_count)) {
+- ext4_msg(sb, KERN_ERR, "inodes count not valid: %u vs %llu",
+- le32_to_cpu(es->s_inodes_count),
+- ((u64)sbi->s_groups_count * sbi->s_inodes_per_group));
+- ret = -EINVAL;
+- goto failed_mount;
+- }
+
+ bgl_lock_init(sbi->s_blockgroup_lock);
+
--- /dev/null
+From 45ae932d246f721e6584430017176cbcadfde610 Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Wed, 7 Nov 2018 11:07:01 -0500
+Subject: ext4: release bs.bh before re-using in ext4_xattr_block_find()
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit 45ae932d246f721e6584430017176cbcadfde610 upstream.
+
+bs.bh was taken in previous ext4_xattr_block_find() call,
+it should be released before re-using
+
+Fixes: 7e01c8e5420b ("ext3/4: fix uninitialized bs in ...")
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org # 2.6.26
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/xattr.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -1221,6 +1221,8 @@ ext4_xattr_set_handle(handle_t *handle,
+ error = ext4_xattr_block_set(handle, inode, &i, &bs);
+ } else if (error == -ENOSPC) {
+ if (EXT4_I(inode)->i_file_acl && !bs.s.base) {
++ brelse(bs.bh);
++ bs.bh = NULL;
+ error = ext4_xattr_block_find(inode, &i, &bs);
+ if (error)
+ goto cleanup;
--- /dev/null
+From 7fabaf303458fcabb694999d6fa772cc13d4e217 Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Fri, 9 Nov 2018 15:52:16 +0100
+Subject: fuse: fix leaked notify reply
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit 7fabaf303458fcabb694999d6fa772cc13d4e217 upstream.
+
+fuse_request_send_notify_reply() may fail if the connection was reset for
+some reason (e.g. fs was unmounted). Don't leak request reference in this
+case. Besides leaking memory, this resulted in fc->num_waiting not being
+decremented and hence fuse_wait_aborted() left in a hanging and unkillable
+state.
+
+Fixes: 2d45ba381a74 ("fuse: add retrieve request")
+Fixes: b8f95e5d13f5 ("fuse: umount should wait for all requests")
+Reported-and-tested-by: syzbot+6339eda9cb4ebbc4c37b@syzkaller.appspotmail.com
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Cc: <stable@vger.kernel.org> #v2.6.36
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/dev.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -1715,8 +1715,10 @@ static int fuse_retrieve(struct fuse_con
+ req->in.args[1].size = total_len;
+
+ err = fuse_request_send_notify_reply(fc, req, outarg->notify_unique);
+- if (err)
++ if (err) {
+ fuse_retrieve_end(fc, req);
++ fuse_put_request(fc, req);
++ }
+
+ return err;
+ }
--- /dev/null
+From ebacb81273599555a7a19f7754a1451206a5fc4f Mon Sep 17 00:00:00 2001
+From: Lukas Czerner <lczerner@redhat.com>
+Date: Fri, 9 Nov 2018 14:51:46 +0100
+Subject: fuse: fix use-after-free in fuse_direct_IO()
+
+From: Lukas Czerner <lczerner@redhat.com>
+
+commit ebacb81273599555a7a19f7754a1451206a5fc4f upstream.
+
+In async IO blocking case the additional reference to the io is taken for
+it to survive fuse_aio_complete(). In non blocking case this additional
+reference is not needed, however we still reference io to figure out
+whether to wait for completion or not. This is wrong and will lead to
+use-after-free. Fix it by storing blocking information in separate
+variable.
+
+This was spotted by KASAN when running generic/208 fstest.
+
+Signed-off-by: Lukas Czerner <lczerner@redhat.com>
+Reported-by: Zorro Lang <zlang@redhat.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Fixes: 744742d692e3 ("fuse: Add reference counting for fuse_io_priv")
+Cc: <stable@vger.kernel.org> # v4.6
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/file.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -2900,10 +2900,12 @@ fuse_direct_IO(struct kiocb *iocb, struc
+ }
+
+ if (io->async) {
++ bool blocking = io->blocking;
++
+ fuse_aio_complete(io, ret < 0 ? ret : 0, -1);
+
+ /* we have a non-extending, async request, so return */
+- if (!io->blocking)
++ if (!blocking)
+ return -EIOCBQUEUED;
+
+ wait_for_completion(&wait);
--- /dev/null
+From 5e41540c8a0f0e98c337dda8b391e5dda0cde7cf Mon Sep 17 00:00:00 2001
+From: Mike Kravetz <mike.kravetz@oracle.com>
+Date: Fri, 16 Nov 2018 15:08:04 -0800
+Subject: hugetlbfs: fix kernel BUG at fs/hugetlbfs/inode.c:444!
+
+From: Mike Kravetz <mike.kravetz@oracle.com>
+
+commit 5e41540c8a0f0e98c337dda8b391e5dda0cde7cf upstream.
+
+This bug has been experienced several times by the Oracle DB team. The
+BUG is in remove_inode_hugepages() as follows:
+
+ /*
+ * If page is mapped, it was faulted in after being
+ * unmapped in caller. Unmap (again) now after taking
+ * the fault mutex. The mutex will prevent faults
+ * until we finish removing the page.
+ *
+ * This race can only happen in the hole punch case.
+ * Getting here in a truncate operation is a bug.
+ */
+ if (unlikely(page_mapped(page))) {
+ BUG_ON(truncate_op);
+
+In this case, the elevated map count is not the result of a race.
+Rather it was incorrectly incremented as the result of a bug in the huge
+pmd sharing code. Consider the following:
+
+ - Process A maps a hugetlbfs file of sufficient size and alignment
+ (PUD_SIZE) that a pmd page could be shared.
+
+ - Process B maps the same hugetlbfs file with the same size and
+ alignment such that a pmd page is shared.
+
+ - Process B then calls mprotect() to change protections for the mapping
+ with the shared pmd. As a result, the pmd is 'unshared'.
+
+ - Process B then calls mprotect() again to chage protections for the
+ mapping back to their original value. pmd remains unshared.
+
+ - Process B then forks and process C is created. During the fork
+ process, we do dup_mm -> dup_mmap -> copy_page_range to copy page
+ tables. Copying page tables for hugetlb mappings is done in the
+ routine copy_hugetlb_page_range.
+
+In copy_hugetlb_page_range(), the destination pte is obtained by:
+
+ dst_pte = huge_pte_alloc(dst, addr, sz);
+
+If pmd sharing is possible, the returned pointer will be to a pte in an
+existing page table. In the situation above, process C could share with
+either process A or process B. Since process A is first in the list,
+the returned pte is a pointer to a pte in process A's page table.
+
+However, the check for pmd sharing in copy_hugetlb_page_range is:
+
+ /* If the pagetables are shared don't copy or take references */
+ if (dst_pte == src_pte)
+ continue;
+
+Since process C is sharing with process A instead of process B, the
+above test fails. The code in copy_hugetlb_page_range which follows
+assumes dst_pte points to a huge_pte_none pte. It copies the pte entry
+from src_pte to dst_pte and increments this map count of the associated
+page. This is how we end up with an elevated map count.
+
+To solve, check the dst_pte entry for huge_pte_none. If !none, this
+implies PMD sharing so do not copy.
+
+Link: http://lkml.kernel.org/r/20181105212315.14125-1-mike.kravetz@oracle.com
+Fixes: c5c99429fa57 ("fix hugepages leak due to pagetable page sharing")
+Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com>
+Reviewed-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
+Cc: Michal Hocko <mhocko@kernel.org>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: "Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>
+Cc: Davidlohr Bueso <dave@stgolabs.net>
+Cc: Prakash Sangappa <prakash.sangappa@oracle.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/hugetlb.c | 23 +++++++++++++++++++----
+ 1 file changed, 19 insertions(+), 4 deletions(-)
+
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -3220,7 +3220,7 @@ static int is_hugetlb_entry_hwpoisoned(p
+ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
+ struct vm_area_struct *vma)
+ {
+- pte_t *src_pte, *dst_pte, entry;
++ pte_t *src_pte, *dst_pte, entry, dst_entry;
+ struct page *ptepage;
+ unsigned long addr;
+ int cow;
+@@ -3248,15 +3248,30 @@ int copy_hugetlb_page_range(struct mm_st
+ break;
+ }
+
+- /* If the pagetables are shared don't copy or take references */
+- if (dst_pte == src_pte)
++ /*
++ * If the pagetables are shared don't copy or take references.
++ * dst_pte == src_pte is the common case of src/dest sharing.
++ *
++ * However, src could have 'unshared' and dst shares with
++ * another vma. If dst_pte !none, this implies sharing.
++ * Check here before taking page table lock, and once again
++ * after taking the lock below.
++ */
++ dst_entry = huge_ptep_get(dst_pte);
++ if ((dst_pte == src_pte) || !huge_pte_none(dst_entry))
+ continue;
+
+ dst_ptl = huge_pte_lock(h, dst, dst_pte);
+ src_ptl = huge_pte_lockptr(h, src, src_pte);
+ spin_lock_nested(src_ptl, SINGLE_DEPTH_NESTING);
+ entry = huge_ptep_get(src_pte);
+- if (huge_pte_none(entry)) { /* skip none entry */
++ dst_entry = huge_ptep_get(dst_pte);
++ if (huge_pte_none(entry) || !huge_pte_none(dst_entry)) {
++ /*
++ * Skip if src entry none. Also, skip in the
++ * unlikely case dst entry !none as this implies
++ * sharing with another vma.
++ */
+ ;
+ } else if (unlikely(is_hugetlb_entry_migration(entry) ||
+ is_hugetlb_entry_hwpoisoned(entry))) {
--- /dev/null
+From 1c23b4108d716cc848b38532063a8aca4f86add8 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Fri, 16 Nov 2018 15:08:35 -0800
+Subject: lib/ubsan.c: don't mark __ubsan_handle_builtin_unreachable as noreturn
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit 1c23b4108d716cc848b38532063a8aca4f86add8 upstream.
+
+gcc-8 complains about the prototype for this function:
+
+ lib/ubsan.c:432:1: error: ignoring attribute 'noreturn' in declaration of a built-in function '__ubsan_handle_builtin_unreachable' because it conflicts with attribute 'const' [-Werror=attributes]
+
+This is actually a GCC's bug. In GCC internals
+__ubsan_handle_builtin_unreachable() declared with both 'noreturn' and
+'const' attributes instead of only 'noreturn':
+
+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84210
+
+Workaround this by removing the noreturn attribute.
+
+[aryabinin: add information about GCC bug in changelog]
+Link: http://lkml.kernel.org/r/20181107144516.4587-1-aryabinin@virtuozzo.com
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
+Acked-by: Olof Johansson <olof@lixom.net>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ lib/ubsan.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/lib/ubsan.c
++++ b/lib/ubsan.c
+@@ -451,8 +451,7 @@ void __ubsan_handle_shift_out_of_bounds(
+ EXPORT_SYMBOL(__ubsan_handle_shift_out_of_bounds);
+
+
+-void __noreturn
+-__ubsan_handle_builtin_unreachable(struct unreachable_data *data)
++void __ubsan_handle_builtin_unreachable(struct unreachable_data *data)
+ {
+ unsigned long flags;
+
--- /dev/null
+From 017b1660df89f5fb4bfe66c34e35f7d2031100c7 Mon Sep 17 00:00:00 2001
+From: Mike Kravetz <mike.kravetz@oracle.com>
+Date: Fri, 5 Oct 2018 15:51:29 -0700
+Subject: mm: migration: fix migration of huge PMD shared pages
+
+From: Mike Kravetz <mike.kravetz@oracle.com>
+
+commit 017b1660df89f5fb4bfe66c34e35f7d2031100c7 upstream.
+
+The page migration code employs try_to_unmap() to try and unmap the source
+page. This is accomplished by using rmap_walk to find all vmas where the
+page is mapped. This search stops when page mapcount is zero. For shared
+PMD huge pages, the page map count is always 1 no matter the number of
+mappings. Shared mappings are tracked via the reference count of the PMD
+page. Therefore, try_to_unmap stops prematurely and does not completely
+unmap all mappings of the source page.
+
+This problem can result is data corruption as writes to the original
+source page can happen after contents of the page are copied to the target
+page. Hence, data is lost.
+
+This problem was originally seen as DB corruption of shared global areas
+after a huge page was soft offlined due to ECC memory errors. DB
+developers noticed they could reproduce the issue by (hotplug) offlining
+memory used to back huge pages. A simple testcase can reproduce the
+problem by creating a shared PMD mapping (note that this must be at least
+PUD_SIZE in size and PUD_SIZE aligned (1GB on x86)), and using
+migrate_pages() to migrate process pages between nodes while continually
+writing to the huge pages being migrated.
+
+To fix, have the try_to_unmap_one routine check for huge PMD sharing by
+calling huge_pmd_unshare for hugetlbfs huge pages. If it is a shared
+mapping it will be 'unshared' which removes the page table entry and drops
+the reference on the PMD page. After this, flush caches and TLB.
+
+mmu notifiers are called before locking page tables, but we can not be
+sure of PMD sharing until page tables are locked. Therefore, check for
+the possibility of PMD sharing before locking so that notifiers can
+prepare for the worst possible case.
+
+Link: http://lkml.kernel.org/r/20180823205917.16297-2-mike.kravetz@oracle.com
+[mike.kravetz@oracle.com: make _range_in_vma() a static inline]
+ Link: http://lkml.kernel.org/r/6063f215-a5c8-2f0c-465a-2c515ddc952d@oracle.com
+Fixes: 39dde65c9940 ("shared page table for hugetlb page")
+Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com>
+Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Reviewed-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: Vlastimil Babka <vbabka@suse.cz>
+Cc: Davidlohr Bueso <dave@stgolabs.net>
+Cc: Jerome Glisse <jglisse@redhat.com>
+Cc: Mike Kravetz <mike.kravetz@oracle.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com>
+Reviewed-by: Jérôme Glisse <jglisse@redhat.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/hugetlb.h | 14 ++++++++++++
+ include/linux/mm.h | 6 +++++
+ mm/hugetlb.c | 37 ++++++++++++++++++++++++++++++-
+ mm/rmap.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 111 insertions(+), 2 deletions(-)
+
+--- a/include/linux/hugetlb.h
++++ b/include/linux/hugetlb.h
+@@ -109,6 +109,8 @@ pte_t *huge_pte_alloc(struct mm_struct *
+ unsigned long addr, unsigned long sz);
+ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr);
+ int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep);
++void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma,
++ unsigned long *start, unsigned long *end);
+ struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
+ int write);
+ struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+@@ -131,6 +133,18 @@ static inline unsigned long hugetlb_tota
+ return 0;
+ }
+
++static inline int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr,
++ pte_t *ptep)
++{
++ return 0;
++}
++
++static inline void adjust_range_if_pmd_sharing_possible(
++ struct vm_area_struct *vma,
++ unsigned long *start, unsigned long *end)
++{
++}
++
+ #define follow_hugetlb_page(m,v,p,vs,a,b,i,w) ({ BUG(); 0; })
+ #define follow_huge_addr(mm, addr, write) ERR_PTR(-EINVAL)
+ #define copy_hugetlb_page_range(src, dst, vma) ({ BUG(); 0; })
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -2187,6 +2187,12 @@ static inline struct vm_area_struct *fin
+ return vma;
+ }
+
++static inline bool range_in_vma(struct vm_area_struct *vma,
++ unsigned long start, unsigned long end)
++{
++ return (vma && vma->vm_start <= start && end <= vma->vm_end);
++}
++
+ #ifdef CONFIG_MMU
+ pgprot_t vm_get_page_prot(unsigned long vm_flags);
+ void vma_set_page_prot(struct vm_area_struct *vma);
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -4333,13 +4333,41 @@ static bool vma_shareable(struct vm_area
+ /*
+ * check on proper vm_flags and page table alignment
+ */
+- if (vma->vm_flags & VM_MAYSHARE &&
+- vma->vm_start <= base && end <= vma->vm_end)
++ if (vma->vm_flags & VM_MAYSHARE && range_in_vma(vma, base, end))
+ return true;
+ return false;
+ }
+
+ /*
++ * Determine if start,end range within vma could be mapped by shared pmd.
++ * If yes, adjust start and end to cover range associated with possible
++ * shared pmd mappings.
++ */
++void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma,
++ unsigned long *start, unsigned long *end)
++{
++ unsigned long check_addr = *start;
++
++ if (!(vma->vm_flags & VM_MAYSHARE))
++ return;
++
++ for (check_addr = *start; check_addr < *end; check_addr += PUD_SIZE) {
++ unsigned long a_start = check_addr & PUD_MASK;
++ unsigned long a_end = a_start + PUD_SIZE;
++
++ /*
++ * If sharing is possible, adjust start/end if necessary.
++ */
++ if (range_in_vma(vma, a_start, a_end)) {
++ if (a_start < *start)
++ *start = a_start;
++ if (a_end > *end)
++ *end = a_end;
++ }
++ }
++}
++
++/*
+ * Search for a shareable pmd page for hugetlb. In any case calls pmd_alloc()
+ * and returns the corresponding pte. While this is not necessary for the
+ * !shared pmd case because we can allocate the pmd later as well, it makes the
+@@ -4435,6 +4463,11 @@ int huge_pmd_unshare(struct mm_struct *m
+ {
+ return 0;
+ }
++
++void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma,
++ unsigned long *start, unsigned long *end)
++{
++}
+ #define want_pmd_share() (0)
+ #endif /* CONFIG_ARCH_WANT_HUGE_PMD_SHARE */
+
+--- a/mm/rmap.c
++++ b/mm/rmap.c
+@@ -1476,6 +1476,9 @@ static int try_to_unmap_one(struct page
+ pte_t pteval;
+ spinlock_t *ptl;
+ int ret = SWAP_AGAIN;
++ unsigned long sh_address;
++ bool pmd_sharing_possible = false;
++ unsigned long spmd_start, spmd_end;
+ struct rmap_private *rp = arg;
+ enum ttu_flags flags = rp->flags;
+
+@@ -1491,6 +1494,32 @@ static int try_to_unmap_one(struct page
+ goto out;
+ }
+
++ /*
++ * Only use the range_start/end mmu notifiers if huge pmd sharing
++ * is possible. In the normal case, mmu_notifier_invalidate_page
++ * is sufficient as we only unmap a page. However, if we unshare
++ * a pmd, we will unmap a PUD_SIZE range.
++ */
++ if (PageHuge(page)) {
++ spmd_start = address;
++ spmd_end = spmd_start + vma_mmu_pagesize(vma);
++
++ /*
++ * Check if pmd sharing is possible. If possible, we could
++ * unmap a PUD_SIZE range. spmd_start/spmd_end will be
++ * modified if sharing is possible.
++ */
++ adjust_range_if_pmd_sharing_possible(vma, &spmd_start,
++ &spmd_end);
++ if (spmd_end - spmd_start != vma_mmu_pagesize(vma)) {
++ sh_address = address;
++
++ pmd_sharing_possible = true;
++ mmu_notifier_invalidate_range_start(vma->vm_mm,
++ spmd_start, spmd_end);
++ }
++ }
++
+ pte = page_check_address(page, mm, address, &ptl,
+ PageTransCompound(page));
+ if (!pte)
+@@ -1524,6 +1553,30 @@ static int try_to_unmap_one(struct page
+ }
+ }
+
++ /*
++ * Call huge_pmd_unshare to potentially unshare a huge pmd. Pass
++ * sh_address as it will be modified if unsharing is successful.
++ */
++ if (PageHuge(page) && huge_pmd_unshare(mm, &sh_address, pte)) {
++ /*
++ * huge_pmd_unshare unmapped an entire PMD page. There is
++ * no way of knowing exactly which PMDs may be cached for
++ * this mm, so flush them all. spmd_start/spmd_end cover
++ * this PUD_SIZE range.
++ */
++ flush_cache_range(vma, spmd_start, spmd_end);
++ flush_tlb_range(vma, spmd_start, spmd_end);
++
++ /*
++ * The ref count of the PMD page was dropped which is part
++ * of the way map counting is done for shared PMDs. When
++ * there is no other sharing, huge_pmd_unshare returns false
++ * and we will unmap the actual page and drop map count
++ * to zero.
++ */
++ goto out_unmap;
++ }
++
+ /* Nuke the page table entry. */
+ flush_cache_page(vma, address, page_to_pfn(page));
+ if (should_defer_flush(mm, flags)) {
+@@ -1621,6 +1674,9 @@ out_unmap:
+ if (ret != SWAP_FAIL && ret != SWAP_MLOCK && !(flags & TTU_MUNLOCK))
+ mmu_notifier_invalidate_page(mm, address);
+ out:
++ if (pmd_sharing_possible)
++ mmu_notifier_invalidate_range_end(vma->vm_mm,
++ spmd_start, spmd_end);
+ return ret;
+ }
+
--- /dev/null
+From df7342b240185d58d3d9665c0bbf0a0f5570ec29 Mon Sep 17 00:00:00 2001
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+Date: Thu, 25 Oct 2018 09:04:18 -0500
+Subject: mount: Don't allow copying MNT_UNBINDABLE|MNT_LOCKED mounts
+
+From: Eric W. Biederman <ebiederm@xmission.com>
+
+commit df7342b240185d58d3d9665c0bbf0a0f5570ec29 upstream.
+
+Jonathan Calmels from NVIDIA reported that he's able to bypass the
+mount visibility security check in place in the Linux kernel by using
+a combination of the unbindable property along with the private mount
+propagation option to allow a unprivileged user to see a path which
+was purposefully hidden by the root user.
+
+Reproducer:
+ # Hide a path to all users using a tmpfs
+ root@castiana:~# mount -t tmpfs tmpfs /sys/devices/
+ root@castiana:~#
+
+ # As an unprivileged user, unshare user namespace and mount namespace
+ stgraber@castiana:~$ unshare -U -m -r
+
+ # Confirm the path is still not accessible
+ root@castiana:~# ls /sys/devices/
+
+ # Make /sys recursively unbindable and private
+ root@castiana:~# mount --make-runbindable /sys
+ root@castiana:~# mount --make-private /sys
+
+ # Recursively bind-mount the rest of /sys over to /mnnt
+ root@castiana:~# mount --rbind /sys/ /mnt
+
+ # Access our hidden /sys/device as an unprivileged user
+ root@castiana:~# ls /mnt/devices/
+ breakpoint cpu cstate_core cstate_pkg i915 intel_pt isa kprobe
+ LNXSYSTM:00 msr pci0000:00 platform pnp0 power software system
+ tracepoint uncore_arb uncore_cbox_0 uncore_cbox_1 uprobe virtual
+
+Solve this by teaching copy_tree to fail if a mount turns out to be
+both unbindable and locked.
+
+Cc: stable@vger.kernel.org
+Fixes: 5ff9d8a65ce8 ("vfs: Lock in place mounts from more privileged users")
+Reported-by: Jonathan Calmels <jcalmels@nvidia.com>
+Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/namespace.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -1788,8 +1788,14 @@ struct mount *copy_tree(struct mount *mn
+ for (s = r; s; s = next_mnt(s, r)) {
+ if (!(flag & CL_COPY_UNBINDABLE) &&
+ IS_MNT_UNBINDABLE(s)) {
+- s = skip_mnt_tree(s);
+- continue;
++ if (s->mnt.mnt_flags & MNT_LOCKED) {
++ /* Both unbindable and locked. */
++ q = ERR_PTR(-EPERM);
++ goto out;
++ } else {
++ s = skip_mnt_tree(s);
++ continue;
++ }
+ }
+ if (!(flag & CL_COPY_MNT_NS_FILE) &&
+ is_mnt_ns_file(s->mnt.mnt_root)) {
--- /dev/null
+From 9c8e0a1b683525464a2abe9fb4b54404a50ed2b4 Mon Sep 17 00:00:00 2001
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+Date: Thu, 25 Oct 2018 12:05:11 -0500
+Subject: mount: Prevent MNT_DETACH from disconnecting locked mounts
+
+From: Eric W. Biederman <ebiederm@xmission.com>
+
+commit 9c8e0a1b683525464a2abe9fb4b54404a50ed2b4 upstream.
+
+Timothy Baldwin <timbaldwin@fastmail.co.uk> wrote:
+> As per mount_namespaces(7) unprivileged users should not be able to look under mount points:
+>
+> Mounts that come as a single unit from more privileged mount are locked
+> together and may not be separated in a less privileged mount namespace.
+>
+> However they can:
+>
+> 1. Create a mount namespace.
+> 2. In the mount namespace open a file descriptor to the parent of a mount point.
+> 3. Destroy the mount namespace.
+> 4. Use the file descriptor to look under the mount point.
+>
+> I have reproduced this with Linux 4.16.18 and Linux 4.18-rc8.
+>
+> The setup:
+>
+> $ sudo sysctl kernel.unprivileged_userns_clone=1
+> kernel.unprivileged_userns_clone = 1
+> $ mkdir -p A/B/Secret
+> $ sudo mount -t tmpfs hide A/B
+>
+>
+> "Secret" is indeed hidden as expected:
+>
+> $ ls -lR A
+> A:
+> total 0
+> drwxrwxrwt 2 root root 40 Feb 12 21:08 B
+>
+> A/B:
+> total 0
+>
+>
+> The attack revealing "Secret":
+>
+> $ unshare -Umr sh -c "exec unshare -m ls -lR /proc/self/fd/4/ 4<A"
+> /proc/self/fd/4/:
+> total 0
+> drwxr-xr-x 3 root root 60 Feb 12 21:08 B
+>
+> /proc/self/fd/4/B:
+> total 0
+> drwxr-xr-x 2 root root 40 Feb 12 21:08 Secret
+>
+> /proc/self/fd/4/B/Secret:
+> total 0
+
+I tracked this down to put_mnt_ns running passing UMOUNT_SYNC and
+disconnecting all of the mounts in a mount namespace. Fix this by
+factoring drop_mounts out of drop_collected_mounts and passing
+0 instead of UMOUNT_SYNC.
+
+There are two possible behavior differences that result from this.
+- No longer setting UMOUNT_SYNC will no longer set MNT_SYNC_UMOUNT on
+ the vfsmounts being unmounted. This effects the lazy rcu walk by
+ kicking the walk out of rcu mode and forcing it to be a non-lazy
+ walk.
+- No longer disconnecting locked mounts will keep some mounts around
+ longer as they stay because the are locked to other mounts.
+
+There are only two users of drop_collected mounts: audit_tree.c and
+put_mnt_ns.
+
+In audit_tree.c the mounts are private and there are no rcu lazy walks
+only calls to iterate_mounts. So the changes should have no effect
+except for a small timing effect as the connected mounts are disconnected.
+
+In put_mnt_ns there may be references from process outside the mount
+namespace to the mounts. So the mounts remaining connected will
+be the bug fix that is needed. That rcu walks are allowed to continue
+appears not to be a problem especially as the rcu walk change was about
+an implementation detail not about semantics.
+
+Cc: stable@vger.kernel.org
+Fixes: 5ff9d8a65ce8 ("vfs: Lock in place mounts from more privileged users")
+Reported-by: Timothy Baldwin <timbaldwin@fastmail.co.uk>
+Tested-by: Timothy Baldwin <timbaldwin@fastmail.co.uk>
+Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/namespace.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -1848,7 +1848,7 @@ void drop_collected_mounts(struct vfsmou
+ {
+ namespace_lock();
+ lock_mount_hash();
+- umount_tree(real_mount(mnt), UMOUNT_SYNC);
++ umount_tree(real_mount(mnt), 0);
+ unlock_mount_hash();
+ namespace_unlock();
+ }
--- /dev/null
+From 25d202ed820ee347edec0bf3bf553544556bf64b Mon Sep 17 00:00:00 2001
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+Date: Mon, 22 Oct 2018 10:21:38 -0500
+Subject: mount: Retest MNT_LOCKED in do_umount
+
+From: Eric W. Biederman <ebiederm@xmission.com>
+
+commit 25d202ed820ee347edec0bf3bf553544556bf64b upstream.
+
+It was recently pointed out that the one instance of testing MNT_LOCKED
+outside of the namespace_sem is in ksys_umount.
+
+Fix that by adding a test inside of do_umount with namespace_sem and
+the mount_lock held. As it helps to fail fails the existing test is
+maintained with an additional comment pointing out that it may be racy
+because the locks are not held.
+
+Cc: stable@vger.kernel.org
+Reported-by: Al Viro <viro@ZenIV.linux.org.uk>
+Fixes: 5ff9d8a65ce8 ("vfs: Lock in place mounts from more privileged users")
+Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/namespace.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -1599,8 +1599,13 @@ static int do_umount(struct mount *mnt,
+
+ namespace_lock();
+ lock_mount_hash();
+- event++;
+
++ /* Recheck MNT_LOCKED with the locks held */
++ retval = -EINVAL;
++ if (mnt->mnt.mnt_flags & MNT_LOCKED)
++ goto out;
++
++ event++;
+ if (flags & MNT_DETACH) {
+ if (!list_empty(&mnt->mnt_list))
+ umount_tree(mnt, UMOUNT_PROPAGATE);
+@@ -1614,6 +1619,7 @@ static int do_umount(struct mount *mnt,
+ retval = 0;
+ }
+ }
++out:
+ unlock_mount_hash();
+ namespace_unlock();
+ return retval;
+@@ -1704,7 +1710,7 @@ SYSCALL_DEFINE2(umount, char __user *, n
+ goto dput_and_out;
+ if (!check_mnt(mnt))
+ goto dput_and_out;
+- if (mnt->mnt.mnt_flags & MNT_LOCKED)
++ if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */
+ goto dput_and_out;
+ retval = -EPERM;
+ if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN))
--- /dev/null
+From 01310bb7c9c98752cc763b36532fab028e0f8f81 Mon Sep 17 00:00:00 2001
+From: Scott Mayhew <smayhew@redhat.com>
+Date: Thu, 8 Nov 2018 11:11:36 -0500
+Subject: nfsd: COPY and CLONE operations require the saved filehandle to be set
+
+From: Scott Mayhew <smayhew@redhat.com>
+
+commit 01310bb7c9c98752cc763b36532fab028e0f8f81 upstream.
+
+Make sure we have a saved filehandle, otherwise we'll oops with a null
+pointer dereference in nfs4_preprocess_stateid_op().
+
+Signed-off-by: Scott Mayhew <smayhew@redhat.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfsd/nfs4proc.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/fs/nfsd/nfs4proc.c
++++ b/fs/nfsd/nfs4proc.c
+@@ -1016,6 +1016,9 @@ nfsd4_verify_copy(struct svc_rqst *rqstp
+ {
+ __be32 status;
+
++ if (!cstate->save_fh.fh_dentry)
++ return nfserr_nofilehandle;
++
+ status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->save_fh,
+ src_stateid, RD_STATE, src, NULL);
+ if (status) {
--- /dev/null
+From 7ce9a992ffde8ce93d5ae5767362a5c7389ae895 Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@linux-mips.org>
+Date: Mon, 5 Nov 2018 03:48:25 +0000
+Subject: rtc: hctosys: Add missing range error reporting
+
+From: Maciej W. Rozycki <macro@linux-mips.org>
+
+commit 7ce9a992ffde8ce93d5ae5767362a5c7389ae895 upstream.
+
+Fix an issue with the 32-bit range error path in `rtc_hctosys' where no
+error code is set and consequently the successful preceding call result
+from `rtc_read_time' is propagated to `rtc_hctosys_ret'. This in turn
+makes any subsequent call to `hctosys_show' incorrectly report in sysfs
+that the system time has been set from this RTC while it has not.
+
+Set the error to ERANGE then if we can't express the result due to an
+overflow.
+
+Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
+Fixes: b3a5ac42ab18 ("rtc: hctosys: Ensure system time doesn't overflow time_t")
+Cc: stable@vger.kernel.org # 4.17+
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/rtc/hctosys.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/rtc/hctosys.c
++++ b/drivers/rtc/hctosys.c
+@@ -50,8 +50,10 @@ static int __init rtc_hctosys(void)
+ tv64.tv_sec = rtc_tm_to_time64(&tm);
+
+ #if BITS_PER_LONG == 32
+- if (tv64.tv_sec > INT_MAX)
++ if (tv64.tv_sec > INT_MAX) {
++ err = -ERANGE;
+ goto err_read;
++ }
+ #endif
+
+ err = do_settimeofday64(&tv64);
netfilter-conntrack-fix-calculation-of-next-bucket-number-in-early_drop.patch
mtd-docg3-don-t-set-conflicting-bch_const_params-option.patch
of-numa-validate-some-distance-map-rules.patch
+termios-tty-tty_baudrate.c-fix-buffer-overrun.patch
+arch-alpha-termios-implement-bother-ibshift-and-termios2.patch
+btrfs-fix-cur_offset-in-the-error-case-for-nocow.patch
+btrfs-fix-data-corruption-due-to-cloning-of-eof-block.patch
+clockevents-drivers-i8253-add-support-for-pit-shutdown-quirk.patch
+ext4-add-missing-brelse-update_backups-s-error-path.patch
+ext4-add-missing-brelse-in-set_flexbg_block_bitmap-s-error-path.patch
+ext4-add-missing-brelse-add_new_gdb_meta_bg-s-error-path.patch
+ext4-avoid-potential-extra-brelse-in-setup_new_flex_group_blocks.patch
+ext4-fix-possible-inode-leak-in-the-retry-loop-of-ext4_resize_fs.patch
+ext4-avoid-buffer-leak-in-ext4_orphan_add-after-prior-errors.patch
+ext4-fix-missing-cleanup-if-ext4_alloc_flex_bg_array-fails-while-resizing.patch
+ext4-avoid-possible-double-brelse-in-add_new_gdb-on-error-path.patch
+ext4-fix-possible-leak-of-sbi-s_group_desc_leak-in-error-path.patch
+ext4-fix-possible-leak-of-s_journal_flag_rwsem-in-error-path.patch
+ext4-release-bs.bh-before-re-using-in-ext4_xattr_block_find.patch
+ext4-fix-buffer-leak-in-ext4_xattr_move_to_block-on-error-path.patch
+ext4-fix-buffer-leak-in-__ext4_read_dirblock-on-error-path.patch
+mount-retest-mnt_locked-in-do_umount.patch
+mount-don-t-allow-copying-mnt_unbindable-mnt_locked-mounts.patch
+mount-prevent-mnt_detach-from-disconnecting-locked-mounts.patch
+sunrpc-correct-the-computation-for-page_ptr-when-truncating.patch
+nfsd-copy-and-clone-operations-require-the-saved-filehandle-to-be-set.patch
+rtc-hctosys-add-missing-range-error-reporting.patch
+fuse-fix-use-after-free-in-fuse_direct_io.patch
+fuse-fix-leaked-notify-reply.patch
+configfs-replace-strncpy-with-memcpy.patch
+lib-ubsan.c-don-t-mark-__ubsan_handle_builtin_unreachable-as-noreturn.patch
+hugetlbfs-fix-kernel-bug-at-fs-hugetlbfs-inode.c-444.patch
+mm-migration-fix-migration-of-huge-pmd-shared-pages.patch
--- /dev/null
+From 5d7a5bcb67c70cbc904057ef52d3fcfeb24420bb Mon Sep 17 00:00:00 2001
+From: Frank Sorenson <sorenson@redhat.com>
+Date: Tue, 30 Oct 2018 15:10:40 -0500
+Subject: sunrpc: correct the computation for page_ptr when truncating
+
+From: Frank Sorenson <sorenson@redhat.com>
+
+commit 5d7a5bcb67c70cbc904057ef52d3fcfeb24420bb upstream.
+
+When truncating the encode buffer, the page_ptr is getting
+advanced, causing the next page to be skipped while encoding.
+The page is still included in the response, so the response
+contains a page of bogus data.
+
+We need to adjust the page_ptr backwards to ensure we encode
+the next page into the correct place.
+
+We saw this triggered when concurrent directory modifications caused
+nfsd4_encode_direct_fattr() to return nfserr_noent, and the resulting
+call to xdr_truncate_encode() corrupted the READDIR reply.
+
+Signed-off-by: Frank Sorenson <sorenson@redhat.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/sunrpc/xdr.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/net/sunrpc/xdr.c
++++ b/net/sunrpc/xdr.c
+@@ -639,11 +639,10 @@ void xdr_truncate_encode(struct xdr_stre
+ WARN_ON_ONCE(xdr->iov);
+ return;
+ }
+- if (fraglen) {
++ if (fraglen)
+ xdr->end = head->iov_base + head->iov_len;
+- xdr->page_ptr--;
+- }
+ /* (otherwise assume xdr->end is already set) */
++ xdr->page_ptr--;
+ head->iov_len = len;
+ buf->len = len;
+ xdr->p = head->iov_base + head->iov_len;
--- /dev/null
+From 991a25194097006ec1e0d2e0814ff920e59e3465 Mon Sep 17 00:00:00 2001
+From: "H. Peter Anvin" <hpa@zytor.com>
+Date: Mon, 22 Oct 2018 09:19:04 -0700
+Subject: termios, tty/tty_baudrate.c: fix buffer overrun
+
+From: H. Peter Anvin <hpa@zytor.com>
+
+commit 991a25194097006ec1e0d2e0814ff920e59e3465 upstream.
+
+On architectures with CBAUDEX == 0 (Alpha and PowerPC), the code in tty_baudrate.c does
+not do any limit checking on the tty_baudrate[] array, and in fact a
+buffer overrun is possible on both architectures. Add a limit check to
+prevent that situation.
+
+This will be followed by a much bigger cleanup/simplification patch.
+
+Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
+Requested-by: Cc: Johan Hovold <johan@kernel.org>
+Cc: Jiri Slaby <jslaby@suse.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Richard Henderson <rth@twiddle.net>
+Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
+Cc: Matt Turner <mattst88@gmail.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Kate Stewart <kstewart@linuxfoundation.org>
+Cc: Philippe Ombredanne <pombredanne@nexb.com>
+Cc: Eugene Syromiatnikov <esyr@redhat.com>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/tty_ioctl.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/tty/tty_ioctl.c
++++ b/drivers/tty/tty_ioctl.c
+@@ -325,7 +325,7 @@ speed_t tty_termios_baud_rate(struct kte
+ else
+ cbaud += 15;
+ }
+- return baud_table[cbaud];
++ return cbaud >= n_baud_table ? 0 : baud_table[cbaud];
+ }
+ EXPORT_SYMBOL(tty_termios_baud_rate);
+
+@@ -361,7 +361,7 @@ speed_t tty_termios_input_baud_rate(stru
+ else
+ cbaud += 15;
+ }
+- return baud_table[cbaud];
++ return cbaud >= n_baud_table ? 0 : baud_table[cbaud];
+ #else
+ return tty_termios_baud_rate(termios);
+ #endif