]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 21 Jan 2019 11:53:03 +0000 (12:53 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 21 Jan 2019 11:53:03 +0000 (12:53 +0100)
added patches:
arm64-dts-marvell-armada-ap806-reserve-psci-area.patch
arm64-kaslr-ensure-randomized-quantities-are-clean-to-the-poc.patch
block-loop-don-t-grab-struct-file-for-vfs_getattr-operation.patch
block-loop-use-global-lock-for-ioctl-operation.patch
block-use-rcu_work-instead-of-call_rcu-to-avoid-sleep-in-softirq.patch
blockdev-fix-livelocks-on-loop-device.patch
bpf-in-__bpf_redirect_no_mac-pull-mac-only-if-present.patch
disable-msi-also-when-pcie-octeon.pcie_disable-on.patch
drm-i915-gvt-fix-mmap-range-check.patch
fix-int_sqrt64-for-very-large-numbers.patch
ipv6-make-icmp6_send-robust-against-null-skb-dev.patch
kbuild-disable-ld_dead_code_data_elimination-with-ftrace-gcc-4.7.patch
loop-avoid-circular-locking-dependency-between-loop_ctl_mutex-and-bd_mutex.patch
loop-drop-caches-if-offset-or-block_size-are-changed.patch
loop-fix-deadlock-when-calling-blkdev_reread_part.patch
loop-fix-double-mutex_unlock-loop_ctl_mutex-in-loop_control_ioctl.patch
loop-fold-__loop_release-into-loop_release.patch
loop-get-rid-of-loop_index_mutex.patch
loop-get-rid-of-nested-acquisition-of-loop_ctl_mutex.patch
loop-move-loop_reread_partitions-out-of-loop_ctl_mutex.patch
loop-move-special-partition-reread-handling-in-loop_clr_fd.patch
loop-push-lo_ctl_mutex-down-into-individual-ioctls.patch
loop-push-loop_ctl_mutex-down-into-loop_clr_fd.patch
loop-push-loop_ctl_mutex-down-to-loop_change_fd.patch
loop-push-loop_ctl_mutex-down-to-loop_get_status.patch
loop-push-loop_ctl_mutex-down-to-loop_set_fd.patch
loop-push-loop_ctl_mutex-down-to-loop_set_status.patch
loop-split-setting-of-lo_state-from-loop_clr_fd.patch
lsm-check-for-null-cred-security-on-free.patch
media-v4l-ioctl-validate-num_planes-for-debug-messages.patch
media-vb2-vb2_mmap-move-lock-up.patch
media-vivid-fix-error-handling-of-kthread_run.patch
media-vivid-set-min-width-height-to-a-value-0.patch
mfd-tps6586x-handle-interrupts-on-suspend.patch
mips-bcm47xx-setup-struct-device-for-the-soc.patch
mips-fix-n32-compat_ipc_parse_version.patch
mips-lantiq-fix-ipi-interrupt-handling.patch
net-dsa-realtek-smi-fix-of-child-node-lookup.patch
netfilter-ebtables-account-ebt_table_info-to-kmemcg.patch
of-properties-add-missing-of_node_put.patch
omap2fb-fix-stack-memory-disclosure.patch
pstore-ram-avoid-allocation-and-leak-of-platform-data.patch
rdma-nldev-don-t-expose-unsafe-global-rkey-to-regular-user.patch
rdma-vmw_pvrdma-return-the-correct-opcode-when-creating-wr.patch
sctp-allocate-sctp_sockaddr_entry-with-kzalloc.patch
selinux-fix-gpf-on-invalid-policy.patch
sunrpc-handle-enomem-in-rpcb_getport_async.patch
tipc-fix-uninit-value-in-in-tipc_conn_rcv_sub.patch
tipc-fix-uninit-value-in-tipc_nl_compat_bearer_enable.patch
tipc-fix-uninit-value-in-tipc_nl_compat_doit.patch
tipc-fix-uninit-value-in-tipc_nl_compat_link_reset_stats.patch
tipc-fix-uninit-value-in-tipc_nl_compat_link_set.patch
tipc-fix-uninit-value-in-tipc_nl_compat_name_table_dump.patch

54 files changed:
queue-4.19/arm64-dts-marvell-armada-ap806-reserve-psci-area.patch [new file with mode: 0644]
queue-4.19/arm64-kaslr-ensure-randomized-quantities-are-clean-to-the-poc.patch [new file with mode: 0644]
queue-4.19/block-loop-don-t-grab-struct-file-for-vfs_getattr-operation.patch [new file with mode: 0644]
queue-4.19/block-loop-use-global-lock-for-ioctl-operation.patch [new file with mode: 0644]
queue-4.19/block-use-rcu_work-instead-of-call_rcu-to-avoid-sleep-in-softirq.patch [new file with mode: 0644]
queue-4.19/blockdev-fix-livelocks-on-loop-device.patch [new file with mode: 0644]
queue-4.19/bpf-in-__bpf_redirect_no_mac-pull-mac-only-if-present.patch [new file with mode: 0644]
queue-4.19/disable-msi-also-when-pcie-octeon.pcie_disable-on.patch [new file with mode: 0644]
queue-4.19/drm-i915-gvt-fix-mmap-range-check.patch [new file with mode: 0644]
queue-4.19/fix-int_sqrt64-for-very-large-numbers.patch [new file with mode: 0644]
queue-4.19/ipv6-make-icmp6_send-robust-against-null-skb-dev.patch [new file with mode: 0644]
queue-4.19/kbuild-disable-ld_dead_code_data_elimination-with-ftrace-gcc-4.7.patch [new file with mode: 0644]
queue-4.19/loop-avoid-circular-locking-dependency-between-loop_ctl_mutex-and-bd_mutex.patch [new file with mode: 0644]
queue-4.19/loop-drop-caches-if-offset-or-block_size-are-changed.patch [new file with mode: 0644]
queue-4.19/loop-fix-deadlock-when-calling-blkdev_reread_part.patch [new file with mode: 0644]
queue-4.19/loop-fix-double-mutex_unlock-loop_ctl_mutex-in-loop_control_ioctl.patch [new file with mode: 0644]
queue-4.19/loop-fold-__loop_release-into-loop_release.patch [new file with mode: 0644]
queue-4.19/loop-get-rid-of-loop_index_mutex.patch [new file with mode: 0644]
queue-4.19/loop-get-rid-of-nested-acquisition-of-loop_ctl_mutex.patch [new file with mode: 0644]
queue-4.19/loop-move-loop_reread_partitions-out-of-loop_ctl_mutex.patch [new file with mode: 0644]
queue-4.19/loop-move-special-partition-reread-handling-in-loop_clr_fd.patch [new file with mode: 0644]
queue-4.19/loop-push-lo_ctl_mutex-down-into-individual-ioctls.patch [new file with mode: 0644]
queue-4.19/loop-push-loop_ctl_mutex-down-into-loop_clr_fd.patch [new file with mode: 0644]
queue-4.19/loop-push-loop_ctl_mutex-down-to-loop_change_fd.patch [new file with mode: 0644]
queue-4.19/loop-push-loop_ctl_mutex-down-to-loop_get_status.patch [new file with mode: 0644]
queue-4.19/loop-push-loop_ctl_mutex-down-to-loop_set_fd.patch [new file with mode: 0644]
queue-4.19/loop-push-loop_ctl_mutex-down-to-loop_set_status.patch [new file with mode: 0644]
queue-4.19/loop-split-setting-of-lo_state-from-loop_clr_fd.patch [new file with mode: 0644]
queue-4.19/lsm-check-for-null-cred-security-on-free.patch [new file with mode: 0644]
queue-4.19/media-v4l-ioctl-validate-num_planes-for-debug-messages.patch [new file with mode: 0644]
queue-4.19/media-vb2-vb2_mmap-move-lock-up.patch [new file with mode: 0644]
queue-4.19/media-vivid-fix-error-handling-of-kthread_run.patch [new file with mode: 0644]
queue-4.19/media-vivid-set-min-width-height-to-a-value-0.patch [new file with mode: 0644]
queue-4.19/mfd-tps6586x-handle-interrupts-on-suspend.patch [new file with mode: 0644]
queue-4.19/mips-bcm47xx-setup-struct-device-for-the-soc.patch [new file with mode: 0644]
queue-4.19/mips-fix-n32-compat_ipc_parse_version.patch [new file with mode: 0644]
queue-4.19/mips-lantiq-fix-ipi-interrupt-handling.patch [new file with mode: 0644]
queue-4.19/net-dsa-realtek-smi-fix-of-child-node-lookup.patch [new file with mode: 0644]
queue-4.19/netfilter-ebtables-account-ebt_table_info-to-kmemcg.patch [new file with mode: 0644]
queue-4.19/of-properties-add-missing-of_node_put.patch [new file with mode: 0644]
queue-4.19/omap2fb-fix-stack-memory-disclosure.patch [new file with mode: 0644]
queue-4.19/pstore-ram-avoid-allocation-and-leak-of-platform-data.patch [new file with mode: 0644]
queue-4.19/rdma-nldev-don-t-expose-unsafe-global-rkey-to-regular-user.patch [new file with mode: 0644]
queue-4.19/rdma-vmw_pvrdma-return-the-correct-opcode-when-creating-wr.patch [new file with mode: 0644]
queue-4.19/sctp-allocate-sctp_sockaddr_entry-with-kzalloc.patch [new file with mode: 0644]
queue-4.19/selinux-fix-gpf-on-invalid-policy.patch [new file with mode: 0644]
queue-4.19/series
queue-4.19/sunrpc-handle-enomem-in-rpcb_getport_async.patch [new file with mode: 0644]
queue-4.19/tipc-fix-uninit-value-in-in-tipc_conn_rcv_sub.patch [new file with mode: 0644]
queue-4.19/tipc-fix-uninit-value-in-tipc_nl_compat_bearer_enable.patch [new file with mode: 0644]
queue-4.19/tipc-fix-uninit-value-in-tipc_nl_compat_doit.patch [new file with mode: 0644]
queue-4.19/tipc-fix-uninit-value-in-tipc_nl_compat_link_reset_stats.patch [new file with mode: 0644]
queue-4.19/tipc-fix-uninit-value-in-tipc_nl_compat_link_set.patch [new file with mode: 0644]
queue-4.19/tipc-fix-uninit-value-in-tipc_nl_compat_name_table_dump.patch [new file with mode: 0644]

diff --git a/queue-4.19/arm64-dts-marvell-armada-ap806-reserve-psci-area.patch b/queue-4.19/arm64-dts-marvell-armada-ap806-reserve-psci-area.patch
new file mode 100644 (file)
index 0000000..6497599
--- /dev/null
@@ -0,0 +1,49 @@
+From 132ac39cffbcfed80ada38ef0fc6d34d95da7be6 Mon Sep 17 00:00:00 2001
+From: Heinrich Schuchardt <xypron.glpk@gmx.de>
+Date: Fri, 21 Dec 2018 17:45:03 +0100
+Subject: arm64: dts: marvell: armada-ap806: reserve PSCI area
+
+From: Heinrich Schuchardt <xypron.glpk@gmx.de>
+
+commit 132ac39cffbcfed80ada38ef0fc6d34d95da7be6 upstream.
+
+The memory area [0x4000000-0x4200000[ is occupied by the PSCI firmware. Any
+attempt to access it from Linux leads to an immediate crash.
+
+So let's make the same memory reservation as the vendor kernel.
+
+[gregory: added as comment that this region matches the mainline U-boot]
+Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/boot/dts/marvell/armada-ap806.dtsi |   17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
++++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
+@@ -27,6 +27,23 @@
+               method = "smc";
+       };
++      reserved-memory {
++              #address-cells = <2>;
++              #size-cells = <2>;
++              ranges;
++
++              /*
++               * This area matches the mapping done with a
++               * mainline U-Boot, and should be updated by the
++               * bootloader.
++               */
++
++              psci-area@4000000 {
++                      reg = <0x0 0x4000000 0x0 0x200000>;
++                      no-map;
++              };
++      };
++
+       ap806 {
+               #address-cells = <2>;
+               #size-cells = <2>;
diff --git a/queue-4.19/arm64-kaslr-ensure-randomized-quantities-are-clean-to-the-poc.patch b/queue-4.19/arm64-kaslr-ensure-randomized-quantities-are-clean-to-the-poc.patch
new file mode 100644 (file)
index 0000000..0ebc88e
--- /dev/null
@@ -0,0 +1,70 @@
+From 1598ecda7b239e9232dda032bfddeed9d89fab6c Mon Sep 17 00:00:00 2001
+From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Date: Tue, 15 Jan 2019 20:47:07 +0100
+Subject: arm64: kaslr: ensure randomized quantities are clean to the PoC
+
+From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+
+commit 1598ecda7b239e9232dda032bfddeed9d89fab6c upstream.
+
+kaslr_early_init() is called with the kernel mapped at its
+link time offset, and if it returns with a non-zero offset,
+the kernel is unmapped and remapped again at the randomized
+offset.
+
+During its execution, kaslr_early_init() also randomizes the
+base of the module region and of the linear mapping of DRAM,
+and sets two variables accordingly. However, since these
+variables are assigned with the caches on, they may get lost
+during the cache maintenance that occurs when unmapping and
+remapping the kernel, so ensure that these values are cleaned
+to the PoC.
+
+Acked-by: Catalin Marinas <catalin.marinas@arm.com>
+Fixes: f80fb3a3d508 ("arm64: add support for kernel ASLR")
+Cc: <stable@vger.kernel.org> # v4.6+
+Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/kernel/kaslr.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/arch/arm64/kernel/kaslr.c
++++ b/arch/arm64/kernel/kaslr.c
+@@ -14,6 +14,7 @@
+ #include <linux/sched.h>
+ #include <linux/types.h>
++#include <asm/cacheflush.h>
+ #include <asm/fixmap.h>
+ #include <asm/kernel-pgtable.h>
+ #include <asm/memory.h>
+@@ -43,7 +44,7 @@ static __init u64 get_kaslr_seed(void *f
+       return ret;
+ }
+-static __init const u8 *get_cmdline(void *fdt)
++static __init const u8 *kaslr_get_cmdline(void *fdt)
+ {
+       static __initconst const u8 default_cmdline[] = CONFIG_CMDLINE;
+@@ -109,7 +110,7 @@ u64 __init kaslr_early_init(u64 dt_phys)
+        * Check if 'nokaslr' appears on the command line, and
+        * return 0 if that is the case.
+        */
+-      cmdline = get_cmdline(fdt);
++      cmdline = kaslr_get_cmdline(fdt);
+       str = strstr(cmdline, "nokaslr");
+       if (str == cmdline || (str > cmdline && *(str - 1) == ' '))
+               return 0;
+@@ -169,5 +170,8 @@ u64 __init kaslr_early_init(u64 dt_phys)
+       module_alloc_base += (module_range * (seed & ((1 << 21) - 1))) >> 21;
+       module_alloc_base &= PAGE_MASK;
++      __flush_dcache_area(&module_alloc_base, sizeof(module_alloc_base));
++      __flush_dcache_area(&memstart_offset_seed, sizeof(memstart_offset_seed));
++
+       return offset;
+ }
diff --git a/queue-4.19/block-loop-don-t-grab-struct-file-for-vfs_getattr-operation.patch b/queue-4.19/block-loop-don-t-grab-struct-file-for-vfs_getattr-operation.patch
new file mode 100644 (file)
index 0000000..62364c8
--- /dev/null
@@ -0,0 +1,54 @@
+From b1ab5fa309e6c49e4e06270ec67dd7b3e9971d04 Mon Sep 17 00:00:00 2001
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Date: Thu, 8 Nov 2018 14:01:01 +0100
+Subject: block/loop: Don't grab "struct file" for vfs_getattr() operation.
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+commit b1ab5fa309e6c49e4e06270ec67dd7b3e9971d04 upstream.
+
+vfs_getattr() needs "struct path" rather than "struct file".
+Let's use path_get()/path_put() rather than get_file()/fput().
+
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |   10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -1205,7 +1205,7 @@ loop_set_status(struct loop_device *lo,
+ static int
+ loop_get_status(struct loop_device *lo, struct loop_info64 *info)
+ {
+-      struct file *file;
++      struct path path;
+       struct kstat stat;
+       int ret;
+@@ -1230,16 +1230,16 @@ loop_get_status(struct loop_device *lo,
+       }
+       /* Drop lo_ctl_mutex while we call into the filesystem. */
+-      file = get_file(lo->lo_backing_file);
++      path = lo->lo_backing_file->f_path;
++      path_get(&path);
+       mutex_unlock(&lo->lo_ctl_mutex);
+-      ret = vfs_getattr(&file->f_path, &stat, STATX_INO,
+-                        AT_STATX_SYNC_AS_STAT);
++      ret = vfs_getattr(&path, &stat, STATX_INO, AT_STATX_SYNC_AS_STAT);
+       if (!ret) {
+               info->lo_device = huge_encode_dev(stat.dev);
+               info->lo_inode = stat.ino;
+               info->lo_rdevice = huge_encode_dev(stat.rdev);
+       }
+-      fput(file);
++      path_put(&path);
+       return ret;
+ }
diff --git a/queue-4.19/block-loop-use-global-lock-for-ioctl-operation.patch b/queue-4.19/block-loop-use-global-lock-for-ioctl-operation.patch
new file mode 100644 (file)
index 0000000..c6d8c0f
--- /dev/null
@@ -0,0 +1,267 @@
+From 310ca162d779efee8a2dc3731439680f3e9c1e86 Mon Sep 17 00:00:00 2001
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Date: Thu, 8 Nov 2018 14:01:02 +0100
+Subject: block/loop: Use global lock for ioctl() operation.
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+commit 310ca162d779efee8a2dc3731439680f3e9c1e86 upstream.
+
+syzbot is reporting NULL pointer dereference [1] which is caused by
+race condition between ioctl(loop_fd, LOOP_CLR_FD, 0) versus
+ioctl(other_loop_fd, LOOP_SET_FD, loop_fd) due to traversing other
+loop devices at loop_validate_file() without holding corresponding
+lo->lo_ctl_mutex locks.
+
+Since ioctl() request on loop devices is not frequent operation, we don't
+need fine grained locking. Let's use global lock in order to allow safe
+traversal at loop_validate_file().
+
+Note that syzbot is also reporting circular locking dependency between
+bdev->bd_mutex and lo->lo_ctl_mutex [2] which is caused by calling
+blkdev_reread_part() with lock held. This patch does not address it.
+
+[1] https://syzkaller.appspot.com/bug?id=f3cfe26e785d85f9ee259f385515291d21bd80a3
+[2] https://syzkaller.appspot.com/bug?id=bf154052f0eea4bc7712499e4569505907d15889
+
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Reported-by: syzbot <syzbot+bf89c128e05dd6c62523@syzkaller.appspotmail.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |   58 +++++++++++++++++++++++++--------------------------
+ drivers/block/loop.h |    1 
+ 2 files changed, 29 insertions(+), 30 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -84,6 +84,7 @@
+ static DEFINE_IDR(loop_index_idr);
+ static DEFINE_MUTEX(loop_index_mutex);
++static DEFINE_MUTEX(loop_ctl_mutex);
+ static int max_part;
+ static int part_shift;
+@@ -1047,7 +1048,7 @@ static int loop_clr_fd(struct loop_devic
+        */
+       if (atomic_read(&lo->lo_refcnt) > 1) {
+               lo->lo_flags |= LO_FLAGS_AUTOCLEAR;
+-              mutex_unlock(&lo->lo_ctl_mutex);
++              mutex_unlock(&loop_ctl_mutex);
+               return 0;
+       }
+@@ -1100,12 +1101,12 @@ static int loop_clr_fd(struct loop_devic
+       if (!part_shift)
+               lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN;
+       loop_unprepare_queue(lo);
+-      mutex_unlock(&lo->lo_ctl_mutex);
++      mutex_unlock(&loop_ctl_mutex);
+       /*
+-       * Need not hold lo_ctl_mutex to fput backing file.
+-       * Calling fput holding lo_ctl_mutex triggers a circular
++       * Need not hold loop_ctl_mutex to fput backing file.
++       * Calling fput holding loop_ctl_mutex triggers a circular
+        * lock dependency possibility warning as fput can take
+-       * bd_mutex which is usually taken before lo_ctl_mutex.
++       * bd_mutex which is usually taken before loop_ctl_mutex.
+        */
+       fput(filp);
+       return 0;
+@@ -1210,7 +1211,7 @@ loop_get_status(struct loop_device *lo,
+       int ret;
+       if (lo->lo_state != Lo_bound) {
+-              mutex_unlock(&lo->lo_ctl_mutex);
++              mutex_unlock(&loop_ctl_mutex);
+               return -ENXIO;
+       }
+@@ -1229,10 +1230,10 @@ loop_get_status(struct loop_device *lo,
+                      lo->lo_encrypt_key_size);
+       }
+-      /* Drop lo_ctl_mutex while we call into the filesystem. */
++      /* Drop loop_ctl_mutex while we call into the filesystem. */
+       path = lo->lo_backing_file->f_path;
+       path_get(&path);
+-      mutex_unlock(&lo->lo_ctl_mutex);
++      mutex_unlock(&loop_ctl_mutex);
+       ret = vfs_getattr(&path, &stat, STATX_INO, AT_STATX_SYNC_AS_STAT);
+       if (!ret) {
+               info->lo_device = huge_encode_dev(stat.dev);
+@@ -1324,7 +1325,7 @@ loop_get_status_old(struct loop_device *
+       int err;
+       if (!arg) {
+-              mutex_unlock(&lo->lo_ctl_mutex);
++              mutex_unlock(&loop_ctl_mutex);
+               return -EINVAL;
+       }
+       err = loop_get_status(lo, &info64);
+@@ -1342,7 +1343,7 @@ loop_get_status64(struct loop_device *lo
+       int err;
+       if (!arg) {
+-              mutex_unlock(&lo->lo_ctl_mutex);
++              mutex_unlock(&loop_ctl_mutex);
+               return -EINVAL;
+       }
+       err = loop_get_status(lo, &info64);
+@@ -1400,7 +1401,7 @@ static int lo_ioctl(struct block_device
+       struct loop_device *lo = bdev->bd_disk->private_data;
+       int err;
+-      err = mutex_lock_killable_nested(&lo->lo_ctl_mutex, 1);
++      err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
+       if (err)
+               goto out_unlocked;
+@@ -1412,7 +1413,7 @@ static int lo_ioctl(struct block_device
+               err = loop_change_fd(lo, bdev, arg);
+               break;
+       case LOOP_CLR_FD:
+-              /* loop_clr_fd would have unlocked lo_ctl_mutex on success */
++              /* loop_clr_fd would have unlocked loop_ctl_mutex on success */
+               err = loop_clr_fd(lo);
+               if (!err)
+                       goto out_unlocked;
+@@ -1425,7 +1426,7 @@ static int lo_ioctl(struct block_device
+               break;
+       case LOOP_GET_STATUS:
+               err = loop_get_status_old(lo, (struct loop_info __user *) arg);
+-              /* loop_get_status() unlocks lo_ctl_mutex */
++              /* loop_get_status() unlocks loop_ctl_mutex */
+               goto out_unlocked;
+       case LOOP_SET_STATUS64:
+               err = -EPERM;
+@@ -1435,7 +1436,7 @@ static int lo_ioctl(struct block_device
+               break;
+       case LOOP_GET_STATUS64:
+               err = loop_get_status64(lo, (struct loop_info64 __user *) arg);
+-              /* loop_get_status() unlocks lo_ctl_mutex */
++              /* loop_get_status() unlocks loop_ctl_mutex */
+               goto out_unlocked;
+       case LOOP_SET_CAPACITY:
+               err = -EPERM;
+@@ -1455,7 +1456,7 @@ static int lo_ioctl(struct block_device
+       default:
+               err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
+       }
+-      mutex_unlock(&lo->lo_ctl_mutex);
++      mutex_unlock(&loop_ctl_mutex);
+ out_unlocked:
+       return err;
+@@ -1572,7 +1573,7 @@ loop_get_status_compat(struct loop_devic
+       int err;
+       if (!arg) {
+-              mutex_unlock(&lo->lo_ctl_mutex);
++              mutex_unlock(&loop_ctl_mutex);
+               return -EINVAL;
+       }
+       err = loop_get_status(lo, &info64);
+@@ -1589,19 +1590,19 @@ static int lo_compat_ioctl(struct block_
+       switch(cmd) {
+       case LOOP_SET_STATUS:
+-              err = mutex_lock_killable(&lo->lo_ctl_mutex);
++              err = mutex_lock_killable(&loop_ctl_mutex);
+               if (!err) {
+                       err = loop_set_status_compat(lo,
+                                                    (const struct compat_loop_info __user *)arg);
+-                      mutex_unlock(&lo->lo_ctl_mutex);
++                      mutex_unlock(&loop_ctl_mutex);
+               }
+               break;
+       case LOOP_GET_STATUS:
+-              err = mutex_lock_killable(&lo->lo_ctl_mutex);
++              err = mutex_lock_killable(&loop_ctl_mutex);
+               if (!err) {
+                       err = loop_get_status_compat(lo,
+                                                    (struct compat_loop_info __user *)arg);
+-                      /* loop_get_status() unlocks lo_ctl_mutex */
++                      /* loop_get_status() unlocks loop_ctl_mutex */
+               }
+               break;
+       case LOOP_SET_CAPACITY:
+@@ -1648,7 +1649,7 @@ static void __lo_release(struct loop_dev
+       if (atomic_dec_return(&lo->lo_refcnt))
+               return;
+-      mutex_lock(&lo->lo_ctl_mutex);
++      mutex_lock(&loop_ctl_mutex);
+       if (lo->lo_flags & LO_FLAGS_AUTOCLEAR) {
+               /*
+                * In autoclear mode, stop the loop thread
+@@ -1666,7 +1667,7 @@ static void __lo_release(struct loop_dev
+               blk_mq_unfreeze_queue(lo->lo_queue);
+       }
+-      mutex_unlock(&lo->lo_ctl_mutex);
++      mutex_unlock(&loop_ctl_mutex);
+ }
+ static void lo_release(struct gendisk *disk, fmode_t mode)
+@@ -1712,10 +1713,10 @@ static int unregister_transfer_cb(int id
+       struct loop_device *lo = ptr;
+       struct loop_func_table *xfer = data;
+-      mutex_lock(&lo->lo_ctl_mutex);
++      mutex_lock(&loop_ctl_mutex);
+       if (lo->lo_encryption == xfer)
+               loop_release_xfer(lo);
+-      mutex_unlock(&lo->lo_ctl_mutex);
++      mutex_unlock(&loop_ctl_mutex);
+       return 0;
+ }
+@@ -1896,7 +1897,6 @@ static int loop_add(struct loop_device *
+       if (!part_shift)
+               disk->flags |= GENHD_FL_NO_PART_SCAN;
+       disk->flags |= GENHD_FL_EXT_DEVT;
+-      mutex_init(&lo->lo_ctl_mutex);
+       atomic_set(&lo->lo_refcnt, 0);
+       lo->lo_number           = i;
+       spin_lock_init(&lo->lo_lock);
+@@ -2009,21 +2009,21 @@ static long loop_control_ioctl(struct fi
+               ret = loop_lookup(&lo, parm);
+               if (ret < 0)
+                       break;
+-              ret = mutex_lock_killable(&lo->lo_ctl_mutex);
++              ret = mutex_lock_killable(&loop_ctl_mutex);
+               if (ret)
+                       break;
+               if (lo->lo_state != Lo_unbound) {
+                       ret = -EBUSY;
+-                      mutex_unlock(&lo->lo_ctl_mutex);
++                      mutex_unlock(&loop_ctl_mutex);
+                       break;
+               }
+               if (atomic_read(&lo->lo_refcnt) > 0) {
+                       ret = -EBUSY;
+-                      mutex_unlock(&lo->lo_ctl_mutex);
++                      mutex_unlock(&loop_ctl_mutex);
+                       break;
+               }
+               lo->lo_disk->private_data = NULL;
+-              mutex_unlock(&lo->lo_ctl_mutex);
++              mutex_unlock(&loop_ctl_mutex);
+               idr_remove(&loop_index_idr, lo->lo_number);
+               loop_remove(lo);
+               break;
+--- a/drivers/block/loop.h
++++ b/drivers/block/loop.h
+@@ -54,7 +54,6 @@ struct loop_device {
+       spinlock_t              lo_lock;
+       int                     lo_state;
+-      struct mutex            lo_ctl_mutex;
+       struct kthread_worker   worker;
+       struct task_struct      *worker_task;
+       bool                    use_dio;
diff --git a/queue-4.19/block-use-rcu_work-instead-of-call_rcu-to-avoid-sleep-in-softirq.patch b/queue-4.19/block-use-rcu_work-instead-of-call_rcu-to-avoid-sleep-in-softirq.patch
new file mode 100644 (file)
index 0000000..d317e64
--- /dev/null
@@ -0,0 +1,115 @@
+From 94a2c3a32b62e868dc1e3d854326745a7f1b8c7a Mon Sep 17 00:00:00 2001
+From: Yufen Yu <yuyufen@huawei.com>
+Date: Wed, 28 Nov 2018 16:42:01 +0800
+Subject: block: use rcu_work instead of call_rcu to avoid sleep in softirq
+
+From: Yufen Yu <yuyufen@huawei.com>
+
+commit 94a2c3a32b62e868dc1e3d854326745a7f1b8c7a upstream.
+
+We recently got a stack by syzkaller like this:
+
+BUG: sleeping function called from invalid context at mm/slab.h:361
+in_atomic(): 1, irqs_disabled(): 0, pid: 6644, name: blkid
+INFO: lockdep is turned off.
+CPU: 1 PID: 6644 Comm: blkid Not tainted 4.4.163-514.55.6.9.x86_64+ #76
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014
+ 0000000000000000 5ba6a6b879e50c00 ffff8801f6b07b10 ffffffff81cb2194
+ 0000000041b58ab3 ffffffff833c7745 ffffffff81cb2080 5ba6a6b879e50c00
+ 0000000000000000 0000000000000001 0000000000000004 0000000000000000
+Call Trace:
+ <IRQ>  [<ffffffff81cb2194>] __dump_stack lib/dump_stack.c:15 [inline]
+ <IRQ>  [<ffffffff81cb2194>] dump_stack+0x114/0x1a0 lib/dump_stack.c:51
+ [<ffffffff8129a981>] ___might_sleep+0x291/0x490 kernel/sched/core.c:7675
+ [<ffffffff8129ac33>] __might_sleep+0xb3/0x270 kernel/sched/core.c:7637
+ [<ffffffff81794c13>] slab_pre_alloc_hook mm/slab.h:361 [inline]
+ [<ffffffff81794c13>] slab_alloc_node mm/slub.c:2610 [inline]
+ [<ffffffff81794c13>] slab_alloc mm/slub.c:2692 [inline]
+ [<ffffffff81794c13>] kmem_cache_alloc_trace+0x2c3/0x5c0 mm/slub.c:2709
+ [<ffffffff81cbe9a7>] kmalloc include/linux/slab.h:479 [inline]
+ [<ffffffff81cbe9a7>] kzalloc include/linux/slab.h:623 [inline]
+ [<ffffffff81cbe9a7>] kobject_uevent_env+0x2c7/0x1150 lib/kobject_uevent.c:227
+ [<ffffffff81cbf84f>] kobject_uevent+0x1f/0x30 lib/kobject_uevent.c:374
+ [<ffffffff81cbb5b9>] kobject_cleanup lib/kobject.c:633 [inline]
+ [<ffffffff81cbb5b9>] kobject_release+0x229/0x440 lib/kobject.c:675
+ [<ffffffff81cbb0a2>] kref_sub include/linux/kref.h:73 [inline]
+ [<ffffffff81cbb0a2>] kref_put include/linux/kref.h:98 [inline]
+ [<ffffffff81cbb0a2>] kobject_put+0x72/0xd0 lib/kobject.c:692
+ [<ffffffff8216f095>] put_device+0x25/0x30 drivers/base/core.c:1237
+ [<ffffffff81c4cc34>] delete_partition_rcu_cb+0x1d4/0x2f0 block/partition-generic.c:232
+ [<ffffffff813c08bc>] __rcu_reclaim kernel/rcu/rcu.h:118 [inline]
+ [<ffffffff813c08bc>] rcu_do_batch kernel/rcu/tree.c:2705 [inline]
+ [<ffffffff813c08bc>] invoke_rcu_callbacks kernel/rcu/tree.c:2973 [inline]
+ [<ffffffff813c08bc>] __rcu_process_callbacks kernel/rcu/tree.c:2940 [inline]
+ [<ffffffff813c08bc>] rcu_process_callbacks+0x59c/0x1c70 kernel/rcu/tree.c:2957
+ [<ffffffff8120f509>] __do_softirq+0x299/0xe20 kernel/softirq.c:273
+ [<ffffffff81210496>] invoke_softirq kernel/softirq.c:350 [inline]
+ [<ffffffff81210496>] irq_exit+0x216/0x2c0 kernel/softirq.c:391
+ [<ffffffff82c2cd7b>] exiting_irq arch/x86/include/asm/apic.h:652 [inline]
+ [<ffffffff82c2cd7b>] smp_apic_timer_interrupt+0x8b/0xc0 arch/x86/kernel/apic/apic.c:926
+ [<ffffffff82c2bc25>] apic_timer_interrupt+0xa5/0xb0 arch/x86/entry/entry_64.S:746
+ <EOI>  [<ffffffff814cbf40>] ? audit_kill_trees+0x180/0x180
+ [<ffffffff8187d2f7>] fd_install+0x57/0x80 fs/file.c:626
+ [<ffffffff8180989e>] do_sys_open+0x45e/0x550 fs/open.c:1043
+ [<ffffffff818099c2>] SYSC_open fs/open.c:1055 [inline]
+ [<ffffffff818099c2>] SyS_open+0x32/0x40 fs/open.c:1050
+ [<ffffffff82c299e1>] entry_SYSCALL_64_fastpath+0x1e/0x9a
+
+In softirq context, we call rcu callback function delete_partition_rcu_cb(),
+which may allocate memory by kzalloc with GFP_KERNEL flag. If the
+allocation cannot be satisfied, it may sleep. However, That is not allowed
+in softirq contex.
+
+Although we found this problem on linux 4.4, the latest kernel version
+seems to have this problem as well. And it is very similar to the
+previous one:
+       https://lkml.org/lkml/2018/7/9/391
+
+Fix it by using RCU workqueue, which allows sleep.
+
+Reviewed-by: Paul E. McKenney <paulmck@linux.ibm.com>
+Signed-off-by: Yufen Yu <yuyufen@huawei.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ block/partition-generic.c |    8 +++++---
+ include/linux/genhd.h     |    2 +-
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+--- a/block/partition-generic.c
++++ b/block/partition-generic.c
+@@ -249,9 +249,10 @@ struct device_type part_type = {
+       .uevent         = part_uevent,
+ };
+-static void delete_partition_rcu_cb(struct rcu_head *head)
++static void delete_partition_work_fn(struct work_struct *work)
+ {
+-      struct hd_struct *part = container_of(head, struct hd_struct, rcu_head);
++      struct hd_struct *part = container_of(to_rcu_work(work), struct hd_struct,
++                                      rcu_work);
+       part->start_sect = 0;
+       part->nr_sects = 0;
+@@ -262,7 +263,8 @@ static void delete_partition_rcu_cb(stru
+ void __delete_partition(struct percpu_ref *ref)
+ {
+       struct hd_struct *part = container_of(ref, struct hd_struct, ref);
+-      call_rcu(&part->rcu_head, delete_partition_rcu_cb);
++      INIT_RCU_WORK(&part->rcu_work, delete_partition_work_fn);
++      queue_rcu_work(system_wq, &part->rcu_work);
+ }
+ /*
+--- a/include/linux/genhd.h
++++ b/include/linux/genhd.h
+@@ -129,7 +129,7 @@ struct hd_struct {
+       struct disk_stats dkstats;
+ #endif
+       struct percpu_ref ref;
+-      struct rcu_head rcu_head;
++      struct rcu_work rcu_work;
+ };
+ #define GENHD_FL_REMOVABLE                    1
diff --git a/queue-4.19/blockdev-fix-livelocks-on-loop-device.patch b/queue-4.19/blockdev-fix-livelocks-on-loop-device.patch
new file mode 100644 (file)
index 0000000..b69b8a0
--- /dev/null
@@ -0,0 +1,123 @@
+From 04906b2f542c23626b0ef6219b808406f8dddbe9 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Mon, 14 Jan 2019 09:48:10 +0100
+Subject: blockdev: Fix livelocks on loop device
+
+From: Jan Kara <jack@suse.cz>
+
+commit 04906b2f542c23626b0ef6219b808406f8dddbe9 upstream.
+
+bd_set_size() updates also block device's block size. This is somewhat
+unexpected from its name and at this point, only blkdev_open() uses this
+functionality. Furthermore, this can result in changing block size under
+a filesystem mounted on a loop device which leads to livelocks inside
+__getblk_gfp() like:
+
+Sending NMI from CPU 0 to CPUs 1:
+NMI backtrace for cpu 1
+CPU: 1 PID: 10863 Comm: syz-executor0 Not tainted 4.18.0-rc5+ #151
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google
+01/01/2011
+RIP: 0010:__sanitizer_cov_trace_pc+0x3f/0x50 kernel/kcov.c:106
+...
+Call Trace:
+ init_page_buffers+0x3e2/0x530 fs/buffer.c:904
+ grow_dev_page fs/buffer.c:947 [inline]
+ grow_buffers fs/buffer.c:1009 [inline]
+ __getblk_slow fs/buffer.c:1036 [inline]
+ __getblk_gfp+0x906/0xb10 fs/buffer.c:1313
+ __bread_gfp+0x2d/0x310 fs/buffer.c:1347
+ sb_bread include/linux/buffer_head.h:307 [inline]
+ fat12_ent_bread+0x14e/0x3d0 fs/fat/fatent.c:75
+ fat_ent_read_block fs/fat/fatent.c:441 [inline]
+ fat_alloc_clusters+0x8ce/0x16e0 fs/fat/fatent.c:489
+ fat_add_cluster+0x7a/0x150 fs/fat/inode.c:101
+ __fat_get_block fs/fat/inode.c:148 [inline]
+...
+
+Trivial reproducer for the problem looks like:
+
+truncate -s 1G /tmp/image
+losetup /dev/loop0 /tmp/image
+mkfs.ext4 -b 1024 /dev/loop0
+mount -t ext4 /dev/loop0 /mnt
+losetup -c /dev/loop0
+l /mnt
+
+Fix the problem by moving initialization of a block device block size
+into a separate function and call it when needed.
+
+Thanks to Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> for help with
+debugging the problem.
+
+Reported-by: syzbot+9933e4476f365f5d5a1b@syzkaller.appspotmail.com
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/block_dev.c |   28 ++++++++++++++++++----------
+ 1 file changed, 18 insertions(+), 10 deletions(-)
+
+--- a/fs/block_dev.c
++++ b/fs/block_dev.c
+@@ -104,6 +104,20 @@ void invalidate_bdev(struct block_device
+ }
+ EXPORT_SYMBOL(invalidate_bdev);
++static void set_init_blocksize(struct block_device *bdev)
++{
++      unsigned bsize = bdev_logical_block_size(bdev);
++      loff_t size = i_size_read(bdev->bd_inode);
++
++      while (bsize < PAGE_SIZE) {
++              if (size & bsize)
++                      break;
++              bsize <<= 1;
++      }
++      bdev->bd_block_size = bsize;
++      bdev->bd_inode->i_blkbits = blksize_bits(bsize);
++}
++
+ int set_blocksize(struct block_device *bdev, int size)
+ {
+       /* Size must be a power of two, and between 512 and PAGE_SIZE */
+@@ -1408,18 +1422,9 @@ EXPORT_SYMBOL(check_disk_change);
+ void bd_set_size(struct block_device *bdev, loff_t size)
+ {
+-      unsigned bsize = bdev_logical_block_size(bdev);
+-
+       inode_lock(bdev->bd_inode);
+       i_size_write(bdev->bd_inode, size);
+       inode_unlock(bdev->bd_inode);
+-      while (bsize < PAGE_SIZE) {
+-              if (size & bsize)
+-                      break;
+-              bsize <<= 1;
+-      }
+-      bdev->bd_block_size = bsize;
+-      bdev->bd_inode->i_blkbits = blksize_bits(bsize);
+ }
+ EXPORT_SYMBOL(bd_set_size);
+@@ -1496,8 +1501,10 @@ static int __blkdev_get(struct block_dev
+                               }
+                       }
+-                      if (!ret)
++                      if (!ret) {
+                               bd_set_size(bdev,(loff_t)get_capacity(disk)<<9);
++                              set_init_blocksize(bdev);
++                      }
+                       /*
+                        * If the device is invalidated, rescan partition
+@@ -1532,6 +1539,7 @@ static int __blkdev_get(struct block_dev
+                               goto out_clear;
+                       }
+                       bd_set_size(bdev, (loff_t)bdev->bd_part->nr_sects << 9);
++                      set_init_blocksize(bdev);
+               }
+               if (bdev->bd_bdi == &noop_backing_dev_info)
diff --git a/queue-4.19/bpf-in-__bpf_redirect_no_mac-pull-mac-only-if-present.patch b/queue-4.19/bpf-in-__bpf_redirect_no_mac-pull-mac-only-if-present.patch
new file mode 100644 (file)
index 0000000..a492fec
--- /dev/null
@@ -0,0 +1,115 @@
+From e7c87bd6cc4ec7b0ac1ed0a88a58f8206c577488 Mon Sep 17 00:00:00 2001
+From: Willem de Bruijn <willemb@google.com>
+Date: Tue, 15 Jan 2019 20:19:22 -0500
+Subject: bpf: in __bpf_redirect_no_mac pull mac only if present
+
+From: Willem de Bruijn <willemb@google.com>
+
+commit e7c87bd6cc4ec7b0ac1ed0a88a58f8206c577488 upstream.
+
+Syzkaller was able to construct a packet of negative length by
+redirecting from bpf_prog_test_run_skb with BPF_PROG_TYPE_LWT_XMIT:
+
+    BUG: KASAN: slab-out-of-bounds in memcpy include/linux/string.h:345 [inline]
+    BUG: KASAN: slab-out-of-bounds in skb_copy_from_linear_data include/linux/skbuff.h:3421 [inline]
+    BUG: KASAN: slab-out-of-bounds in __pskb_copy_fclone+0x2dd/0xeb0 net/core/skbuff.c:1395
+    Read of size 4294967282 at addr ffff8801d798009c by task syz-executor2/12942
+
+    kasan_report.cold.9+0x242/0x309 mm/kasan/report.c:412
+    check_memory_region_inline mm/kasan/kasan.c:260 [inline]
+    check_memory_region+0x13e/0x1b0 mm/kasan/kasan.c:267
+    memcpy+0x23/0x50 mm/kasan/kasan.c:302
+    memcpy include/linux/string.h:345 [inline]
+    skb_copy_from_linear_data include/linux/skbuff.h:3421 [inline]
+    __pskb_copy_fclone+0x2dd/0xeb0 net/core/skbuff.c:1395
+    __pskb_copy include/linux/skbuff.h:1053 [inline]
+    pskb_copy include/linux/skbuff.h:2904 [inline]
+    skb_realloc_headroom+0xe7/0x120 net/core/skbuff.c:1539
+    ipip6_tunnel_xmit net/ipv6/sit.c:965 [inline]
+    sit_tunnel_xmit+0xe1b/0x30d0 net/ipv6/sit.c:1029
+    __netdev_start_xmit include/linux/netdevice.h:4325 [inline]
+    netdev_start_xmit include/linux/netdevice.h:4334 [inline]
+    xmit_one net/core/dev.c:3219 [inline]
+    dev_hard_start_xmit+0x295/0xc90 net/core/dev.c:3235
+    __dev_queue_xmit+0x2f0d/0x3950 net/core/dev.c:3805
+    dev_queue_xmit+0x17/0x20 net/core/dev.c:3838
+    __bpf_tx_skb net/core/filter.c:2016 [inline]
+    __bpf_redirect_common net/core/filter.c:2054 [inline]
+    __bpf_redirect+0x5cf/0xb20 net/core/filter.c:2061
+    ____bpf_clone_redirect net/core/filter.c:2094 [inline]
+    bpf_clone_redirect+0x2f6/0x490 net/core/filter.c:2066
+    bpf_prog_41f2bcae09cd4ac3+0xb25/0x1000
+
+The generated test constructs a packet with mac header, network
+header, skb->data pointing to network header and skb->len 0.
+
+Redirecting to a sit0 through __bpf_redirect_no_mac pulls the
+mac length, even though skb->data already is at skb->network_header.
+bpf_prog_test_run_skb has already pulled it as LWT_XMIT !is_l2.
+
+Update the offset calculation to pull only if skb->data differs
+from skb->network_header, which is not true in this case.
+
+The test itself can be run only from commit 1cf1cae963c2 ("bpf:
+introduce BPF_PROG_TEST_RUN command"), but the same type of packets
+with skb at network header could already be built from lwt xmit hooks,
+so this fix is more relevant to that commit.
+
+Also set the mac header on redirect from LWT_XMIT, as even after this
+change to __bpf_redirect_no_mac that field is expected to be set, but
+is not yet in ip_finish_output2.
+
+Fixes: 3a0af8fd61f9 ("bpf: BPF for lightweight tunnel infrastructure")
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Acked-by: Martin KaFai Lau <kafai@fb.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/core/filter.c  |   21 +++++++++++----------
+ net/core/lwt_bpf.c |    1 +
+ 2 files changed, 12 insertions(+), 10 deletions(-)
+
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -2018,18 +2018,19 @@ static inline int __bpf_tx_skb(struct ne
+ static int __bpf_redirect_no_mac(struct sk_buff *skb, struct net_device *dev,
+                                u32 flags)
+ {
+-      /* skb->mac_len is not set on normal egress */
+-      unsigned int mlen = skb->network_header - skb->mac_header;
++      unsigned int mlen = skb_network_offset(skb);
+-      __skb_pull(skb, mlen);
++      if (mlen) {
++              __skb_pull(skb, mlen);
+-      /* At ingress, the mac header has already been pulled once.
+-       * At egress, skb_pospull_rcsum has to be done in case that
+-       * the skb is originated from ingress (i.e. a forwarded skb)
+-       * to ensure that rcsum starts at net header.
+-       */
+-      if (!skb_at_tc_ingress(skb))
+-              skb_postpull_rcsum(skb, skb_mac_header(skb), mlen);
++              /* At ingress, the mac header has already been pulled once.
++               * At egress, skb_pospull_rcsum has to be done in case that
++               * the skb is originated from ingress (i.e. a forwarded skb)
++               * to ensure that rcsum starts at net header.
++               */
++              if (!skb_at_tc_ingress(skb))
++                      skb_postpull_rcsum(skb, skb_mac_header(skb), mlen);
++      }
+       skb_pop_mac_header(skb);
+       skb_reset_mac_len(skb);
+       return flags & BPF_F_INGRESS ?
+--- a/net/core/lwt_bpf.c
++++ b/net/core/lwt_bpf.c
+@@ -63,6 +63,7 @@ static int run_lwt_bpf(struct sk_buff *s
+                                    lwt->name ? : "<unknown>");
+                       ret = BPF_OK;
+               } else {
++                      skb_reset_mac_header(skb);
+                       ret = skb_do_redirect(skb);
+                       if (ret == 0)
+                               ret = BPF_REDIRECT;
diff --git a/queue-4.19/disable-msi-also-when-pcie-octeon.pcie_disable-on.patch b/queue-4.19/disable-msi-also-when-pcie-octeon.pcie_disable-on.patch
new file mode 100644 (file)
index 0000000..195aaaf
--- /dev/null
@@ -0,0 +1,40 @@
+From a214720cbf50cd8c3f76bbb9c3f5c283910e9d33 Mon Sep 17 00:00:00 2001
+From: YunQiang Su <ysu@wavecomp.com>
+Date: Tue, 8 Jan 2019 13:45:10 +0800
+Subject: Disable MSI also when pcie-octeon.pcie_disable on
+
+From: YunQiang Su <ysu@wavecomp.com>
+
+commit a214720cbf50cd8c3f76bbb9c3f5c283910e9d33 upstream.
+
+Octeon has an boot-time option to disable pcie.
+
+Since MSI depends on PCI-E, we should also disable MSI also with
+this option is on in order to avoid inadvertently accessing PCIe
+registers.
+
+Signed-off-by: YunQiang Su <ysu@wavecomp.com>
+Signed-off-by: Paul Burton <paul.burton@mips.com>
+Cc: pburton@wavecomp.com
+Cc: linux-mips@vger.kernel.org
+Cc: aaro.koskinen@iki.fi
+Cc: stable@vger.kernel.org # v3.3+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/pci/msi-octeon.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/arch/mips/pci/msi-octeon.c
++++ b/arch/mips/pci/msi-octeon.c
+@@ -369,7 +369,9 @@ int __init octeon_msi_initialize(void)
+       int irq;
+       struct irq_chip *msi;
+-      if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_PCIE) {
++      if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_INVALID) {
++              return 0;
++      } else if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_PCIE) {
+               msi_rcv_reg[0] = CVMX_PEXP_NPEI_MSI_RCV0;
+               msi_rcv_reg[1] = CVMX_PEXP_NPEI_MSI_RCV1;
+               msi_rcv_reg[2] = CVMX_PEXP_NPEI_MSI_RCV2;
diff --git a/queue-4.19/drm-i915-gvt-fix-mmap-range-check.patch b/queue-4.19/drm-i915-gvt-fix-mmap-range-check.patch
new file mode 100644 (file)
index 0000000..b44fa4e
--- /dev/null
@@ -0,0 +1,58 @@
+From 51b00d8509dc69c98740da2ad07308b630d3eb7d Mon Sep 17 00:00:00 2001
+From: Zhenyu Wang <zhenyuw@linux.intel.com>
+Date: Fri, 11 Jan 2019 13:58:53 +0800
+Subject: drm/i915/gvt: Fix mmap range check
+
+From: Zhenyu Wang <zhenyuw@linux.intel.com>
+
+commit 51b00d8509dc69c98740da2ad07308b630d3eb7d upstream.
+
+This is to fix missed mmap range check on vGPU bar2 region
+and only allow to map vGPU allocated GMADDR range, which means
+user space should support sparse mmap to get proper offset for
+mmap vGPU aperture. And this takes care of actual pgoff in mmap
+request as original code always does from beginning of vGPU
+aperture.
+
+Fixes: 659643f7d814 ("drm/i915/gvt/kvmgt: add vfio/mdev support to KVMGT")
+Cc: "Monroy, Rodrigo Axel" <rodrigo.axel.monroy@intel.com>
+Cc: "Orrala Contreras, Alfredo" <alfredo.orrala.contreras@intel.com>
+Cc: stable@vger.kernel.org # v4.10+
+Reviewed-by: Hang Yuan <hang.yuan@intel.com>
+Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/gvt/kvmgt.c |   14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
++++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
+@@ -996,7 +996,7 @@ static int intel_vgpu_mmap(struct mdev_d
+ {
+       unsigned int index;
+       u64 virtaddr;
+-      unsigned long req_size, pgoff = 0;
++      unsigned long req_size, pgoff, req_start;
+       pgprot_t pg_prot;
+       struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);
+@@ -1014,7 +1014,17 @@ static int intel_vgpu_mmap(struct mdev_d
+       pg_prot = vma->vm_page_prot;
+       virtaddr = vma->vm_start;
+       req_size = vma->vm_end - vma->vm_start;
+-      pgoff = vgpu_aperture_pa_base(vgpu) >> PAGE_SHIFT;
++      pgoff = vma->vm_pgoff &
++              ((1U << (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT)) - 1);
++      req_start = pgoff << PAGE_SHIFT;
++
++      if (!intel_vgpu_in_aperture(vgpu, req_start))
++              return -EINVAL;
++      if (req_start + req_size >
++          vgpu_aperture_offset(vgpu) + vgpu_aperture_sz(vgpu))
++              return -EINVAL;
++
++      pgoff = (gvt_aperture_pa_base(vgpu->gvt) >> PAGE_SHIFT) + pgoff;
+       return remap_pfn_range(vma, virtaddr, pgoff, req_size, pg_prot);
+ }
diff --git a/queue-4.19/fix-int_sqrt64-for-very-large-numbers.patch b/queue-4.19/fix-int_sqrt64-for-very-large-numbers.patch
new file mode 100644 (file)
index 0000000..378c591
--- /dev/null
@@ -0,0 +1,43 @@
+From fbfaf851902cd9293f392f3a1735e0543016d530 Mon Sep 17 00:00:00 2001
+From: Florian La Roche <florian.laroche@googlemail.com>
+Date: Sat, 19 Jan 2019 16:14:50 +0100
+Subject: fix int_sqrt64() for very large numbers
+
+From: Florian La Roche <florian.laroche@googlemail.com>
+
+commit fbfaf851902cd9293f392f3a1735e0543016d530 upstream.
+
+If an input number x for int_sqrt64() has the highest bit set, then
+fls64(x) is 64.  (1UL << 64) is an overflow and breaks the algorithm.
+
+Subtracting 1 is a better guess for the initial value of m anyway and
+that's what also done in int_sqrt() implicitly [*].
+
+[*] Note how int_sqrt() uses __fls() with two underscores, which already
+    returns the proper raw bit number.
+
+    In contrast, int_sqrt64() used fls64(), and that returns bit numbers
+    illogically starting at 1, because of error handling for the "no
+    bits set" case. Will points out that he bug probably is due to a
+    copy-and-paste error from the regular int_sqrt() case.
+
+Signed-off-by: Florian La Roche <Florian.LaRoche@googlemail.com>
+Acked-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ lib/int_sqrt.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/lib/int_sqrt.c
++++ b/lib/int_sqrt.c
+@@ -52,7 +52,7 @@ u32 int_sqrt64(u64 x)
+       if (x <= ULONG_MAX)
+               return int_sqrt((unsigned long) x);
+-      m = 1ULL << (fls64(x) & ~1ULL);
++      m = 1ULL << ((fls64(x) - 1) & ~1ULL);
+       while (m != 0) {
+               b = y + m;
+               y >>= 1;
diff --git a/queue-4.19/ipv6-make-icmp6_send-robust-against-null-skb-dev.patch b/queue-4.19/ipv6-make-icmp6_send-robust-against-null-skb-dev.patch
new file mode 100644 (file)
index 0000000..9d13b6d
--- /dev/null
@@ -0,0 +1,81 @@
+From 8d933670452107e41165bea70a30dffbd281bef1 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Fri, 4 Jan 2019 11:00:00 -0800
+Subject: ipv6: make icmp6_send() robust against null skb->dev
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit 8d933670452107e41165bea70a30dffbd281bef1 upstream.
+
+syzbot was able to crash one host with the following stack trace :
+
+kasan: GPF could be caused by NULL-ptr deref or user memory access
+general protection fault: 0000 [#1] PREEMPT SMP KASAN
+CPU: 0 PID: 8625 Comm: syz-executor4 Not tainted 4.20.0+ #8
+RIP: 0010:dev_net include/linux/netdevice.h:2169 [inline]
+RIP: 0010:icmp6_send+0x116/0x2d30 net/ipv6/icmp.c:426
+ icmpv6_send
+ smack_socket_sock_rcv_skb
+ security_sock_rcv_skb
+ sk_filter_trim_cap
+ __sk_receive_skb
+ dccp_v6_do_rcv
+ release_sock
+
+This is because a RX packet found socket owned by user and
+was stored into socket backlog. Before leaving RCU protected section,
+skb->dev was cleared in __sk_receive_skb(). When socket backlog
+was finally handled at release_sock() time, skb was fed to
+smack_socket_sock_rcv_skb() then icmp6_send()
+
+We could fix the bug in smack_socket_sock_rcv_skb(), or simply
+make icmp6_send() more robust against such possibility.
+
+In the future we might provide to icmp6_send() the net pointer
+instead of infering it.
+
+Fixes: d66a8acbda92 ("Smack: Inform peer that IPv6 traffic has been blocked")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Piotr Sawicki <p.sawicki2@partner.samsung.com>
+Cc: Casey Schaufler <casey@schaufler-ca.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Acked-by: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ipv6/icmp.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/net/ipv6/icmp.c
++++ b/net/ipv6/icmp.c
+@@ -421,10 +421,10 @@ static int icmp6_iif(const struct sk_buf
+ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
+                      const struct in6_addr *force_saddr)
+ {
+-      struct net *net = dev_net(skb->dev);
+       struct inet6_dev *idev = NULL;
+       struct ipv6hdr *hdr = ipv6_hdr(skb);
+       struct sock *sk;
++      struct net *net;
+       struct ipv6_pinfo *np;
+       const struct in6_addr *saddr = NULL;
+       struct dst_entry *dst;
+@@ -435,12 +435,16 @@ static void icmp6_send(struct sk_buff *s
+       int iif = 0;
+       int addr_type = 0;
+       int len;
+-      u32 mark = IP6_REPLY_MARK(net, skb->mark);
++      u32 mark;
+       if ((u8 *)hdr < skb->head ||
+           (skb_network_header(skb) + sizeof(*hdr)) > skb_tail_pointer(skb))
+               return;
++      if (!skb->dev)
++              return;
++      net = dev_net(skb->dev);
++      mark = IP6_REPLY_MARK(net, skb->mark);
+       /*
+        *      Make sure we respect the rules
+        *      i.e. RFC 1885 2.4(e)
diff --git a/queue-4.19/kbuild-disable-ld_dead_code_data_elimination-with-ftrace-gcc-4.7.patch b/queue-4.19/kbuild-disable-ld_dead_code_data_elimination-with-ftrace-gcc-4.7.patch
new file mode 100644 (file)
index 0000000..e8a464c
--- /dev/null
@@ -0,0 +1,51 @@
+From 16fd20aa98080c2fa666dc384036ec08c80af710 Mon Sep 17 00:00:00 2001
+From: Paul Burton <paul.burton@mips.com>
+Date: Fri, 11 Jan 2019 19:06:44 +0000
+Subject: kbuild: Disable LD_DEAD_CODE_DATA_ELIMINATION with ftrace & GCC <= 4.7
+
+From: Paul Burton <paul.burton@mips.com>
+
+commit 16fd20aa98080c2fa666dc384036ec08c80af710 upstream.
+
+When building using GCC 4.7 or older, -ffunction-sections & the -pg flag
+used by ftrace are incompatible. This causes warnings or build failures
+(where -Werror applies) such as the following:
+
+  arch/mips/generic/init.c:
+    error: -ffunction-sections disabled; it makes profiling impossible
+
+This used to be taken into account by the ordering of calls to cc-option
+from within the top-level Makefile, which was introduced by commit
+90ad4052e85c ("kbuild: avoid conflict between -ffunction-sections and
+-pg on gcc-4.7"). Unfortunately this was broken when the
+CONFIG_LD_DEAD_CODE_DATA_ELIMINATION cc-option check was moved to
+Kconfig in commit e85d1d65cd8a ("kbuild: test dead code/data elimination
+support in Kconfig"), because the flags used by this check no longer
+include -pg.
+
+Fix this by not allowing CONFIG_LD_DEAD_CODE_DATA_ELIMINATION to be
+enabled at the same time as ftrace/CONFIG_FUNCTION_TRACER when building
+using GCC 4.7 or older.
+
+Signed-off-by: Paul Burton <paul.burton@mips.com>
+Fixes: e85d1d65cd8a ("kbuild: test dead code/data elimination support in Kconfig")
+Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Cc: Nicholas Piggin <npiggin@gmail.com>
+Cc: stable@vger.kernel.org # v4.19+
+Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ init/Kconfig |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -1102,6 +1102,7 @@ config LD_DEAD_CODE_DATA_ELIMINATION
+       bool "Dead code and data elimination (EXPERIMENTAL)"
+       depends on HAVE_LD_DEAD_CODE_DATA_ELIMINATION
+       depends on EXPERT
++      depends on !(FUNCTION_TRACER && CC_IS_GCC && GCC_VERSION < 40800)
+       depends on $(cc-option,-ffunction-sections -fdata-sections)
+       depends on $(ld-option,--gc-sections)
+       help
diff --git a/queue-4.19/loop-avoid-circular-locking-dependency-between-loop_ctl_mutex-and-bd_mutex.patch b/queue-4.19/loop-avoid-circular-locking-dependency-between-loop_ctl_mutex-and-bd_mutex.patch
new file mode 100644 (file)
index 0000000..a1855bc
--- /dev/null
@@ -0,0 +1,98 @@
+From 1dded9acf6dc9a34cd27fcf8815507e4e65b3c4f Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 8 Nov 2018 14:01:15 +0100
+Subject: loop: Avoid circular locking dependency between loop_ctl_mutex and bd_mutex
+
+From: Jan Kara <jack@suse.cz>
+
+commit 1dded9acf6dc9a34cd27fcf8815507e4e65b3c4f upstream.
+
+Code in loop_change_fd() drops reference to the old file (and also the
+new file in a failure case) under loop_ctl_mutex. Similarly to a
+situation in loop_set_fd() this can create a circular locking dependency
+if this was the last reference holding the file open. Delay dropping of
+the file reference until we have released loop_ctl_mutex.
+
+Reported-by: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |   26 +++++++++++++++-----------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -678,7 +678,7 @@ static int loop_validate_file(struct fil
+ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
+                         unsigned int arg)
+ {
+-      struct file     *file, *old_file;
++      struct file     *file = NULL, *old_file;
+       int             error;
+       bool            partscan;
+@@ -687,21 +687,21 @@ static int loop_change_fd(struct loop_de
+               return error;
+       error = -ENXIO;
+       if (lo->lo_state != Lo_bound)
+-              goto out_unlock;
++              goto out_err;
+       /* the loop device has to be read-only */
+       error = -EINVAL;
+       if (!(lo->lo_flags & LO_FLAGS_READ_ONLY))
+-              goto out_unlock;
++              goto out_err;
+       error = -EBADF;
+       file = fget(arg);
+       if (!file)
+-              goto out_unlock;
++              goto out_err;
+       error = loop_validate_file(file, bdev);
+       if (error)
+-              goto out_putf;
++              goto out_err;
+       old_file = lo->lo_backing_file;
+@@ -709,7 +709,7 @@ static int loop_change_fd(struct loop_de
+       /* size of the new backing store needs to be the same */
+       if (get_loop_size(lo, file) != get_loop_size(lo, old_file))
+-              goto out_putf;
++              goto out_err;
+       /* and ... switch */
+       blk_mq_freeze_queue(lo->lo_queue);
+@@ -720,18 +720,22 @@ static int loop_change_fd(struct loop_de
+                            lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS));
+       loop_update_dio(lo);
+       blk_mq_unfreeze_queue(lo->lo_queue);
+-
+-      fput(old_file);
+       partscan = lo->lo_flags & LO_FLAGS_PARTSCAN;
+       mutex_unlock(&loop_ctl_mutex);
++      /*
++       * We must drop file reference outside of loop_ctl_mutex as dropping
++       * the file ref can take bd_mutex which creates circular locking
++       * dependency.
++       */
++      fput(old_file);
+       if (partscan)
+               loop_reread_partitions(lo, bdev);
+       return 0;
+-out_putf:
+-      fput(file);
+-out_unlock:
++out_err:
+       mutex_unlock(&loop_ctl_mutex);
++      if (file)
++              fput(file);
+       return error;
+ }
diff --git a/queue-4.19/loop-drop-caches-if-offset-or-block_size-are-changed.patch b/queue-4.19/loop-drop-caches-if-offset-or-block_size-are-changed.patch
new file mode 100644 (file)
index 0000000..31d2394
--- /dev/null
@@ -0,0 +1,101 @@
+From 5db470e229e22b7eda6e23b5566e532c96fb5bc3 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+Date: Wed, 9 Jan 2019 19:17:14 -0800
+Subject: loop: drop caches if offset or block_size are changed
+
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+
+commit 5db470e229e22b7eda6e23b5566e532c96fb5bc3 upstream.
+
+If we don't drop caches used in old offset or block_size, we can get old data
+from new offset/block_size, which gives unexpected data to user.
+
+For example, Martijn found a loopback bug in the below scenario.
+1) LOOP_SET_FD loads first two pages on loop file
+2) LOOP_SET_STATUS64 changes the offset on the loop file
+3) mount is failed due to the cached pages having wrong superblock
+
+Cc: Jens Axboe <axboe@kernel.dk>
+Cc: linux-block@vger.kernel.org
+Reported-by: Martijn Coenen <maco@google.com>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |   35 +++++++++++++++++++++++++++++++++--
+ 1 file changed, 33 insertions(+), 2 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -1191,6 +1191,12 @@ loop_set_status(struct loop_device *lo,
+               goto out_unlock;
+       }
++      if (lo->lo_offset != info->lo_offset ||
++          lo->lo_sizelimit != info->lo_sizelimit) {
++              sync_blockdev(lo->lo_device);
++              kill_bdev(lo->lo_device);
++      }
++
+       /* I/O need to be drained during transfer transition */
+       blk_mq_freeze_queue(lo->lo_queue);
+@@ -1219,6 +1225,14 @@ loop_set_status(struct loop_device *lo,
+       if (lo->lo_offset != info->lo_offset ||
+           lo->lo_sizelimit != info->lo_sizelimit) {
++              /* kill_bdev should have truncated all the pages */
++              if (lo->lo_device->bd_inode->i_mapping->nrpages) {
++                      err = -EAGAIN;
++                      pr_warn("%s: loop%d (%s) has still dirty pages (nrpages=%lu)\n",
++                              __func__, lo->lo_number, lo->lo_file_name,
++                              lo->lo_device->bd_inode->i_mapping->nrpages);
++                      goto out_unfreeze;
++              }
+               if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit)) {
+                       err = -EFBIG;
+                       goto out_unfreeze;
+@@ -1444,22 +1458,39 @@ static int loop_set_dio(struct loop_devi
+ static int loop_set_block_size(struct loop_device *lo, unsigned long arg)
+ {
++      int err = 0;
++
+       if (lo->lo_state != Lo_bound)
+               return -ENXIO;
+       if (arg < 512 || arg > PAGE_SIZE || !is_power_of_2(arg))
+               return -EINVAL;
++      if (lo->lo_queue->limits.logical_block_size != arg) {
++              sync_blockdev(lo->lo_device);
++              kill_bdev(lo->lo_device);
++      }
++
+       blk_mq_freeze_queue(lo->lo_queue);
++      /* kill_bdev should have truncated all the pages */
++      if (lo->lo_queue->limits.logical_block_size != arg &&
++                      lo->lo_device->bd_inode->i_mapping->nrpages) {
++              err = -EAGAIN;
++              pr_warn("%s: loop%d (%s) has still dirty pages (nrpages=%lu)\n",
++                      __func__, lo->lo_number, lo->lo_file_name,
++                      lo->lo_device->bd_inode->i_mapping->nrpages);
++              goto out_unfreeze;
++      }
++
+       blk_queue_logical_block_size(lo->lo_queue, arg);
+       blk_queue_physical_block_size(lo->lo_queue, arg);
+       blk_queue_io_min(lo->lo_queue, arg);
+       loop_update_dio(lo);
+-
++out_unfreeze:
+       blk_mq_unfreeze_queue(lo->lo_queue);
+-      return 0;
++      return err;
+ }
+ static int lo_simple_ioctl(struct loop_device *lo, unsigned int cmd,
diff --git a/queue-4.19/loop-fix-deadlock-when-calling-blkdev_reread_part.patch b/queue-4.19/loop-fix-deadlock-when-calling-blkdev_reread_part.patch
new file mode 100644 (file)
index 0000000..e1286d9
--- /dev/null
@@ -0,0 +1,109 @@
+From 0da03cab87e6323ff2e05b14bc7d5c6fcc531efd Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 8 Nov 2018 14:01:14 +0100
+Subject: loop: Fix deadlock when calling blkdev_reread_part()
+
+From: Jan Kara <jack@suse.cz>
+
+commit 0da03cab87e6323ff2e05b14bc7d5c6fcc531efd upstream.
+
+Calling blkdev_reread_part() under loop_ctl_mutex causes lockdep to
+complain about circular lock dependency between bdev->bd_mutex and
+lo->lo_ctl_mutex. The problem is that on loop device open or close
+lo_open() and lo_release() get called with bdev->bd_mutex held and they
+need to acquire loop_ctl_mutex. OTOH when loop_reread_partitions() is
+called with loop_ctl_mutex held, it will call blkdev_reread_part() which
+acquires bdev->bd_mutex. See syzbot report for details [1].
+
+Move call to blkdev_reread_part() in __loop_clr_fd() from under
+loop_ctl_mutex to finish fixing of the lockdep warning and the possible
+deadlock.
+
+[1] https://syzkaller.appspot.com/bug?id=bf154052f0eea4bc7712499e4569505907d1588
+
+Reported-by: syzbot <syzbot+4684a000d5abdade83fac55b1e7d1f935ef1936e@syzkaller.appspotmail.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |   28 ++++++++++++++++------------
+ 1 file changed, 16 insertions(+), 12 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -1031,12 +1031,14 @@ loop_init_xfer(struct loop_device *lo, s
+       return err;
+ }
+-static int __loop_clr_fd(struct loop_device *lo)
++static int __loop_clr_fd(struct loop_device *lo, bool release)
+ {
+       struct file *filp = NULL;
+       gfp_t gfp = lo->old_gfp_mask;
+       struct block_device *bdev = lo->lo_device;
+       int err = 0;
++      bool partscan = false;
++      int lo_number;
+       mutex_lock(&loop_ctl_mutex);
+       if (WARN_ON_ONCE(lo->lo_state != Lo_rundown)) {
+@@ -1089,7 +1091,15 @@ static int __loop_clr_fd(struct loop_dev
+       module_put(THIS_MODULE);
+       blk_mq_unfreeze_queue(lo->lo_queue);
+-      if (lo->lo_flags & LO_FLAGS_PARTSCAN && bdev) {
++      partscan = lo->lo_flags & LO_FLAGS_PARTSCAN && bdev;
++      lo_number = lo->lo_number;
++      lo->lo_flags = 0;
++      if (!part_shift)
++              lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN;
++      loop_unprepare_queue(lo);
++out_unlock:
++      mutex_unlock(&loop_ctl_mutex);
++      if (partscan) {
+               /*
+                * bd_mutex has been held already in release path, so don't
+                * acquire it if this function is called in such case.
+@@ -1098,21 +1108,15 @@ static int __loop_clr_fd(struct loop_dev
+                * must be at least one and it can only become zero when the
+                * current holder is released.
+                */
+-              if (!atomic_read(&lo->lo_refcnt))
++              if (release)
+                       err = __blkdev_reread_part(bdev);
+               else
+                       err = blkdev_reread_part(bdev);
+               pr_warn("%s: partition scan of loop%d failed (rc=%d)\n",
+-                      __func__, lo->lo_number, err);
++                      __func__, lo_number, err);
+               /* Device is gone, no point in returning error */
+               err = 0;
+       }
+-      lo->lo_flags = 0;
+-      if (!part_shift)
+-              lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN;
+-      loop_unprepare_queue(lo);
+-out_unlock:
+-      mutex_unlock(&loop_ctl_mutex);
+       /*
+        * Need not hold loop_ctl_mutex to fput backing file.
+        * Calling fput holding loop_ctl_mutex triggers a circular
+@@ -1153,7 +1157,7 @@ static int loop_clr_fd(struct loop_devic
+       lo->lo_state = Lo_rundown;
+       mutex_unlock(&loop_ctl_mutex);
+-      return __loop_clr_fd(lo);
++      return __loop_clr_fd(lo, false);
+ }
+ static int
+@@ -1714,7 +1718,7 @@ static void lo_release(struct gendisk *d
+                * In autoclear mode, stop the loop thread
+                * and remove configuration after last close.
+                */
+-              __loop_clr_fd(lo);
++              __loop_clr_fd(lo, true);
+               return;
+       } else if (lo->lo_state == Lo_bound) {
+               /*
diff --git a/queue-4.19/loop-fix-double-mutex_unlock-loop_ctl_mutex-in-loop_control_ioctl.patch b/queue-4.19/loop-fix-double-mutex_unlock-loop_ctl_mutex-in-loop_control_ioctl.patch
new file mode 100644 (file)
index 0000000..424952e
--- /dev/null
@@ -0,0 +1,40 @@
+From 628bd85947091830a8c4872adfd5ed1d515a9cf2 Mon Sep 17 00:00:00 2001
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Date: Mon, 12 Nov 2018 08:42:14 -0700
+Subject: loop: Fix double mutex_unlock(&loop_ctl_mutex) in loop_control_ioctl()
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+commit 628bd85947091830a8c4872adfd5ed1d515a9cf2 upstream.
+
+Commit 0a42e99b58a20883 ("loop: Get rid of loop_index_mutex") forgot to
+remove mutex_unlock(&loop_ctl_mutex) from loop_control_ioctl() when
+replacing loop_index_mutex with loop_ctl_mutex.
+
+Fixes: 0a42e99b58a20883 ("loop: Get rid of loop_index_mutex")
+Reported-by: syzbot <syzbot+c0138741c2290fc5e63f@syzkaller.appspotmail.com>
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -2075,12 +2075,10 @@ static long loop_control_ioctl(struct fi
+                       break;
+               if (lo->lo_state != Lo_unbound) {
+                       ret = -EBUSY;
+-                      mutex_unlock(&loop_ctl_mutex);
+                       break;
+               }
+               if (atomic_read(&lo->lo_refcnt) > 0) {
+                       ret = -EBUSY;
+-                      mutex_unlock(&loop_ctl_mutex);
+                       break;
+               }
+               lo->lo_disk->private_data = NULL;
diff --git a/queue-4.19/loop-fold-__loop_release-into-loop_release.patch b/queue-4.19/loop-fold-__loop_release-into-loop_release.patch
new file mode 100644 (file)
index 0000000..463ae1a
--- /dev/null
@@ -0,0 +1,64 @@
+From 967d1dc144b50ad005e5eecdfadfbcfb399ffff6 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 8 Nov 2018 14:01:03 +0100
+Subject: loop: Fold __loop_release into loop_release
+
+From: Jan Kara <jack@suse.cz>
+
+commit 967d1dc144b50ad005e5eecdfadfbcfb399ffff6 upstream.
+
+__loop_release() has a single call site. Fold it there. This is
+currently not a huge win but it will make following replacement of
+loop_index_mutex more obvious.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |   16 +++++++---------
+ 1 file changed, 7 insertions(+), 9 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -1642,12 +1642,15 @@ out:
+       return err;
+ }
+-static void __lo_release(struct loop_device *lo)
++static void lo_release(struct gendisk *disk, fmode_t mode)
+ {
++      struct loop_device *lo;
+       int err;
++      mutex_lock(&loop_index_mutex);
++      lo = disk->private_data;
+       if (atomic_dec_return(&lo->lo_refcnt))
+-              return;
++              goto unlock_index;
+       mutex_lock(&loop_ctl_mutex);
+       if (lo->lo_flags & LO_FLAGS_AUTOCLEAR) {
+@@ -1657,7 +1660,7 @@ static void __lo_release(struct loop_dev
+                */
+               err = loop_clr_fd(lo);
+               if (!err)
+-                      return;
++                      goto unlock_index;
+       } else if (lo->lo_state == Lo_bound) {
+               /*
+                * Otherwise keep thread (if running) and config,
+@@ -1668,12 +1671,7 @@ static void __lo_release(struct loop_dev
+       }
+       mutex_unlock(&loop_ctl_mutex);
+-}
+-
+-static void lo_release(struct gendisk *disk, fmode_t mode)
+-{
+-      mutex_lock(&loop_index_mutex);
+-      __lo_release(disk->private_data);
++unlock_index:
+       mutex_unlock(&loop_index_mutex);
+ }
diff --git a/queue-4.19/loop-get-rid-of-loop_index_mutex.patch b/queue-4.19/loop-get-rid-of-loop_index_mutex.patch
new file mode 100644 (file)
index 0000000..537db5b
--- /dev/null
@@ -0,0 +1,163 @@
+From 0a42e99b58a208839626465af194cfe640ef9493 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 8 Nov 2018 14:01:04 +0100
+Subject: loop: Get rid of loop_index_mutex
+
+From: Jan Kara <jack@suse.cz>
+
+commit 0a42e99b58a208839626465af194cfe640ef9493 upstream.
+
+Now that loop_ctl_mutex is global, just get rid of loop_index_mutex as
+there is no good reason to keep these two separate and it just
+complicates the locking.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |   41 ++++++++++++++++++++---------------------
+ 1 file changed, 20 insertions(+), 21 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -83,7 +83,6 @@
+ #include <linux/uaccess.h>
+ static DEFINE_IDR(loop_index_idr);
+-static DEFINE_MUTEX(loop_index_mutex);
+ static DEFINE_MUTEX(loop_ctl_mutex);
+ static int max_part;
+@@ -1627,9 +1626,11 @@ static int lo_compat_ioctl(struct block_
+ static int lo_open(struct block_device *bdev, fmode_t mode)
+ {
+       struct loop_device *lo;
+-      int err = 0;
++      int err;
+-      mutex_lock(&loop_index_mutex);
++      err = mutex_lock_killable(&loop_ctl_mutex);
++      if (err)
++              return err;
+       lo = bdev->bd_disk->private_data;
+       if (!lo) {
+               err = -ENXIO;
+@@ -1638,7 +1639,7 @@ static int lo_open(struct block_device *
+       atomic_inc(&lo->lo_refcnt);
+ out:
+-      mutex_unlock(&loop_index_mutex);
++      mutex_unlock(&loop_ctl_mutex);
+       return err;
+ }
+@@ -1647,12 +1648,11 @@ static void lo_release(struct gendisk *d
+       struct loop_device *lo;
+       int err;
+-      mutex_lock(&loop_index_mutex);
++      mutex_lock(&loop_ctl_mutex);
+       lo = disk->private_data;
+       if (atomic_dec_return(&lo->lo_refcnt))
+-              goto unlock_index;
++              goto out_unlock;
+-      mutex_lock(&loop_ctl_mutex);
+       if (lo->lo_flags & LO_FLAGS_AUTOCLEAR) {
+               /*
+                * In autoclear mode, stop the loop thread
+@@ -1660,7 +1660,7 @@ static void lo_release(struct gendisk *d
+                */
+               err = loop_clr_fd(lo);
+               if (!err)
+-                      goto unlock_index;
++                      return;
+       } else if (lo->lo_state == Lo_bound) {
+               /*
+                * Otherwise keep thread (if running) and config,
+@@ -1670,9 +1670,8 @@ static void lo_release(struct gendisk *d
+               blk_mq_unfreeze_queue(lo->lo_queue);
+       }
++out_unlock:
+       mutex_unlock(&loop_ctl_mutex);
+-unlock_index:
+-      mutex_unlock(&loop_index_mutex);
+ }
+ static const struct block_device_operations lo_fops = {
+@@ -1973,7 +1972,7 @@ static struct kobject *loop_probe(dev_t
+       struct kobject *kobj;
+       int err;
+-      mutex_lock(&loop_index_mutex);
++      mutex_lock(&loop_ctl_mutex);
+       err = loop_lookup(&lo, MINOR(dev) >> part_shift);
+       if (err < 0)
+               err = loop_add(&lo, MINOR(dev) >> part_shift);
+@@ -1981,7 +1980,7 @@ static struct kobject *loop_probe(dev_t
+               kobj = NULL;
+       else
+               kobj = get_disk_and_module(lo->lo_disk);
+-      mutex_unlock(&loop_index_mutex);
++      mutex_unlock(&loop_ctl_mutex);
+       *part = 0;
+       return kobj;
+@@ -1991,9 +1990,13 @@ static long loop_control_ioctl(struct fi
+                              unsigned long parm)
+ {
+       struct loop_device *lo;
+-      int ret = -ENOSYS;
++      int ret;
+-      mutex_lock(&loop_index_mutex);
++      ret = mutex_lock_killable(&loop_ctl_mutex);
++      if (ret)
++              return ret;
++
++      ret = -ENOSYS;
+       switch (cmd) {
+       case LOOP_CTL_ADD:
+               ret = loop_lookup(&lo, parm);
+@@ -2007,9 +2010,6 @@ static long loop_control_ioctl(struct fi
+               ret = loop_lookup(&lo, parm);
+               if (ret < 0)
+                       break;
+-              ret = mutex_lock_killable(&loop_ctl_mutex);
+-              if (ret)
+-                      break;
+               if (lo->lo_state != Lo_unbound) {
+                       ret = -EBUSY;
+                       mutex_unlock(&loop_ctl_mutex);
+@@ -2021,7 +2021,6 @@ static long loop_control_ioctl(struct fi
+                       break;
+               }
+               lo->lo_disk->private_data = NULL;
+-              mutex_unlock(&loop_ctl_mutex);
+               idr_remove(&loop_index_idr, lo->lo_number);
+               loop_remove(lo);
+               break;
+@@ -2031,7 +2030,7 @@ static long loop_control_ioctl(struct fi
+                       break;
+               ret = loop_add(&lo, -1);
+       }
+-      mutex_unlock(&loop_index_mutex);
++      mutex_unlock(&loop_ctl_mutex);
+       return ret;
+ }
+@@ -2115,10 +2114,10 @@ static int __init loop_init(void)
+                                 THIS_MODULE, loop_probe, NULL, NULL);
+       /* pre-create number of devices given by config or max_loop */
+-      mutex_lock(&loop_index_mutex);
++      mutex_lock(&loop_ctl_mutex);
+       for (i = 0; i < nr; i++)
+               loop_add(&lo, i);
+-      mutex_unlock(&loop_index_mutex);
++      mutex_unlock(&loop_ctl_mutex);
+       printk(KERN_INFO "loop: module loaded\n");
+       return 0;
diff --git a/queue-4.19/loop-get-rid-of-nested-acquisition-of-loop_ctl_mutex.patch b/queue-4.19/loop-get-rid-of-nested-acquisition-of-loop_ctl_mutex.patch
new file mode 100644 (file)
index 0000000..9de23cf
--- /dev/null
@@ -0,0 +1,79 @@
+From c28445fa06a3a54e06938559b9514c5a7f01c90f Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 8 Nov 2018 14:01:16 +0100
+Subject: loop: Get rid of 'nested' acquisition of loop_ctl_mutex
+
+From: Jan Kara <jack@suse.cz>
+
+commit c28445fa06a3a54e06938559b9514c5a7f01c90f upstream.
+
+The nested acquisition of loop_ctl_mutex (->lo_ctl_mutex back then) has
+been introduced by commit f028f3b2f987e "loop: fix circular locking in
+loop_clr_fd()" to fix lockdep complains about bd_mutex being acquired
+after lo_ctl_mutex during partition rereading. Now that these are
+properly fixed, let's stop fooling lockdep.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -682,7 +682,7 @@ static int loop_change_fd(struct loop_de
+       int             error;
+       bool            partscan;
+-      error = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
++      error = mutex_lock_killable(&loop_ctl_mutex);
+       if (error)
+               return error;
+       error = -ENXIO;
+@@ -920,7 +920,7 @@ static int loop_set_fd(struct loop_devic
+       if (!file)
+               goto out;
+-      error = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
++      error = mutex_lock_killable(&loop_ctl_mutex);
+       if (error)
+               goto out_putf;
+@@ -1136,7 +1136,7 @@ static int loop_clr_fd(struct loop_devic
+ {
+       int err;
+-      err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
++      err = mutex_lock_killable(&loop_ctl_mutex);
+       if (err)
+               return err;
+       if (lo->lo_state != Lo_bound) {
+@@ -1173,7 +1173,7 @@ loop_set_status(struct loop_device *lo,
+       struct block_device *bdev;
+       bool partscan = false;
+-      err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
++      err = mutex_lock_killable(&loop_ctl_mutex);
+       if (err)
+               return err;
+       if (lo->lo_encrypt_key_size &&
+@@ -1278,7 +1278,7 @@ loop_get_status(struct loop_device *lo,
+       struct kstat stat;
+       int ret;
+-      ret = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
++      ret = mutex_lock_killable(&loop_ctl_mutex);
+       if (ret)
+               return ret;
+       if (lo->lo_state != Lo_bound) {
+@@ -1467,7 +1467,7 @@ static int lo_simple_ioctl(struct loop_d
+ {
+       int err;
+-      err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
++      err = mutex_lock_killable(&loop_ctl_mutex);
+       if (err)
+               return err;
+       switch (cmd) {
diff --git a/queue-4.19/loop-move-loop_reread_partitions-out-of-loop_ctl_mutex.patch b/queue-4.19/loop-move-loop_reread_partitions-out-of-loop_ctl_mutex.patch
new file mode 100644 (file)
index 0000000..7374c84
--- /dev/null
@@ -0,0 +1,104 @@
+From 85b0a54a82e4fbceeb1aebb7cb6909edd1a24668 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 8 Nov 2018 14:01:13 +0100
+Subject: loop: Move loop_reread_partitions() out of loop_ctl_mutex
+
+From: Jan Kara <jack@suse.cz>
+
+commit 85b0a54a82e4fbceeb1aebb7cb6909edd1a24668 upstream.
+
+Calling loop_reread_partitions() under loop_ctl_mutex causes lockdep to
+complain about circular lock dependency between bdev->bd_mutex and
+lo->lo_ctl_mutex. The problem is that on loop device open or close
+lo_open() and lo_release() get called with bdev->bd_mutex held and they
+need to acquire loop_ctl_mutex. OTOH when loop_reread_partitions() is
+called with loop_ctl_mutex held, it will call blkdev_reread_part() which
+acquires bdev->bd_mutex. See syzbot report for details [1].
+
+Move all calls of loop_rescan_partitions() out of loop_ctl_mutex to
+avoid lockdep warning and fix deadlock possibility.
+
+[1] https://syzkaller.appspot.com/bug?id=bf154052f0eea4bc7712499e4569505907d1588
+
+Reported-by: syzbot <syzbot+4684a000d5abdade83fac55b1e7d1f935ef1936e@syzkaller.appspotmail.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |   19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -680,6 +680,7 @@ static int loop_change_fd(struct loop_de
+ {
+       struct file     *file, *old_file;
+       int             error;
++      bool            partscan;
+       error = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
+       if (error)
+@@ -721,9 +722,10 @@ static int loop_change_fd(struct loop_de
+       blk_mq_unfreeze_queue(lo->lo_queue);
+       fput(old_file);
+-      if (lo->lo_flags & LO_FLAGS_PARTSCAN)
+-              loop_reread_partitions(lo, bdev);
++      partscan = lo->lo_flags & LO_FLAGS_PARTSCAN;
+       mutex_unlock(&loop_ctl_mutex);
++      if (partscan)
++              loop_reread_partitions(lo, bdev);
+       return 0;
+ out_putf:
+@@ -904,6 +906,7 @@ static int loop_set_fd(struct loop_devic
+       int             lo_flags = 0;
+       int             error;
+       loff_t          size;
++      bool            partscan;
+       /* This is safe, since we have a reference from open(). */
+       __module_get(THIS_MODULE);
+@@ -970,14 +973,15 @@ static int loop_set_fd(struct loop_devic
+       lo->lo_state = Lo_bound;
+       if (part_shift)
+               lo->lo_flags |= LO_FLAGS_PARTSCAN;
+-      if (lo->lo_flags & LO_FLAGS_PARTSCAN)
+-              loop_reread_partitions(lo, bdev);
++      partscan = lo->lo_flags & LO_FLAGS_PARTSCAN;
+       /* Grab the block_device to prevent its destruction after we
+        * put /dev/loopXX inode. Later in __loop_clr_fd() we bdput(bdev).
+        */
+       bdgrab(bdev);
+       mutex_unlock(&loop_ctl_mutex);
++      if (partscan)
++              loop_reread_partitions(lo, bdev);
+       return 0;
+ out_unlock:
+@@ -1158,6 +1162,8 @@ loop_set_status(struct loop_device *lo,
+       int err;
+       struct loop_func_table *xfer;
+       kuid_t uid = current_uid();
++      struct block_device *bdev;
++      bool partscan = false;
+       err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
+       if (err)
+@@ -1246,10 +1252,13 @@ out_unfreeze:
+            !(lo->lo_flags & LO_FLAGS_PARTSCAN)) {
+               lo->lo_flags |= LO_FLAGS_PARTSCAN;
+               lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;
+-              loop_reread_partitions(lo, lo->lo_device);
++              bdev = lo->lo_device;
++              partscan = true;
+       }
+ out_unlock:
+       mutex_unlock(&loop_ctl_mutex);
++      if (partscan)
++              loop_reread_partitions(lo, bdev);
+       return err;
+ }
diff --git a/queue-4.19/loop-move-special-partition-reread-handling-in-loop_clr_fd.patch b/queue-4.19/loop-move-special-partition-reread-handling-in-loop_clr_fd.patch
new file mode 100644 (file)
index 0000000..48d9d06
--- /dev/null
@@ -0,0 +1,77 @@
+From d57f3374ba4817f7c8d26fae8a13d20ac8d31b92 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 8 Nov 2018 14:01:12 +0100
+Subject: loop: Move special partition reread handling in loop_clr_fd()
+
+From: Jan Kara <jack@suse.cz>
+
+commit d57f3374ba4817f7c8d26fae8a13d20ac8d31b92 upstream.
+
+The call of __blkdev_reread_part() from loop_reread_partition() happens
+only when we need to invalidate partitions from loop_release(). Thus
+move a detection for this into loop_clr_fd() and simplify
+loop_reread_partition().
+
+This makes loop_reread_partition() safe to use without loop_ctl_mutex
+because we use only lo->lo_number and lo->lo_file_name in case of error
+for reporting purposes (thus possibly reporting outdate information is
+not a big deal) and we are safe from 'lo' going away under us by
+elevated lo->lo_refcnt.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |   33 +++++++++++++++++++--------------
+ 1 file changed, 19 insertions(+), 14 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -631,18 +631,7 @@ static void loop_reread_partitions(struc
+ {
+       int rc;
+-      /*
+-       * bd_mutex has been held already in release path, so don't
+-       * acquire it if this function is called in such case.
+-       *
+-       * If the reread partition isn't from release path, lo_refcnt
+-       * must be at least one and it can only become zero when the
+-       * current holder is released.
+-       */
+-      if (!atomic_read(&lo->lo_refcnt))
+-              rc = __blkdev_reread_part(bdev);
+-      else
+-              rc = blkdev_reread_part(bdev);
++      rc = blkdev_reread_part(bdev);
+       if (rc)
+               pr_warn("%s: partition scan of loop%d (%s) failed (rc=%d)\n",
+                       __func__, lo->lo_number, lo->lo_file_name, rc);
+@@ -1096,8 +1085,24 @@ static int __loop_clr_fd(struct loop_dev
+       module_put(THIS_MODULE);
+       blk_mq_unfreeze_queue(lo->lo_queue);
+-      if (lo->lo_flags & LO_FLAGS_PARTSCAN && bdev)
+-              loop_reread_partitions(lo, bdev);
++      if (lo->lo_flags & LO_FLAGS_PARTSCAN && bdev) {
++              /*
++               * bd_mutex has been held already in release path, so don't
++               * acquire it if this function is called in such case.
++               *
++               * If the reread partition isn't from release path, lo_refcnt
++               * must be at least one and it can only become zero when the
++               * current holder is released.
++               */
++              if (!atomic_read(&lo->lo_refcnt))
++                      err = __blkdev_reread_part(bdev);
++              else
++                      err = blkdev_reread_part(bdev);
++              pr_warn("%s: partition scan of loop%d failed (rc=%d)\n",
++                      __func__, lo->lo_number, err);
++              /* Device is gone, no point in returning error */
++              err = 0;
++      }
+       lo->lo_flags = 0;
+       if (!part_shift)
+               lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN;
diff --git a/queue-4.19/loop-push-lo_ctl_mutex-down-into-individual-ioctls.patch b/queue-4.19/loop-push-lo_ctl_mutex-down-into-individual-ioctls.patch
new file mode 100644 (file)
index 0000000..3a7ca72
--- /dev/null
@@ -0,0 +1,159 @@
+From a13165441d58b216adbd50252a9cc829d78a6bce Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 8 Nov 2018 14:01:05 +0100
+Subject: loop: Push lo_ctl_mutex down into individual ioctls
+
+From: Jan Kara <jack@suse.cz>
+
+commit a13165441d58b216adbd50252a9cc829d78a6bce upstream.
+
+Push acquisition of lo_ctl_mutex down into individual ioctl handling
+branches. This is a preparatory step for pushing the lock down into
+individual ioctl handling functions so that they can release the lock as
+they need it. We also factor out some simple ioctl handlers that will
+not need any special handling to reduce unnecessary code duplication.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |   88 ++++++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 63 insertions(+), 25 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -1394,70 +1394,108 @@ static int loop_set_block_size(struct lo
+       return 0;
+ }
+-static int lo_ioctl(struct block_device *bdev, fmode_t mode,
+-      unsigned int cmd, unsigned long arg)
++static int lo_simple_ioctl(struct loop_device *lo, unsigned int cmd,
++                         unsigned long arg)
+ {
+-      struct loop_device *lo = bdev->bd_disk->private_data;
+       int err;
+       err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
+       if (err)
+-              goto out_unlocked;
++              return err;
++      switch (cmd) {
++      case LOOP_SET_CAPACITY:
++              err = loop_set_capacity(lo);
++              break;
++      case LOOP_SET_DIRECT_IO:
++              err = loop_set_dio(lo, arg);
++              break;
++      case LOOP_SET_BLOCK_SIZE:
++              err = loop_set_block_size(lo, arg);
++              break;
++      default:
++              err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
++      }
++      mutex_unlock(&loop_ctl_mutex);
++      return err;
++}
++
++static int lo_ioctl(struct block_device *bdev, fmode_t mode,
++      unsigned int cmd, unsigned long arg)
++{
++      struct loop_device *lo = bdev->bd_disk->private_data;
++      int err;
+       switch (cmd) {
+       case LOOP_SET_FD:
++              err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
++              if (err)
++                      return err;
+               err = loop_set_fd(lo, mode, bdev, arg);
++              mutex_unlock(&loop_ctl_mutex);
+               break;
+       case LOOP_CHANGE_FD:
++              err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
++              if (err)
++                      return err;
+               err = loop_change_fd(lo, bdev, arg);
++              mutex_unlock(&loop_ctl_mutex);
+               break;
+       case LOOP_CLR_FD:
++              err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
++              if (err)
++                      return err;
+               /* loop_clr_fd would have unlocked loop_ctl_mutex on success */
+               err = loop_clr_fd(lo);
+-              if (!err)
+-                      goto out_unlocked;
++              if (err)
++                      mutex_unlock(&loop_ctl_mutex);
+               break;
+       case LOOP_SET_STATUS:
+               err = -EPERM;
+-              if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN))
++              if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) {
++                      err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
++                      if (err)
++                              return err;
+                       err = loop_set_status_old(lo,
+                                       (struct loop_info __user *)arg);
++                      mutex_unlock(&loop_ctl_mutex);
++              }
+               break;
+       case LOOP_GET_STATUS:
++              err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
++              if (err)
++                      return err;
+               err = loop_get_status_old(lo, (struct loop_info __user *) arg);
+               /* loop_get_status() unlocks loop_ctl_mutex */
+-              goto out_unlocked;
++              break;
+       case LOOP_SET_STATUS64:
+               err = -EPERM;
+-              if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN))
++              if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) {
++                      err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
++                      if (err)
++                              return err;
+                       err = loop_set_status64(lo,
+                                       (struct loop_info64 __user *) arg);
++                      mutex_unlock(&loop_ctl_mutex);
++              }
+               break;
+       case LOOP_GET_STATUS64:
++              err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
++              if (err)
++                      return err;
+               err = loop_get_status64(lo, (struct loop_info64 __user *) arg);
+               /* loop_get_status() unlocks loop_ctl_mutex */
+-              goto out_unlocked;
+-      case LOOP_SET_CAPACITY:
+-              err = -EPERM;
+-              if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN))
+-                      err = loop_set_capacity(lo);
+               break;
++      case LOOP_SET_CAPACITY:
+       case LOOP_SET_DIRECT_IO:
+-              err = -EPERM;
+-              if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN))
+-                      err = loop_set_dio(lo, arg);
+-              break;
+       case LOOP_SET_BLOCK_SIZE:
+-              err = -EPERM;
+-              if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN))
+-                      err = loop_set_block_size(lo, arg);
+-              break;
++              if (!(mode & FMODE_WRITE) && !capable(CAP_SYS_ADMIN))
++                      return -EPERM;
++              /* Fall through */
+       default:
+-              err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
++              err = lo_simple_ioctl(lo, cmd, arg);
++              break;
+       }
+-      mutex_unlock(&loop_ctl_mutex);
+-out_unlocked:
+       return err;
+ }
diff --git a/queue-4.19/loop-push-loop_ctl_mutex-down-into-loop_clr_fd.patch b/queue-4.19/loop-push-loop_ctl_mutex-down-into-loop_clr_fd.patch
new file mode 100644 (file)
index 0000000..3f278a3
--- /dev/null
@@ -0,0 +1,135 @@
+From 7ccd0791d98531df7cd59e92d55e4f063d48a070 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 8 Nov 2018 14:01:07 +0100
+Subject: loop: Push loop_ctl_mutex down into loop_clr_fd()
+
+From: Jan Kara <jack@suse.cz>
+
+commit 7ccd0791d98531df7cd59e92d55e4f063d48a070 upstream.
+
+loop_clr_fd() has a weird locking convention that is expects
+loop_ctl_mutex held, releases it on success and keeps it on failure.
+Untangle the mess by moving locking of loop_ctl_mutex into
+loop_clr_fd().
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |   49 +++++++++++++++++++++++++++++--------------------
+ 1 file changed, 29 insertions(+), 20 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -1028,15 +1028,22 @@ loop_init_xfer(struct loop_device *lo, s
+ static int __loop_clr_fd(struct loop_device *lo)
+ {
+-      struct file *filp = lo->lo_backing_file;
++      struct file *filp = NULL;
+       gfp_t gfp = lo->old_gfp_mask;
+       struct block_device *bdev = lo->lo_device;
++      int err = 0;
+-      if (WARN_ON_ONCE(lo->lo_state != Lo_rundown))
+-              return -ENXIO;
++      mutex_lock(&loop_ctl_mutex);
++      if (WARN_ON_ONCE(lo->lo_state != Lo_rundown)) {
++              err = -ENXIO;
++              goto out_unlock;
++      }
+-      if (filp == NULL)
+-              return -EINVAL;
++      filp = lo->lo_backing_file;
++      if (filp == NULL) {
++              err = -EINVAL;
++              goto out_unlock;
++      }
+       /* freeze request queue during the transition */
+       blk_mq_freeze_queue(lo->lo_queue);
+@@ -1083,6 +1090,7 @@ static int __loop_clr_fd(struct loop_dev
+       if (!part_shift)
+               lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN;
+       loop_unprepare_queue(lo);
++out_unlock:
+       mutex_unlock(&loop_ctl_mutex);
+       /*
+        * Need not hold loop_ctl_mutex to fput backing file.
+@@ -1090,14 +1098,22 @@ static int __loop_clr_fd(struct loop_dev
+        * lock dependency possibility warning as fput can take
+        * bd_mutex which is usually taken before loop_ctl_mutex.
+        */
+-      fput(filp);
+-      return 0;
++      if (filp)
++              fput(filp);
++      return err;
+ }
+ static int loop_clr_fd(struct loop_device *lo)
+ {
+-      if (lo->lo_state != Lo_bound)
++      int err;
++
++      err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
++      if (err)
++              return err;
++      if (lo->lo_state != Lo_bound) {
++              mutex_unlock(&loop_ctl_mutex);
+               return -ENXIO;
++      }
+       /*
+        * If we've explicitly asked to tear down the loop device,
+        * and it has an elevated reference count, set it for auto-teardown when
+@@ -1114,6 +1130,7 @@ static int loop_clr_fd(struct loop_devic
+               return 0;
+       }
+       lo->lo_state = Lo_rundown;
++      mutex_unlock(&loop_ctl_mutex);
+       return __loop_clr_fd(lo);
+ }
+@@ -1448,14 +1465,7 @@ static int lo_ioctl(struct block_device
+               mutex_unlock(&loop_ctl_mutex);
+               break;
+       case LOOP_CLR_FD:
+-              err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
+-              if (err)
+-                      return err;
+-              /* loop_clr_fd would have unlocked loop_ctl_mutex on success */
+-              err = loop_clr_fd(lo);
+-              if (err)
+-                      mutex_unlock(&loop_ctl_mutex);
+-              break;
++              return loop_clr_fd(lo);
+       case LOOP_SET_STATUS:
+               err = -EPERM;
+               if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) {
+@@ -1691,7 +1701,6 @@ out:
+ static void lo_release(struct gendisk *disk, fmode_t mode)
+ {
+       struct loop_device *lo;
+-      int err;
+       mutex_lock(&loop_ctl_mutex);
+       lo = disk->private_data;
+@@ -1702,13 +1711,13 @@ static void lo_release(struct gendisk *d
+               if (lo->lo_state != Lo_bound)
+                       goto out_unlock;
+               lo->lo_state = Lo_rundown;
++              mutex_unlock(&loop_ctl_mutex);
+               /*
+                * In autoclear mode, stop the loop thread
+                * and remove configuration after last close.
+                */
+-              err = __loop_clr_fd(lo);
+-              if (!err)
+-                      return;
++              __loop_clr_fd(lo);
++              return;
+       } else if (lo->lo_state == Lo_bound) {
+               /*
+                * Otherwise keep thread (if running) and config,
diff --git a/queue-4.19/loop-push-loop_ctl_mutex-down-to-loop_change_fd.patch b/queue-4.19/loop-push-loop_ctl_mutex-down-to-loop_change_fd.patch
new file mode 100644 (file)
index 0000000..751488c
--- /dev/null
@@ -0,0 +1,78 @@
+From c371077000f4138ee3c15fbed50101ff24bdc91d Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 8 Nov 2018 14:01:11 +0100
+Subject: loop: Push loop_ctl_mutex down to loop_change_fd()
+
+From: Jan Kara <jack@suse.cz>
+
+commit c371077000f4138ee3c15fbed50101ff24bdc91d upstream.
+
+Push loop_ctl_mutex down to loop_change_fd(). We will need this to be
+able to call loop_reread_partitions() without loop_ctl_mutex.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |   22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -692,19 +692,22 @@ static int loop_change_fd(struct loop_de
+       struct file     *file, *old_file;
+       int             error;
++      error = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
++      if (error)
++              return error;
+       error = -ENXIO;
+       if (lo->lo_state != Lo_bound)
+-              goto out;
++              goto out_unlock;
+       /* the loop device has to be read-only */
+       error = -EINVAL;
+       if (!(lo->lo_flags & LO_FLAGS_READ_ONLY))
+-              goto out;
++              goto out_unlock;
+       error = -EBADF;
+       file = fget(arg);
+       if (!file)
+-              goto out;
++              goto out_unlock;
+       error = loop_validate_file(file, bdev);
+       if (error)
+@@ -731,11 +734,13 @@ static int loop_change_fd(struct loop_de
+       fput(old_file);
+       if (lo->lo_flags & LO_FLAGS_PARTSCAN)
+               loop_reread_partitions(lo, bdev);
++      mutex_unlock(&loop_ctl_mutex);
+       return 0;
+- out_putf:
++out_putf:
+       fput(file);
+- out:
++out_unlock:
++      mutex_unlock(&loop_ctl_mutex);
+       return error;
+ }
+@@ -1470,12 +1475,7 @@ static int lo_ioctl(struct block_device
+       case LOOP_SET_FD:
+               return loop_set_fd(lo, mode, bdev, arg);
+       case LOOP_CHANGE_FD:
+-              err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
+-              if (err)
+-                      return err;
+-              err = loop_change_fd(lo, bdev, arg);
+-              mutex_unlock(&loop_ctl_mutex);
+-              break;
++              return loop_change_fd(lo, bdev, arg);
+       case LOOP_CLR_FD:
+               return loop_clr_fd(lo);
+       case LOOP_SET_STATUS:
diff --git a/queue-4.19/loop-push-loop_ctl_mutex-down-to-loop_get_status.patch b/queue-4.19/loop-push-loop_ctl_mutex-down-to-loop_get_status.patch
new file mode 100644 (file)
index 0000000..a0e5e92
--- /dev/null
@@ -0,0 +1,112 @@
+From 4a5ce9ba5877e4640200d84a735361306ad1a1b8 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 8 Nov 2018 14:01:08 +0100
+Subject: loop: Push loop_ctl_mutex down to loop_get_status()
+
+From: Jan Kara <jack@suse.cz>
+
+commit 4a5ce9ba5877e4640200d84a735361306ad1a1b8 upstream.
+
+Push loop_ctl_mutex down to loop_get_status() to avoid the unusual
+convention that the function gets called with loop_ctl_mutex held and
+releases it.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |   37 ++++++++++---------------------------
+ 1 file changed, 10 insertions(+), 27 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -1233,6 +1233,9 @@ loop_get_status(struct loop_device *lo,
+       struct kstat stat;
+       int ret;
++      ret = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
++      if (ret)
++              return ret;
+       if (lo->lo_state != Lo_bound) {
+               mutex_unlock(&loop_ctl_mutex);
+               return -ENXIO;
+@@ -1347,10 +1350,8 @@ loop_get_status_old(struct loop_device *
+       struct loop_info64 info64;
+       int err;
+-      if (!arg) {
+-              mutex_unlock(&loop_ctl_mutex);
++      if (!arg)
+               return -EINVAL;
+-      }
+       err = loop_get_status(lo, &info64);
+       if (!err)
+               err = loop_info64_to_old(&info64, &info);
+@@ -1365,10 +1366,8 @@ loop_get_status64(struct loop_device *lo
+       struct loop_info64 info64;
+       int err;
+-      if (!arg) {
+-              mutex_unlock(&loop_ctl_mutex);
++      if (!arg)
+               return -EINVAL;
+-      }
+       err = loop_get_status(lo, &info64);
+       if (!err && copy_to_user(arg, &info64, sizeof(info64)))
+               err = -EFAULT;
+@@ -1478,12 +1477,7 @@ static int lo_ioctl(struct block_device
+               }
+               break;
+       case LOOP_GET_STATUS:
+-              err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
+-              if (err)
+-                      return err;
+-              err = loop_get_status_old(lo, (struct loop_info __user *) arg);
+-              /* loop_get_status() unlocks loop_ctl_mutex */
+-              break;
++              return loop_get_status_old(lo, (struct loop_info __user *) arg);
+       case LOOP_SET_STATUS64:
+               err = -EPERM;
+               if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) {
+@@ -1496,12 +1490,7 @@ static int lo_ioctl(struct block_device
+               }
+               break;
+       case LOOP_GET_STATUS64:
+-              err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
+-              if (err)
+-                      return err;
+-              err = loop_get_status64(lo, (struct loop_info64 __user *) arg);
+-              /* loop_get_status() unlocks loop_ctl_mutex */
+-              break;
++              return loop_get_status64(lo, (struct loop_info64 __user *) arg);
+       case LOOP_SET_CAPACITY:
+       case LOOP_SET_DIRECT_IO:
+       case LOOP_SET_BLOCK_SIZE:
+@@ -1626,10 +1615,8 @@ loop_get_status_compat(struct loop_devic
+       struct loop_info64 info64;
+       int err;
+-      if (!arg) {
+-              mutex_unlock(&loop_ctl_mutex);
++      if (!arg)
+               return -EINVAL;
+-      }
+       err = loop_get_status(lo, &info64);
+       if (!err)
+               err = loop_info64_to_compat(&info64, arg);
+@@ -1652,12 +1639,8 @@ static int lo_compat_ioctl(struct block_
+               }
+               break;
+       case LOOP_GET_STATUS:
+-              err = mutex_lock_killable(&loop_ctl_mutex);
+-              if (!err) {
+-                      err = loop_get_status_compat(lo,
+-                                                   (struct compat_loop_info __user *)arg);
+-                      /* loop_get_status() unlocks loop_ctl_mutex */
+-              }
++              err = loop_get_status_compat(lo,
++                                   (struct compat_loop_info __user *)arg);
+               break;
+       case LOOP_SET_CAPACITY:
+       case LOOP_CLR_FD:
diff --git a/queue-4.19/loop-push-loop_ctl_mutex-down-to-loop_set_fd.patch b/queue-4.19/loop-push-loop_ctl_mutex-down-to-loop_set_fd.patch
new file mode 100644 (file)
index 0000000..b23dc51
--- /dev/null
@@ -0,0 +1,86 @@
+From 757ecf40b7e029529768eb5f9562d5eeb3002106 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 8 Nov 2018 14:01:10 +0100
+Subject: loop: Push loop_ctl_mutex down to loop_set_fd()
+
+From: Jan Kara <jack@suse.cz>
+
+commit 757ecf40b7e029529768eb5f9562d5eeb3002106 upstream.
+
+Push lo_ctl_mutex down to loop_set_fd(). We will need this to be able to
+call loop_reread_partitions() without lo_ctl_mutex.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |   26 ++++++++++++++------------
+ 1 file changed, 14 insertions(+), 12 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -919,13 +919,17 @@ static int loop_set_fd(struct loop_devic
+       if (!file)
+               goto out;
++      error = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
++      if (error)
++              goto out_putf;
++
+       error = -EBUSY;
+       if (lo->lo_state != Lo_unbound)
+-              goto out_putf;
++              goto out_unlock;
+       error = loop_validate_file(file, bdev);
+       if (error)
+-              goto out_putf;
++              goto out_unlock;
+       mapping = file->f_mapping;
+       inode = mapping->host;
+@@ -937,10 +941,10 @@ static int loop_set_fd(struct loop_devic
+       error = -EFBIG;
+       size = get_loop_size(lo, file);
+       if ((loff_t)(sector_t)size != size)
+-              goto out_putf;
++              goto out_unlock;
+       error = loop_prepare_queue(lo);
+       if (error)
+-              goto out_putf;
++              goto out_unlock;
+       error = 0;
+@@ -979,11 +983,14 @@ static int loop_set_fd(struct loop_devic
+        * put /dev/loopXX inode. Later in __loop_clr_fd() we bdput(bdev).
+        */
+       bdgrab(bdev);
++      mutex_unlock(&loop_ctl_mutex);
+       return 0;
+- out_putf:
++out_unlock:
++      mutex_unlock(&loop_ctl_mutex);
++out_putf:
+       fput(file);
+- out:
++out:
+       /* This is safe: open() is still holding a reference. */
+       module_put(THIS_MODULE);
+       return error;
+@@ -1461,12 +1468,7 @@ static int lo_ioctl(struct block_device
+       switch (cmd) {
+       case LOOP_SET_FD:
+-              err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
+-              if (err)
+-                      return err;
+-              err = loop_set_fd(lo, mode, bdev, arg);
+-              mutex_unlock(&loop_ctl_mutex);
+-              break;
++              return loop_set_fd(lo, mode, bdev, arg);
+       case LOOP_CHANGE_FD:
+               err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
+               if (err)
diff --git a/queue-4.19/loop-push-loop_ctl_mutex-down-to-loop_set_status.patch b/queue-4.19/loop-push-loop_ctl_mutex-down-to-loop_set_status.patch
new file mode 100644 (file)
index 0000000..c310734
--- /dev/null
@@ -0,0 +1,148 @@
+From 550df5fdacff94229cde0ed9b8085155654c1696 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 8 Nov 2018 14:01:09 +0100
+Subject: loop: Push loop_ctl_mutex down to loop_set_status()
+
+From: Jan Kara <jack@suse.cz>
+
+commit 550df5fdacff94229cde0ed9b8085155654c1696 upstream.
+
+Push loop_ctl_mutex down to loop_set_status(). We will need this to be
+able to call loop_reread_partitions() without loop_ctl_mutex.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |   51 +++++++++++++++++++++++++--------------------------
+ 1 file changed, 25 insertions(+), 26 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -1142,46 +1142,55 @@ loop_set_status(struct loop_device *lo,
+       struct loop_func_table *xfer;
+       kuid_t uid = current_uid();
++      err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
++      if (err)
++              return err;
+       if (lo->lo_encrypt_key_size &&
+           !uid_eq(lo->lo_key_owner, uid) &&
+-          !capable(CAP_SYS_ADMIN))
+-              return -EPERM;
+-      if (lo->lo_state != Lo_bound)
+-              return -ENXIO;
+-      if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE)
+-              return -EINVAL;
++          !capable(CAP_SYS_ADMIN)) {
++              err = -EPERM;
++              goto out_unlock;
++      }
++      if (lo->lo_state != Lo_bound) {
++              err = -ENXIO;
++              goto out_unlock;
++      }
++      if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE) {
++              err = -EINVAL;
++              goto out_unlock;
++      }
+       /* I/O need to be drained during transfer transition */
+       blk_mq_freeze_queue(lo->lo_queue);
+       err = loop_release_xfer(lo);
+       if (err)
+-              goto exit;
++              goto out_unfreeze;
+       if (info->lo_encrypt_type) {
+               unsigned int type = info->lo_encrypt_type;
+               if (type >= MAX_LO_CRYPT) {
+                       err = -EINVAL;
+-                      goto exit;
++                      goto out_unfreeze;
+               }
+               xfer = xfer_funcs[type];
+               if (xfer == NULL) {
+                       err = -EINVAL;
+-                      goto exit;
++                      goto out_unfreeze;
+               }
+       } else
+               xfer = NULL;
+       err = loop_init_xfer(lo, xfer, info);
+       if (err)
+-              goto exit;
++              goto out_unfreeze;
+       if (lo->lo_offset != info->lo_offset ||
+           lo->lo_sizelimit != info->lo_sizelimit) {
+               if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit)) {
+                       err = -EFBIG;
+-                      goto exit;
++                      goto out_unfreeze;
+               }
+       }
+@@ -1213,7 +1222,7 @@ loop_set_status(struct loop_device *lo,
+       /* update dio if lo_offset or transfer is changed */
+       __loop_update_dio(lo, lo->use_dio);
+- exit:
++out_unfreeze:
+       blk_mq_unfreeze_queue(lo->lo_queue);
+       if (!err && (info->lo_flags & LO_FLAGS_PARTSCAN) &&
+@@ -1222,6 +1231,8 @@ loop_set_status(struct loop_device *lo,
+               lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;
+               loop_reread_partitions(lo, lo->lo_device);
+       }
++out_unlock:
++      mutex_unlock(&loop_ctl_mutex);
+       return err;
+ }
+@@ -1468,12 +1479,8 @@ static int lo_ioctl(struct block_device
+       case LOOP_SET_STATUS:
+               err = -EPERM;
+               if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) {
+-                      err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
+-                      if (err)
+-                              return err;
+                       err = loop_set_status_old(lo,
+                                       (struct loop_info __user *)arg);
+-                      mutex_unlock(&loop_ctl_mutex);
+               }
+               break;
+       case LOOP_GET_STATUS:
+@@ -1481,12 +1488,8 @@ static int lo_ioctl(struct block_device
+       case LOOP_SET_STATUS64:
+               err = -EPERM;
+               if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) {
+-                      err = mutex_lock_killable_nested(&loop_ctl_mutex, 1);
+-                      if (err)
+-                              return err;
+                       err = loop_set_status64(lo,
+                                       (struct loop_info64 __user *) arg);
+-                      mutex_unlock(&loop_ctl_mutex);
+               }
+               break;
+       case LOOP_GET_STATUS64:
+@@ -1631,12 +1634,8 @@ static int lo_compat_ioctl(struct block_
+       switch(cmd) {
+       case LOOP_SET_STATUS:
+-              err = mutex_lock_killable(&loop_ctl_mutex);
+-              if (!err) {
+-                      err = loop_set_status_compat(lo,
+-                                                   (const struct compat_loop_info __user *)arg);
+-                      mutex_unlock(&loop_ctl_mutex);
+-              }
++              err = loop_set_status_compat(lo,
++                           (const struct compat_loop_info __user *)arg);
+               break;
+       case LOOP_GET_STATUS:
+               err = loop_get_status_compat(lo,
diff --git a/queue-4.19/loop-split-setting-of-lo_state-from-loop_clr_fd.patch b/queue-4.19/loop-split-setting-of-lo_state-from-loop_clr_fd.patch
new file mode 100644 (file)
index 0000000..2750e6b
--- /dev/null
@@ -0,0 +1,121 @@
+From a2505b799a496b7b84d9a4a14ec870ff9e42e11b Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 8 Nov 2018 14:01:06 +0100
+Subject: loop: Split setting of lo_state from loop_clr_fd
+
+From: Jan Kara <jack@suse.cz>
+
+commit a2505b799a496b7b84d9a4a14ec870ff9e42e11b upstream.
+
+Move setting of lo_state to Lo_rundown out into the callers. That will
+allow us to unlock loop_ctl_mutex while the loop device is protected
+from other changes by its special state.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |   52 ++++++++++++++++++++++++++++++---------------------
+ 1 file changed, 31 insertions(+), 21 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -976,7 +976,7 @@ static int loop_set_fd(struct loop_devic
+               loop_reread_partitions(lo, bdev);
+       /* Grab the block_device to prevent its destruction after we
+-       * put /dev/loopXX inode. Later in loop_clr_fd() we bdput(bdev).
++       * put /dev/loopXX inode. Later in __loop_clr_fd() we bdput(bdev).
+        */
+       bdgrab(bdev);
+       return 0;
+@@ -1026,31 +1026,15 @@ loop_init_xfer(struct loop_device *lo, s
+       return err;
+ }
+-static int loop_clr_fd(struct loop_device *lo)
++static int __loop_clr_fd(struct loop_device *lo)
+ {
+       struct file *filp = lo->lo_backing_file;
+       gfp_t gfp = lo->old_gfp_mask;
+       struct block_device *bdev = lo->lo_device;
+-      if (lo->lo_state != Lo_bound)
++      if (WARN_ON_ONCE(lo->lo_state != Lo_rundown))
+               return -ENXIO;
+-      /*
+-       * If we've explicitly asked to tear down the loop device,
+-       * and it has an elevated reference count, set it for auto-teardown when
+-       * the last reference goes away. This stops $!~#$@ udev from
+-       * preventing teardown because it decided that it needs to run blkid on
+-       * the loopback device whenever they appear. xfstests is notorious for
+-       * failing tests because blkid via udev races with a losetup
+-       * <dev>/do something like mkfs/losetup -d <dev> causing the losetup -d
+-       * command to fail with EBUSY.
+-       */
+-      if (atomic_read(&lo->lo_refcnt) > 1) {
+-              lo->lo_flags |= LO_FLAGS_AUTOCLEAR;
+-              mutex_unlock(&loop_ctl_mutex);
+-              return 0;
+-      }
+-
+       if (filp == NULL)
+               return -EINVAL;
+@@ -1058,7 +1042,6 @@ static int loop_clr_fd(struct loop_devic
+       blk_mq_freeze_queue(lo->lo_queue);
+       spin_lock_irq(&lo->lo_lock);
+-      lo->lo_state = Lo_rundown;
+       lo->lo_backing_file = NULL;
+       spin_unlock_irq(&lo->lo_lock);
+@@ -1111,6 +1094,30 @@ static int loop_clr_fd(struct loop_devic
+       return 0;
+ }
++static int loop_clr_fd(struct loop_device *lo)
++{
++      if (lo->lo_state != Lo_bound)
++              return -ENXIO;
++      /*
++       * If we've explicitly asked to tear down the loop device,
++       * and it has an elevated reference count, set it for auto-teardown when
++       * the last reference goes away. This stops $!~#$@ udev from
++       * preventing teardown because it decided that it needs to run blkid on
++       * the loopback device whenever they appear. xfstests is notorious for
++       * failing tests because blkid via udev races with a losetup
++       * <dev>/do something like mkfs/losetup -d <dev> causing the losetup -d
++       * command to fail with EBUSY.
++       */
++      if (atomic_read(&lo->lo_refcnt) > 1) {
++              lo->lo_flags |= LO_FLAGS_AUTOCLEAR;
++              mutex_unlock(&loop_ctl_mutex);
++              return 0;
++      }
++      lo->lo_state = Lo_rundown;
++
++      return __loop_clr_fd(lo);
++}
++
+ static int
+ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
+ {
+@@ -1692,11 +1699,14 @@ static void lo_release(struct gendisk *d
+               goto out_unlock;
+       if (lo->lo_flags & LO_FLAGS_AUTOCLEAR) {
++              if (lo->lo_state != Lo_bound)
++                      goto out_unlock;
++              lo->lo_state = Lo_rundown;
+               /*
+                * In autoclear mode, stop the loop thread
+                * and remove configuration after last close.
+                */
+-              err = loop_clr_fd(lo);
++              err = __loop_clr_fd(lo);
+               if (!err)
+                       return;
+       } else if (lo->lo_state == Lo_bound) {
diff --git a/queue-4.19/lsm-check-for-null-cred-security-on-free.patch b/queue-4.19/lsm-check-for-null-cred-security-on-free.patch
new file mode 100644 (file)
index 0000000..8ba7c51
--- /dev/null
@@ -0,0 +1,41 @@
+From a5795fd38ee8194451ba3f281f075301a3696ce2 Mon Sep 17 00:00:00 2001
+From: James Morris <james.morris@microsoft.com>
+Date: Wed, 16 Jan 2019 15:41:11 -0800
+Subject: LSM: Check for NULL cred-security on free
+
+From: James Morris <james.morris@microsoft.com>
+
+commit a5795fd38ee8194451ba3f281f075301a3696ce2 upstream.
+
+From: Casey Schaufler <casey@schaufler-ca.com>
+
+Check that the cred security blob has been set before trying
+to clean it up. There is a case during credential initialization
+that could result in this.
+
+Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
+Acked-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: James Morris <james.morris@microsoft.com>
+Reported-by: syzbot+69ca07954461f189e808@syzkaller.appspotmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/security.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/security/security.c
++++ b/security/security.c
+@@ -1003,6 +1003,13 @@ int security_cred_alloc_blank(struct cre
+ void security_cred_free(struct cred *cred)
+ {
++      /*
++       * There is a failure case in prepare_creds() that
++       * may result in a call here with ->security being NULL.
++       */
++      if (unlikely(cred->security == NULL))
++              return;
++
+       call_void_hook(cred_free, cred);
+ }
diff --git a/queue-4.19/media-v4l-ioctl-validate-num_planes-for-debug-messages.patch b/queue-4.19/media-v4l-ioctl-validate-num_planes-for-debug-messages.patch
new file mode 100644 (file)
index 0000000..c9d4c0d
--- /dev/null
@@ -0,0 +1,45 @@
+From 7fe9f01c04c2673bd6662c35b664f0f91888b96f Mon Sep 17 00:00:00 2001
+From: Sakari Ailus <sakari.ailus@linux.intel.com>
+Date: Thu, 10 Jan 2019 09:24:26 -0500
+Subject: media: v4l: ioctl: Validate num_planes for debug messages
+
+From: Sakari Ailus <sakari.ailus@linux.intel.com>
+
+commit 7fe9f01c04c2673bd6662c35b664f0f91888b96f upstream.
+
+The num_planes field in struct v4l2_pix_format_mplane is used in a loop
+before validating it. As the use is printing a debug message in this case,
+just cap the value to the maximum allowed.
+
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Cc: <stable@vger.kernel.org>      # for v4.12 and up
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/v4l2-core/v4l2-ioctl.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/media/v4l2-core/v4l2-ioctl.c
++++ b/drivers/media/v4l2-core/v4l2-ioctl.c
+@@ -286,6 +286,7 @@ static void v4l_print_format(const void
+       const struct v4l2_window *win;
+       const struct v4l2_sdr_format *sdr;
+       const struct v4l2_meta_format *meta;
++      u32 planes;
+       unsigned i;
+       pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
+@@ -316,7 +317,8 @@ static void v4l_print_format(const void
+                       prt_names(mp->field, v4l2_field_names),
+                       mp->colorspace, mp->num_planes, mp->flags,
+                       mp->ycbcr_enc, mp->quantization, mp->xfer_func);
+-              for (i = 0; i < mp->num_planes; i++)
++              planes = min_t(u32, mp->num_planes, VIDEO_MAX_PLANES);
++              for (i = 0; i < planes; i++)
+                       printk(KERN_DEBUG "plane %u: bytesperline=%u sizeimage=%u\n", i,
+                                       mp->plane_fmt[i].bytesperline,
+                                       mp->plane_fmt[i].sizeimage);
diff --git a/queue-4.19/media-vb2-vb2_mmap-move-lock-up.patch b/queue-4.19/media-vb2-vb2_mmap-move-lock-up.patch
new file mode 100644 (file)
index 0000000..e3ec70c
--- /dev/null
@@ -0,0 +1,65 @@
+From cd26d1c4d1bc947b56ae404998ae2276df7b39b7 Mon Sep 17 00:00:00 2001
+From: Hans Verkuil <hverkuil@xs4all.nl>
+Date: Tue, 13 Nov 2018 09:06:46 -0500
+Subject: media: vb2: vb2_mmap: move lock up
+
+From: Hans Verkuil <hverkuil@xs4all.nl>
+
+commit cd26d1c4d1bc947b56ae404998ae2276df7b39b7 upstream.
+
+If a filehandle is dup()ped, then it is possible to close it from one fd
+and call mmap from the other. This creates a race condition in vb2_mmap
+where it is using queue data that __vb2_queue_free (called from close())
+is in the process of releasing.
+
+By moving up the mutex_lock(mmap_lock) in vb2_mmap this race is avoided
+since __vb2_queue_free is called with the same mutex locked. So vb2_mmap
+now reads consistent buffer data.
+
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Reported-by: syzbot+be93025dd45dccd8923c@syzkaller.appspotmail.com
+Signed-off-by: Hans Verkuil <hansverk@cisco.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/common/videobuf2/videobuf2-core.c |   11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/media/common/videobuf2/videobuf2-core.c
++++ b/drivers/media/common/videobuf2/videobuf2-core.c
+@@ -1933,9 +1933,13 @@ int vb2_mmap(struct vb2_queue *q, struct
+                       return -EINVAL;
+               }
+       }
++
++      mutex_lock(&q->mmap_lock);
++
+       if (vb2_fileio_is_active(q)) {
+               dprintk(1, "mmap: file io in progress\n");
+-              return -EBUSY;
++              ret = -EBUSY;
++              goto unlock;
+       }
+       /*
+@@ -1943,7 +1947,7 @@ int vb2_mmap(struct vb2_queue *q, struct
+        */
+       ret = __find_plane_by_offset(q, off, &buffer, &plane);
+       if (ret)
+-              return ret;
++              goto unlock;
+       vb = q->bufs[buffer];
+@@ -1959,8 +1963,9 @@ int vb2_mmap(struct vb2_queue *q, struct
+               return -EINVAL;
+       }
+-      mutex_lock(&q->mmap_lock);
+       ret = call_memop(vb, mmap, vb->planes[plane].mem_priv, vma);
++
++unlock:
+       mutex_unlock(&q->mmap_lock);
+       if (ret)
+               return ret;
diff --git a/queue-4.19/media-vivid-fix-error-handling-of-kthread_run.patch b/queue-4.19/media-vivid-fix-error-handling-of-kthread_run.patch
new file mode 100644 (file)
index 0000000..d0a615d
--- /dev/null
@@ -0,0 +1,57 @@
+From 701f49bc028edb19ffccd101997dd84f0d71e279 Mon Sep 17 00:00:00 2001
+From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Date: Mon, 29 Oct 2018 06:15:31 -0400
+Subject: media: vivid: fix error handling of kthread_run
+
+From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+
+commit 701f49bc028edb19ffccd101997dd84f0d71e279 upstream.
+
+kthread_run returns an error pointer, but elsewhere in the code
+dev->kthread_vid_cap/out is checked against NULL.
+
+If kthread_run returns an error, then set the pointer to NULL.
+
+I chose this method over changing all kthread_vid_cap/out tests
+elsewhere since this is more robust.
+
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Reported-by: syzbot+53d5b2df0d9744411e2e@syzkaller.appspotmail.com
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/platform/vivid/vivid-kthread-cap.c |    5 ++++-
+ drivers/media/platform/vivid/vivid-kthread-out.c |    5 ++++-
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/media/platform/vivid/vivid-kthread-cap.c
++++ b/drivers/media/platform/vivid/vivid-kthread-cap.c
+@@ -865,8 +865,11 @@ int vivid_start_generating_vid_cap(struc
+                       "%s-vid-cap", dev->v4l2_dev.name);
+       if (IS_ERR(dev->kthread_vid_cap)) {
++              int err = PTR_ERR(dev->kthread_vid_cap);
++
++              dev->kthread_vid_cap = NULL;
+               v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
+-              return PTR_ERR(dev->kthread_vid_cap);
++              return err;
+       }
+       *pstreaming = true;
+       vivid_grab_controls(dev, true);
+--- a/drivers/media/platform/vivid/vivid-kthread-out.c
++++ b/drivers/media/platform/vivid/vivid-kthread-out.c
+@@ -236,8 +236,11 @@ int vivid_start_generating_vid_out(struc
+                       "%s-vid-out", dev->v4l2_dev.name);
+       if (IS_ERR(dev->kthread_vid_out)) {
++              int err = PTR_ERR(dev->kthread_vid_out);
++
++              dev->kthread_vid_out = NULL;
+               v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
+-              return PTR_ERR(dev->kthread_vid_out);
++              return err;
+       }
+       *pstreaming = true;
+       vivid_grab_controls(dev, true);
diff --git a/queue-4.19/media-vivid-set-min-width-height-to-a-value-0.patch b/queue-4.19/media-vivid-set-min-width-height-to-a-value-0.patch
new file mode 100644 (file)
index 0000000..7bac915
--- /dev/null
@@ -0,0 +1,35 @@
+From 9729d6d282a6d7ce88e64c9119cecdf79edf4e88 Mon Sep 17 00:00:00 2001
+From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Date: Mon, 29 Oct 2018 13:32:38 -0400
+Subject: media: vivid: set min width/height to a value > 0
+
+From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+
+commit 9729d6d282a6d7ce88e64c9119cecdf79edf4e88 upstream.
+
+The capture DV timings capabilities allowed for a minimum width and
+height of 0. So passing a timings struct with 0 values is allowed
+and will later cause a division by zero.
+
+Ensure that the width and height must be >= 16 to avoid this.
+
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Reported-by: syzbot+57c3d83d71187054d56f@syzkaller.appspotmail.com
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/platform/vivid/vivid-vid-common.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/media/platform/vivid/vivid-vid-common.c
++++ b/drivers/media/platform/vivid/vivid-vid-common.c
+@@ -21,7 +21,7 @@ const struct v4l2_dv_timings_cap vivid_d
+       .type = V4L2_DV_BT_656_1120,
+       /* keep this initialization for compatibility with GCC < 4.4.6 */
+       .reserved = { 0 },
+-      V4L2_INIT_BT_TIMINGS(0, MAX_WIDTH, 0, MAX_HEIGHT, 14000000, 775000000,
++      V4L2_INIT_BT_TIMINGS(16, MAX_WIDTH, 16, MAX_HEIGHT, 14000000, 775000000,
+               V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
+               V4L2_DV_BT_STD_CVT | V4L2_DV_BT_STD_GTF,
+               V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_INTERLACED)
diff --git a/queue-4.19/mfd-tps6586x-handle-interrupts-on-suspend.patch b/queue-4.19/mfd-tps6586x-handle-interrupts-on-suspend.patch
new file mode 100644 (file)
index 0000000..8c143e2
--- /dev/null
@@ -0,0 +1,94 @@
+From ac4ca4b9f4623ba5e1ea7a582f286567c611e027 Mon Sep 17 00:00:00 2001
+From: Jonathan Hunter <jonathanh@nvidia.com>
+Date: Tue, 13 Nov 2018 08:56:31 +0000
+Subject: mfd: tps6586x: Handle interrupts on suspend
+
+From: Jonathan Hunter <jonathanh@nvidia.com>
+
+commit ac4ca4b9f4623ba5e1ea7a582f286567c611e027 upstream.
+
+The tps6586x driver creates an irqchip that is used by its various child
+devices for managing interrupts. The tps6586x-rtc device is one of its
+children that uses the tps6586x irqchip. When using the tps6586x-rtc as
+a wake-up device from suspend, the following is seen:
+
+ PM: Syncing filesystems ... done.
+ Freezing user space processes ... (elapsed 0.001 seconds) done.
+ OOM killer disabled.
+ Freezing remaining freezable tasks ... (elapsed 0.000 seconds) done.
+ Disabling non-boot CPUs ...
+ Entering suspend state LP1
+ Enabling non-boot CPUs ...
+ CPU1 is up
+ tps6586x 3-0034: failed to read interrupt status
+ tps6586x 3-0034: failed to read interrupt status
+
+The reason why the tps6586x interrupt status cannot be read is because
+the tps6586x interrupt is not masked during suspend and when the
+tps6586x-rtc interrupt occurs, to wake-up the device, the interrupt is
+seen before the i2c controller has been resumed in order to read the
+tps6586x interrupt status.
+
+The tps6586x-rtc driver sets it's interrupt as a wake-up source during
+suspend, which gets propagated to the parent tps6586x interrupt.
+However, the tps6586x-rtc driver cannot disable it's interrupt during
+suspend otherwise we would never be woken up and so the tps6586x must
+disable it's interrupt instead.
+
+Prevent the tps6586x interrupt handler from executing on exiting suspend
+before the i2c controller has been resumed by disabling the tps6586x
+interrupt on entering suspend and re-enabling it on resuming from
+suspend.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
+Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
+Tested-by: Dmitry Osipenko <digetx@gmail.com>
+Acked-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mfd/tps6586x.c |   24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+--- a/drivers/mfd/tps6586x.c
++++ b/drivers/mfd/tps6586x.c
+@@ -592,6 +592,29 @@ static int tps6586x_i2c_remove(struct i2
+       return 0;
+ }
++static int __maybe_unused tps6586x_i2c_suspend(struct device *dev)
++{
++      struct tps6586x *tps6586x = dev_get_drvdata(dev);
++
++      if (tps6586x->client->irq)
++              disable_irq(tps6586x->client->irq);
++
++      return 0;
++}
++
++static int __maybe_unused tps6586x_i2c_resume(struct device *dev)
++{
++      struct tps6586x *tps6586x = dev_get_drvdata(dev);
++
++      if (tps6586x->client->irq)
++              enable_irq(tps6586x->client->irq);
++
++      return 0;
++}
++
++static SIMPLE_DEV_PM_OPS(tps6586x_pm_ops, tps6586x_i2c_suspend,
++                       tps6586x_i2c_resume);
++
+ static const struct i2c_device_id tps6586x_id_table[] = {
+       { "tps6586x", 0 },
+       { },
+@@ -602,6 +625,7 @@ static struct i2c_driver tps6586x_driver
+       .driver = {
+               .name   = "tps6586x",
+               .of_match_table = of_match_ptr(tps6586x_of_match),
++              .pm     = &tps6586x_pm_ops,
+       },
+       .probe          = tps6586x_i2c_probe,
+       .remove         = tps6586x_i2c_remove,
diff --git a/queue-4.19/mips-bcm47xx-setup-struct-device-for-the-soc.patch b/queue-4.19/mips-bcm47xx-setup-struct-device-for-the-soc.patch
new file mode 100644 (file)
index 0000000..c6d2fff
--- /dev/null
@@ -0,0 +1,144 @@
+From 321c46b91550adc03054125fa7a1639390608e1a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Thu, 3 Jan 2019 08:34:17 +0100
+Subject: MIPS: BCM47XX: Setup struct device for the SoC
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: RafaÅ‚ MiÅ‚ecki <rafal@milecki.pl>
+
+commit 321c46b91550adc03054125fa7a1639390608e1a upstream.
+
+So far we never had any device registered for the SoC. This resulted in
+some small issues that we kept ignoring like:
+1) Not working GPIOLIB_IRQCHIP (gpiochip_irqchip_add_key() failing)
+2) Lack of proper tree in the /sys/devices/
+3) mips_dma_alloc_coherent() silently handling empty coherent_dma_mask
+
+Kernel 4.19 came with a lot of DMA changes and caused a regression on
+bcm47xx. Starting with the commit f8c55dc6e828 ("MIPS: use generic dma
+noncoherent ops for simple noncoherent platforms") DMA coherent
+allocations just fail. Example:
+[    1.114914] bgmac_bcma bcma0:2: Allocation of TX ring 0x200 failed
+[    1.121215] bgmac_bcma bcma0:2: Unable to alloc memory for DMA
+[    1.127626] bgmac_bcma: probe of bcma0:2 failed with error -12
+[    1.133838] bgmac_bcma: Broadcom 47xx GBit MAC driver loaded
+
+The bgmac driver also triggers a WARNING:
+[    0.959486] ------------[ cut here ]------------
+[    0.964387] WARNING: CPU: 0 PID: 1 at ./include/linux/dma-mapping.h:516 bgmac_enet_probe+0x1b4/0x5c4
+[    0.973751] Modules linked in:
+[    0.976913] CPU: 0 PID: 1 Comm: swapper Not tainted 4.19.9 #0
+[    0.982750] Stack : 804a0000 804597c4 00000000 00000000 80458fd8 8381bc2c 838282d4 80481a47
+[    0.991367]         8042e3ec 00000001 804d38f0 00000204 83980000 00000065 8381bbe0 6f55b24f
+[    0.999975]         00000000 00000000 80520000 00002018 00000000 00000075 00000007 00000000
+[    1.008583]         00000000 80480000 000ee811 00000000 00000000 00000000 80432c00 80248db8
+[    1.017196]         00000009 00000204 83980000 803ad7b0 00000000 801feeec 00000000 804d0000
+[    1.025804]         ...
+[    1.028325] Call Trace:
+[    1.030875] [<8000aef8>] show_stack+0x58/0x100
+[    1.035513] [<8001f8b4>] __warn+0xe4/0x118
+[    1.039708] [<8001f9a4>] warn_slowpath_null+0x48/0x64
+[    1.044935] [<80248db8>] bgmac_enet_probe+0x1b4/0x5c4
+[    1.050101] [<802498e0>] bgmac_probe+0x558/0x590
+[    1.054906] [<80252fd0>] bcma_device_probe+0x38/0x70
+[    1.060017] [<8020e1e8>] really_probe+0x170/0x2e8
+[    1.064891] [<8020e714>] __driver_attach+0xa4/0xec
+[    1.069784] [<8020c1e0>] bus_for_each_dev+0x58/0xb0
+[    1.074833] [<8020d590>] bus_add_driver+0xf8/0x218
+[    1.079731] [<8020ef24>] driver_register+0xcc/0x11c
+[    1.084804] [<804b54cc>] bgmac_init+0x1c/0x44
+[    1.089258] [<8000121c>] do_one_initcall+0x7c/0x1a0
+[    1.094343] [<804a1d34>] kernel_init_freeable+0x150/0x218
+[    1.099886] [<803a082c>] kernel_init+0x10/0x104
+[    1.104583] [<80005878>] ret_from_kernel_thread+0x14/0x1c
+[    1.110107] ---[ end trace f441c0d873d1fb5b ]---
+
+This patch setups a "struct device" (and passes it to the bcma) which
+allows fixing all the mentioned problems. It'll also require a tiny bcma
+patch which will follow through the wireless tree & its maintainer.
+
+Fixes: f8c55dc6e828 ("MIPS: use generic dma noncoherent ops for simple noncoherent platforms")
+Signed-off-by: RafaÅ‚ MiÅ‚ecki <rafal@milecki.pl>
+Signed-off-by: Paul Burton <paul.burton@mips.com>
+Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Linus Walleij <linus.walleij@linaro.org>
+Cc: linux-wireless@vger.kernel.org
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Cc: James Hogan <jhogan@kernel.org>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Cc: stable@vger.kernel.org # v4.19+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/bcm47xx/setup.c     |   31 +++++++++++++++++++++++++++++++
+ include/linux/bcma/bcma_soc.h |    1 +
+ 2 files changed, 32 insertions(+)
+
+--- a/arch/mips/bcm47xx/setup.c
++++ b/arch/mips/bcm47xx/setup.c
+@@ -173,6 +173,31 @@ void __init plat_mem_setup(void)
+       pm_power_off = bcm47xx_machine_halt;
+ }
++#ifdef CONFIG_BCM47XX_BCMA
++static struct device * __init bcm47xx_setup_device(void)
++{
++      struct device *dev;
++      int err;
++
++      dev = kzalloc(sizeof(*dev), GFP_KERNEL);
++      if (!dev)
++              return NULL;
++
++      err = dev_set_name(dev, "bcm47xx_soc");
++      if (err) {
++              pr_err("Failed to set SoC device name: %d\n", err);
++              kfree(dev);
++              return NULL;
++      }
++
++      err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
++      if (err)
++              pr_err("Failed to set SoC DMA mask: %d\n", err);
++
++      return dev;
++}
++#endif
++
+ /*
+  * This finishes bus initialization doing things that were not possible without
+  * kmalloc. Make sure to call it late enough (after mm_init).
+@@ -183,6 +208,10 @@ void __init bcm47xx_bus_setup(void)
+       if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) {
+               int err;
++              bcm47xx_bus.bcma.dev = bcm47xx_setup_device();
++              if (!bcm47xx_bus.bcma.dev)
++                      panic("Failed to setup SoC device\n");
++
+               err = bcma_host_soc_init(&bcm47xx_bus.bcma);
+               if (err)
+                       panic("Failed to initialize BCMA bus (err %d)", err);
+@@ -235,6 +264,8 @@ static int __init bcm47xx_register_bus_c
+ #endif
+ #ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
++              if (device_register(bcm47xx_bus.bcma.dev))
++                      pr_err("Failed to register SoC device\n");
+               bcma_bus_register(&bcm47xx_bus.bcma.bus);
+               break;
+ #endif
+--- a/include/linux/bcma/bcma_soc.h
++++ b/include/linux/bcma/bcma_soc.h
+@@ -6,6 +6,7 @@
+ struct bcma_soc {
+       struct bcma_bus bus;
++      struct device *dev;
+ };
+ int __init bcma_host_soc_register(struct bcma_soc *soc);
diff --git a/queue-4.19/mips-fix-n32-compat_ipc_parse_version.patch b/queue-4.19/mips-fix-n32-compat_ipc_parse_version.patch
new file mode 100644 (file)
index 0000000..1c5fb9c
--- /dev/null
@@ -0,0 +1,41 @@
+From 5a9372f751b5350e0ce3d2ee91832f1feae2c2e5 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Thu, 10 Jan 2019 17:24:31 +0100
+Subject: mips: fix n32 compat_ipc_parse_version
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit 5a9372f751b5350e0ce3d2ee91832f1feae2c2e5 upstream.
+
+While reading through the sysvipc implementation, I noticed that the n32
+semctl/shmctl/msgctl system calls behave differently based on whether
+o32 support is enabled or not: Without o32, the IPC_64 flag passed by
+user space is rejected but calls without that flag get IPC_64 behavior.
+
+As far as I can tell, this was inadvertently changed by a cleanup patch
+but never noticed by anyone, possibly nobody has tried using sysvipc
+on n32 after linux-3.19.
+
+Change it back to the old behavior now.
+
+Fixes: 78aaf956ba3a ("MIPS: Compat: Fix build error if CONFIG_MIPS32_COMPAT but no compat ABI.")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Paul Burton <paul.burton@mips.com>
+Cc: linux-mips@vger.kernel.org
+Cc: stable@vger.kernel.org # 3.19+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/Kconfig |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -3149,6 +3149,7 @@ config MIPS32_O32
+ config MIPS32_N32
+       bool "Kernel support for n32 binaries"
+       depends on 64BIT
++      select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
+       select COMPAT
+       select MIPS32_COMPAT
+       select SYSVIPC_COMPAT if SYSVIPC
diff --git a/queue-4.19/mips-lantiq-fix-ipi-interrupt-handling.patch b/queue-4.19/mips-lantiq-fix-ipi-interrupt-handling.patch
new file mode 100644 (file)
index 0000000..daa48be
--- /dev/null
@@ -0,0 +1,146 @@
+From 2b4dba55b04b212a7fd1f0395b41d79ee3a9801b Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Sun, 6 Jan 2019 19:44:11 +0100
+Subject: MIPS: lantiq: Fix IPI interrupt handling
+
+From: Hauke Mehrtens <hauke@hauke-m.de>
+
+commit 2b4dba55b04b212a7fd1f0395b41d79ee3a9801b upstream.
+
+This makes SMP on the vrx200 work again, by removing all the MIPS CPU
+interrupt specific code and making it fully use the generic MIPS CPU
+interrupt controller.
+
+The mti,cpu-interrupt-controller from irq-mips-cpu.c now handles the CPU
+interrupts and also the IPI interrupts which are used to communication
+between the CPUs in a SMP system. The generic interrupt code was
+already used before but the interrupt vectors were overwritten again
+when we called set_vi_handler() in the lantiq interrupt driver and we
+also provided our own plat_irq_dispatch() function which overwrote the
+weak generic implementation. Now the code uses the generic handler for
+the MIPS CPU interrupts including the IPI interrupts and registers a
+handler for the CPU interrupts which are handled by the lantiq ICU with
+irq_set_chained_handler() which was already called before.
+
+Calling the set_c0_status() function is also not needed any more because
+the generic MIPS CPU interrupt already activates the needed bits.
+
+Fixes: 1eed40043579 ("MIPS: smp-mt: Use CPU interrupt controller IPI IRQ domain support")
+Cc: stable@kernel.org # v4.12
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+Signed-off-by: Paul Burton <paul.burton@mips.com>
+Cc: jhogan@kernel.org
+Cc: ralf@linux-mips.org
+Cc: john@phrozen.org
+Cc: linux-mips@linux-mips.org
+Cc: linux-mips@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/lantiq/irq.c |   68 +++----------------------------------------------
+ 1 file changed, 5 insertions(+), 63 deletions(-)
+
+--- a/arch/mips/lantiq/irq.c
++++ b/arch/mips/lantiq/irq.c
+@@ -224,9 +224,11 @@ static struct irq_chip ltq_eiu_type = {
+       .irq_set_type = ltq_eiu_settype,
+ };
+-static void ltq_hw_irqdispatch(int module)
++static void ltq_hw_irq_handler(struct irq_desc *desc)
+ {
++      int module = irq_desc_get_irq(desc) - 2;
+       u32 irq;
++      int hwirq;
+       irq = ltq_icu_r32(module, LTQ_ICU_IM0_IOSR);
+       if (irq == 0)
+@@ -237,7 +239,8 @@ static void ltq_hw_irqdispatch(int modul
+        * other bits might be bogus
+        */
+       irq = __fls(irq);
+-      do_IRQ((int)irq + MIPS_CPU_IRQ_CASCADE + (INT_NUM_IM_OFFSET * module));
++      hwirq = irq + MIPS_CPU_IRQ_CASCADE + (INT_NUM_IM_OFFSET * module);
++      generic_handle_irq(irq_linear_revmap(ltq_domain, hwirq));
+       /* if this is a EBU irq, we need to ack it or get a deadlock */
+       if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0) && LTQ_EBU_PCC_ISTAT)
+@@ -245,49 +248,6 @@ static void ltq_hw_irqdispatch(int modul
+                       LTQ_EBU_PCC_ISTAT);
+ }
+-#define DEFINE_HWx_IRQDISPATCH(x)                                     \
+-      static void ltq_hw ## x ## _irqdispatch(void)                   \
+-      {                                                               \
+-              ltq_hw_irqdispatch(x);                                  \
+-      }
+-DEFINE_HWx_IRQDISPATCH(0)
+-DEFINE_HWx_IRQDISPATCH(1)
+-DEFINE_HWx_IRQDISPATCH(2)
+-DEFINE_HWx_IRQDISPATCH(3)
+-DEFINE_HWx_IRQDISPATCH(4)
+-
+-#if MIPS_CPU_TIMER_IRQ == 7
+-static void ltq_hw5_irqdispatch(void)
+-{
+-      do_IRQ(MIPS_CPU_TIMER_IRQ);
+-}
+-#else
+-DEFINE_HWx_IRQDISPATCH(5)
+-#endif
+-
+-static void ltq_hw_irq_handler(struct irq_desc *desc)
+-{
+-      ltq_hw_irqdispatch(irq_desc_get_irq(desc) - 2);
+-}
+-
+-asmlinkage void plat_irq_dispatch(void)
+-{
+-      unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
+-      int irq;
+-
+-      if (!pending) {
+-              spurious_interrupt();
+-              return;
+-      }
+-
+-      pending >>= CAUSEB_IP;
+-      while (pending) {
+-              irq = fls(pending) - 1;
+-              do_IRQ(MIPS_CPU_IRQ_BASE + irq);
+-              pending &= ~BIT(irq);
+-      }
+-}
+-
+ static int icu_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
+ {
+       struct irq_chip *chip = &ltq_irq_type;
+@@ -343,28 +303,10 @@ int __init icu_of_init(struct device_nod
+       for (i = 0; i < MAX_IM; i++)
+               irq_set_chained_handler(i + 2, ltq_hw_irq_handler);
+-      if (cpu_has_vint) {
+-              pr_info("Setting up vectored interrupts\n");
+-              set_vi_handler(2, ltq_hw0_irqdispatch);
+-              set_vi_handler(3, ltq_hw1_irqdispatch);
+-              set_vi_handler(4, ltq_hw2_irqdispatch);
+-              set_vi_handler(5, ltq_hw3_irqdispatch);
+-              set_vi_handler(6, ltq_hw4_irqdispatch);
+-              set_vi_handler(7, ltq_hw5_irqdispatch);
+-      }
+-
+       ltq_domain = irq_domain_add_linear(node,
+               (MAX_IM * INT_NUM_IM_OFFSET) + MIPS_CPU_IRQ_CASCADE,
+               &irq_domain_ops, 0);
+-#ifndef CONFIG_MIPS_MT_SMP
+-      set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 |
+-              IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
+-#else
+-      set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 |
+-              IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
+-#endif
+-
+       /* tell oprofile which irq to use */
+       ltq_perfcount_irq = irq_create_mapping(ltq_domain, LTQ_PERF_IRQ);
diff --git a/queue-4.19/net-dsa-realtek-smi-fix-of-child-node-lookup.patch b/queue-4.19/net-dsa-realtek-smi-fix-of-child-node-lookup.patch
new file mode 100644 (file)
index 0000000..ce1487f
--- /dev/null
@@ -0,0 +1,76 @@
+From 3f1bb6abdf19cfa89860b3bc9e7f31b44b6a0ba1 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 16 Jan 2019 11:27:08 +0100
+Subject: net: dsa: realtek-smi: fix OF child-node lookup
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 3f1bb6abdf19cfa89860b3bc9e7f31b44b6a0ba1 upstream.
+
+Use the new of_get_compatible_child() helper to look up child nodes to
+avoid ever matching non-child nodes elsewhere in the tree.
+
+Also fix up the related struct device_node leaks.
+
+Fixes: d8652956cf37 ("net: dsa: realtek-smi: Add Realtek SMI driver")
+Cc: stable <stable@vger.kernel.org>     # 4.19: 36156f9241cb0
+Cc: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/dsa/realtek-smi.c |   18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/dsa/realtek-smi.c
++++ b/drivers/net/dsa/realtek-smi.c
+@@ -347,16 +347,17 @@ int realtek_smi_setup_mdio(struct realte
+       struct device_node *mdio_np;
+       int ret;
+-      mdio_np = of_find_compatible_node(smi->dev->of_node, NULL,
+-                                        "realtek,smi-mdio");
++      mdio_np = of_get_compatible_child(smi->dev->of_node, "realtek,smi-mdio");
+       if (!mdio_np) {
+               dev_err(smi->dev, "no MDIO bus node\n");
+               return -ENODEV;
+       }
+       smi->slave_mii_bus = devm_mdiobus_alloc(smi->dev);
+-      if (!smi->slave_mii_bus)
+-              return -ENOMEM;
++      if (!smi->slave_mii_bus) {
++              ret = -ENOMEM;
++              goto err_put_node;
++      }
+       smi->slave_mii_bus->priv = smi;
+       smi->slave_mii_bus->name = "SMI slave MII";
+       smi->slave_mii_bus->read = realtek_smi_mdio_read;
+@@ -371,10 +372,15 @@ int realtek_smi_setup_mdio(struct realte
+       if (ret) {
+               dev_err(smi->dev, "unable to register MDIO bus %s\n",
+                       smi->slave_mii_bus->id);
+-              of_node_put(mdio_np);
++              goto err_put_node;
+       }
+       return 0;
++
++err_put_node:
++      of_node_put(mdio_np);
++
++      return ret;
+ }
+ static int realtek_smi_probe(struct platform_device *pdev)
+@@ -457,6 +463,8 @@ static int realtek_smi_remove(struct pla
+       struct realtek_smi *smi = dev_get_drvdata(&pdev->dev);
+       dsa_unregister_switch(smi->ds);
++      if (smi->slave_mii_bus)
++              of_node_put(smi->slave_mii_bus->dev.of_node);
+       gpiod_set_value(smi->reset, 1);
+       return 0;
diff --git a/queue-4.19/netfilter-ebtables-account-ebt_table_info-to-kmemcg.patch b/queue-4.19/netfilter-ebtables-account-ebt_table_info-to-kmemcg.patch
new file mode 100644 (file)
index 0000000..0553f1b
--- /dev/null
@@ -0,0 +1,56 @@
+From e2c8d550a973bb34fc28bc8d0ec996f84562fb8a Mon Sep 17 00:00:00 2001
+From: Shakeel Butt <shakeelb@google.com>
+Date: Wed, 2 Jan 2019 19:14:31 -0800
+Subject: netfilter: ebtables: account ebt_table_info to kmemcg
+
+From: Shakeel Butt <shakeelb@google.com>
+
+commit e2c8d550a973bb34fc28bc8d0ec996f84562fb8a upstream.
+
+The [ip,ip6,arp]_tables use x_tables_info internally and the underlying
+memory is already accounted to kmemcg. Do the same for ebtables. The
+syzbot, by using setsockopt(EBT_SO_SET_ENTRIES), was able to OOM the
+whole system from a restricted memcg, a potential DoS.
+
+By accounting the ebt_table_info, the memory used for ebt_table_info can
+be contained within the memcg of the allocating process. However the
+lifetime of ebt_table_info is independent of the allocating process and
+is tied to the network namespace. So, the oom-killer will not be able to
+relieve the memory pressure due to ebt_table_info memory. The memory for
+ebt_table_info is allocated through vmalloc. Currently vmalloc does not
+handle the oom-killed allocating process correctly and one large
+allocation can bypass memcg limit enforcement. So, with this patch,
+at least the small allocations will be contained. For large allocations,
+we need to fix vmalloc.
+
+Reported-by: syzbot+7713f3aa67be76b1552c@syzkaller.appspotmail.com
+Signed-off-by: Shakeel Butt <shakeelb@google.com>
+Reviewed-by: Kirill Tkhai <ktkhai@virtuozzo.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/bridge/netfilter/ebtables.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -1137,14 +1137,16 @@ static int do_replace(struct net *net, c
+       tmp.name[sizeof(tmp.name) - 1] = 0;
+       countersize = COUNTER_OFFSET(tmp.nentries) * nr_cpu_ids;
+-      newinfo = vmalloc(sizeof(*newinfo) + countersize);
++      newinfo = __vmalloc(sizeof(*newinfo) + countersize, GFP_KERNEL_ACCOUNT,
++                          PAGE_KERNEL);
+       if (!newinfo)
+               return -ENOMEM;
+       if (countersize)
+               memset(newinfo->counters, 0, countersize);
+-      newinfo->entries = vmalloc(tmp.entries_size);
++      newinfo->entries = __vmalloc(tmp.entries_size, GFP_KERNEL_ACCOUNT,
++                                   PAGE_KERNEL);
+       if (!newinfo->entries) {
+               ret = -ENOMEM;
+               goto free_newinfo;
diff --git a/queue-4.19/of-properties-add-missing-of_node_put.patch b/queue-4.19/of-properties-add-missing-of_node_put.patch
new file mode 100644 (file)
index 0000000..565558a
--- /dev/null
@@ -0,0 +1,51 @@
+From 28b170e88bc0c7509e6724717c15cb4b5686026e Mon Sep 17 00:00:00 2001
+From: Julia Lawall <Julia.Lawall@lip6.fr>
+Date: Sun, 13 Jan 2019 10:44:50 +0100
+Subject: OF: properties: add missing of_node_put
+
+From: Julia Lawall <Julia.Lawall@lip6.fr>
+
+commit 28b170e88bc0c7509e6724717c15cb4b5686026e upstream.
+
+Add an of_node_put when the result of of_graph_get_remote_port_parent is
+not available.
+
+The semantic match that finds this problem is as follows
+(http://coccinelle.lip6.fr):
+
+// <smpl>
+@r exists@
+local idexpression e;
+expression x;
+@@
+e = of_graph_get_remote_port_parent(...);
+... when != x = e
+    when != true e == NULL
+    when != of_node_put(e)
+    when != of_fwnode_handle(e)
+(
+return e;
+|
+*return ...;
+)
+// </smpl>
+
+Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
+Cc: stable@vger.kernel.org
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/of/property.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/of/property.c
++++ b/drivers/of/property.c
+@@ -806,6 +806,7 @@ struct device_node *of_graph_get_remote_
+       if (!of_device_is_available(remote)) {
+               pr_debug("not available for remote node\n");
++              of_node_put(remote);
+               return NULL;
+       }
diff --git a/queue-4.19/omap2fb-fix-stack-memory-disclosure.patch b/queue-4.19/omap2fb-fix-stack-memory-disclosure.patch
new file mode 100644 (file)
index 0000000..7052b55
--- /dev/null
@@ -0,0 +1,41 @@
+From a01421e4484327fe44f8e126793ed5a48a221e24 Mon Sep 17 00:00:00 2001
+From: Vlad Tsyrklevich <vlad@tsyrklevich.net>
+Date: Fri, 11 Jan 2019 14:34:38 +0100
+Subject: omap2fb: Fix stack memory disclosure
+
+From: Vlad Tsyrklevich <vlad@tsyrklevich.net>
+
+commit a01421e4484327fe44f8e126793ed5a48a221e24 upstream.
+
+Using [1] for static analysis I found that the OMAPFB_QUERY_PLANE,
+OMAPFB_GET_COLOR_KEY, OMAPFB_GET_DISPLAY_INFO, and OMAPFB_GET_VRAM_INFO
+cases could all leak uninitialized stack memory--either due to
+uninitialized padding or 'reserved' fields.
+
+Fix them by clearing the shared union used to store copied out data.
+
+[1] https://github.com/vlad902/kernel-uninitialized-memory-checker
+
+Signed-off-by: Vlad Tsyrklevich <vlad@tsyrklevich.net>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Fixes: b39a982ddecf ("OMAP: DSS2: omapfb driver")
+Cc: security@kernel.org
+[b.zolnierkie: prefix patch subject with "omap2fb: "]
+Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c
++++ b/drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c
+@@ -609,6 +609,8 @@ int omapfb_ioctl(struct fb_info *fbi, un
+       int r = 0;
++      memset(&p, 0, sizeof(p));
++
+       switch (cmd) {
+       case OMAPFB_SYNC_GFX:
+               DBG("ioctl SYNC_GFX\n");
diff --git a/queue-4.19/pstore-ram-avoid-allocation-and-leak-of-platform-data.patch b/queue-4.19/pstore-ram-avoid-allocation-and-leak-of-platform-data.patch
new file mode 100644 (file)
index 0000000..772b0e7
--- /dev/null
@@ -0,0 +1,47 @@
+From 5631e8576a3caf606cdc375f97425a67983b420c Mon Sep 17 00:00:00 2001
+From: Kees Cook <keescook@chromium.org>
+Date: Sun, 20 Jan 2019 14:33:34 -0800
+Subject: pstore/ram: Avoid allocation and leak of platform data
+
+From: Kees Cook <keescook@chromium.org>
+
+commit 5631e8576a3caf606cdc375f97425a67983b420c upstream.
+
+Yue Hu noticed that when parsing device tree the allocated platform data
+was never freed. Since it's not used beyond the function scope, this
+switches to using a stack variable instead.
+
+Reported-by: Yue Hu <huyue2@yulong.com>
+Fixes: 35da60941e44 ("pstore/ram: add Device Tree bindings")
+Cc: stable@vger.kernel.org
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/pstore/ram.c |    9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+--- a/fs/pstore/ram.c
++++ b/fs/pstore/ram.c
+@@ -713,18 +713,15 @@ static int ramoops_probe(struct platform
+ {
+       struct device *dev = &pdev->dev;
+       struct ramoops_platform_data *pdata = dev->platform_data;
++      struct ramoops_platform_data pdata_local;
+       struct ramoops_context *cxt = &oops_cxt;
+       size_t dump_mem_sz;
+       phys_addr_t paddr;
+       int err = -EINVAL;
+       if (dev_of_node(dev) && !pdata) {
+-              pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+-              if (!pdata) {
+-                      pr_err("cannot allocate platform data buffer\n");
+-                      err = -ENOMEM;
+-                      goto fail_out;
+-              }
++              pdata = &pdata_local;
++              memset(pdata, 0, sizeof(*pdata));
+               err = ramoops_parse_dt(pdev, pdata);
+               if (err < 0)
diff --git a/queue-4.19/rdma-nldev-don-t-expose-unsafe-global-rkey-to-regular-user.patch b/queue-4.19/rdma-nldev-don-t-expose-unsafe-global-rkey-to-regular-user.patch
new file mode 100644 (file)
index 0000000..cf64648
--- /dev/null
@@ -0,0 +1,38 @@
+From a9666c1cae8dbcd1a9aacd08a778bf2a28eea300 Mon Sep 17 00:00:00 2001
+From: Leon Romanovsky <leonro@mellanox.com>
+Date: Mon, 24 Dec 2018 11:05:16 +0200
+Subject: RDMA/nldev: Don't expose unsafe global rkey to regular user
+
+From: Leon Romanovsky <leonro@mellanox.com>
+
+commit a9666c1cae8dbcd1a9aacd08a778bf2a28eea300 upstream.
+
+Unsafe global rkey is considered dangerous because it exposes memory
+registered for all memory in the system. Only users with a QP on the same
+PD can use the rkey, and generally those QPs will already know the
+value. However, out of caution, do not expose the value to unprivleged
+users on the local system. Require CAP_NET_ADMIN instead.
+
+Cc: <stable@vger.kernel.org> # 4.16
+Fixes: 29cf1351d450 ("RDMA/nldev: provide detailed PD information")
+Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/core/nldev.c |    4 ----
+ 1 file changed, 4 deletions(-)
+
+--- a/drivers/infiniband/core/nldev.c
++++ b/drivers/infiniband/core/nldev.c
+@@ -579,10 +579,6 @@ static int fill_res_pd_entry(struct sk_b
+       if (nla_put_u64_64bit(msg, RDMA_NLDEV_ATTR_RES_USECNT,
+                             atomic_read(&pd->usecnt), RDMA_NLDEV_ATTR_PAD))
+               goto err;
+-      if ((pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY) &&
+-          nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_UNSAFE_GLOBAL_RKEY,
+-                      pd->unsafe_global_rkey))
+-              goto err;
+       if (fill_res_name_pid(msg, res))
+               goto err;
diff --git a/queue-4.19/rdma-vmw_pvrdma-return-the-correct-opcode-when-creating-wr.patch b/queue-4.19/rdma-vmw_pvrdma-return-the-correct-opcode-when-creating-wr.patch
new file mode 100644 (file)
index 0000000..a6b889f
--- /dev/null
@@ -0,0 +1,97 @@
+From 6325e01b6cdf4636b721cf7259c1616e3cf28ce2 Mon Sep 17 00:00:00 2001
+From: Adit Ranadive <aditr@vmware.com>
+Date: Wed, 9 Jan 2019 23:08:49 +0000
+Subject: RDMA/vmw_pvrdma: Return the correct opcode when creating WR
+
+From: Adit Ranadive <aditr@vmware.com>
+
+commit 6325e01b6cdf4636b721cf7259c1616e3cf28ce2 upstream.
+
+Since the IB_WR_REG_MR opcode value changed, let's set the PVRDMA device
+opcodes explicitly.
+
+Reported-by: Ruishuang Wang <ruishuangw@vmware.com>
+Fixes: 9a59739bd01f ("IB/rxe: Revise the ib_wr_opcode enum")
+Cc: stable@vger.kernel.org
+Reviewed-by: Bryan Tan <bryantan@vmware.com>
+Reviewed-by: Ruishuang Wang <ruishuangw@vmware.com>
+Reviewed-by: Vishnu Dasa <vdasa@vmware.com>
+Signed-off-by: Adit Ranadive <aditr@vmware.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/vmw_pvrdma/pvrdma.h    |   35 ++++++++++++++++++++++++++-
+ drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c |    6 ++++
+ include/uapi/rdma/vmw_pvrdma-abi.h           |    1 
+ 3 files changed, 41 insertions(+), 1 deletion(-)
+
+--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h
++++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h
+@@ -427,7 +427,40 @@ static inline enum ib_qp_state pvrdma_qp
+ static inline enum pvrdma_wr_opcode ib_wr_opcode_to_pvrdma(enum ib_wr_opcode op)
+ {
+-      return (enum pvrdma_wr_opcode)op;
++      switch (op) {
++      case IB_WR_RDMA_WRITE:
++              return PVRDMA_WR_RDMA_WRITE;
++      case IB_WR_RDMA_WRITE_WITH_IMM:
++              return PVRDMA_WR_RDMA_WRITE_WITH_IMM;
++      case IB_WR_SEND:
++              return PVRDMA_WR_SEND;
++      case IB_WR_SEND_WITH_IMM:
++              return PVRDMA_WR_SEND_WITH_IMM;
++      case IB_WR_RDMA_READ:
++              return PVRDMA_WR_RDMA_READ;
++      case IB_WR_ATOMIC_CMP_AND_SWP:
++              return PVRDMA_WR_ATOMIC_CMP_AND_SWP;
++      case IB_WR_ATOMIC_FETCH_AND_ADD:
++              return PVRDMA_WR_ATOMIC_FETCH_AND_ADD;
++      case IB_WR_LSO:
++              return PVRDMA_WR_LSO;
++      case IB_WR_SEND_WITH_INV:
++              return PVRDMA_WR_SEND_WITH_INV;
++      case IB_WR_RDMA_READ_WITH_INV:
++              return PVRDMA_WR_RDMA_READ_WITH_INV;
++      case IB_WR_LOCAL_INV:
++              return PVRDMA_WR_LOCAL_INV;
++      case IB_WR_REG_MR:
++              return PVRDMA_WR_FAST_REG_MR;
++      case IB_WR_MASKED_ATOMIC_CMP_AND_SWP:
++              return PVRDMA_WR_MASKED_ATOMIC_CMP_AND_SWP;
++      case IB_WR_MASKED_ATOMIC_FETCH_AND_ADD:
++              return PVRDMA_WR_MASKED_ATOMIC_FETCH_AND_ADD;
++      case IB_WR_REG_SIG_MR:
++              return PVRDMA_WR_REG_SIG_MR;
++      default:
++              return PVRDMA_WR_ERROR;
++      }
+ }
+ static inline enum ib_wc_status pvrdma_wc_status_to_ib(
+--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c
++++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c
+@@ -721,6 +721,12 @@ int pvrdma_post_send(struct ib_qp *ibqp,
+                   wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM)
+                       wqe_hdr->ex.imm_data = wr->ex.imm_data;
++              if (unlikely(wqe_hdr->opcode == PVRDMA_WR_ERROR)) {
++                      *bad_wr = wr;
++                      ret = -EINVAL;
++                      goto out;
++              }
++
+               switch (qp->ibqp.qp_type) {
+               case IB_QPT_GSI:
+               case IB_QPT_UD:
+--- a/include/uapi/rdma/vmw_pvrdma-abi.h
++++ b/include/uapi/rdma/vmw_pvrdma-abi.h
+@@ -78,6 +78,7 @@ enum pvrdma_wr_opcode {
+       PVRDMA_WR_MASKED_ATOMIC_FETCH_AND_ADD,
+       PVRDMA_WR_BIND_MW,
+       PVRDMA_WR_REG_SIG_MR,
++      PVRDMA_WR_ERROR,
+ };
+ enum pvrdma_wc_status {
diff --git a/queue-4.19/sctp-allocate-sctp_sockaddr_entry-with-kzalloc.patch b/queue-4.19/sctp-allocate-sctp_sockaddr_entry-with-kzalloc.patch
new file mode 100644 (file)
index 0000000..ddcbd29
--- /dev/null
@@ -0,0 +1,74 @@
+From 400b8b9a2a17918f8ce00786f596f530e7f30d50 Mon Sep 17 00:00:00 2001
+From: Xin Long <lucien.xin@gmail.com>
+Date: Mon, 14 Jan 2019 18:34:02 +0800
+Subject: sctp: allocate sctp_sockaddr_entry with kzalloc
+
+From: Xin Long <lucien.xin@gmail.com>
+
+commit 400b8b9a2a17918f8ce00786f596f530e7f30d50 upstream.
+
+The similar issue as fixed in Commit 4a2eb0c37b47 ("sctp: initialize
+sin6_flowinfo for ipv6 addrs in sctp_inet6addr_event") also exists
+in sctp_inetaddr_event, as Alexander noticed.
+
+To fix it, allocate sctp_sockaddr_entry with kzalloc for both sctp
+ipv4 and ipv6 addresses, as does in sctp_v4/6_copy_addrlist().
+
+Reported-by: Alexander Potapenko <glider@google.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Reported-by: syzbot+ae0c70c0c2d40c51bb92@syzkaller.appspotmail.com
+Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Acked-by: Neil Horman <nhorman@tuxdriver.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/sctp/ipv6.c     |    5 +----
+ net/sctp/protocol.c |    4 +---
+ 2 files changed, 2 insertions(+), 7 deletions(-)
+
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -97,11 +97,9 @@ static int sctp_inet6addr_event(struct n
+       switch (ev) {
+       case NETDEV_UP:
+-              addr = kmalloc(sizeof(struct sctp_sockaddr_entry), GFP_ATOMIC);
++              addr = kzalloc(sizeof(*addr), GFP_ATOMIC);
+               if (addr) {
+                       addr->a.v6.sin6_family = AF_INET6;
+-                      addr->a.v6.sin6_port = 0;
+-                      addr->a.v6.sin6_flowinfo = 0;
+                       addr->a.v6.sin6_addr = ifa->addr;
+                       addr->a.v6.sin6_scope_id = ifa->idev->dev->ifindex;
+                       addr->valid = 1;
+@@ -431,7 +429,6 @@ static void sctp_v6_copy_addrlist(struct
+               addr = kzalloc(sizeof(*addr), GFP_ATOMIC);
+               if (addr) {
+                       addr->a.v6.sin6_family = AF_INET6;
+-                      addr->a.v6.sin6_port = 0;
+                       addr->a.v6.sin6_addr = ifp->addr;
+                       addr->a.v6.sin6_scope_id = dev->ifindex;
+                       addr->valid = 1;
+--- a/net/sctp/protocol.c
++++ b/net/sctp/protocol.c
+@@ -101,7 +101,6 @@ static void sctp_v4_copy_addrlist(struct
+               addr = kzalloc(sizeof(*addr), GFP_ATOMIC);
+               if (addr) {
+                       addr->a.v4.sin_family = AF_INET;
+-                      addr->a.v4.sin_port = 0;
+                       addr->a.v4.sin_addr.s_addr = ifa->ifa_local;
+                       addr->valid = 1;
+                       INIT_LIST_HEAD(&addr->list);
+@@ -776,10 +775,9 @@ static int sctp_inetaddr_event(struct no
+       switch (ev) {
+       case NETDEV_UP:
+-              addr = kmalloc(sizeof(struct sctp_sockaddr_entry), GFP_ATOMIC);
++              addr = kzalloc(sizeof(*addr), GFP_ATOMIC);
+               if (addr) {
+                       addr->a.v4.sin_family = AF_INET;
+-                      addr->a.v4.sin_port = 0;
+                       addr->a.v4.sin_addr.s_addr = ifa->ifa_local;
+                       addr->valid = 1;
+                       spin_lock_bh(&net->sctp.local_addr_lock);
diff --git a/queue-4.19/selinux-fix-gpf-on-invalid-policy.patch b/queue-4.19/selinux-fix-gpf-on-invalid-policy.patch
new file mode 100644 (file)
index 0000000..21b3afa
--- /dev/null
@@ -0,0 +1,34 @@
+From 5b0e7310a2a33c06edc7eb81ffc521af9b2c5610 Mon Sep 17 00:00:00 2001
+From: Stephen Smalley <sds@tycho.nsa.gov>
+Date: Wed, 9 Jan 2019 10:55:10 -0500
+Subject: selinux: fix GPF on invalid policy
+
+From: Stephen Smalley <sds@tycho.nsa.gov>
+
+commit 5b0e7310a2a33c06edc7eb81ffc521af9b2c5610 upstream.
+
+levdatum->level can be NULL if we encounter an error while loading
+the policy during sens_read prior to initializing it.  Make sure
+sens_destroy handles that case correctly.
+
+Reported-by: syzbot+6664500f0f18f07a5c0e@syzkaller.appspotmail.com
+Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/selinux/ss/policydb.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/security/selinux/ss/policydb.c
++++ b/security/selinux/ss/policydb.c
+@@ -732,7 +732,8 @@ static int sens_destroy(void *key, void
+       kfree(key);
+       if (datum) {
+               levdatum = datum;
+-              ebitmap_destroy(&levdatum->level->cat);
++              if (levdatum->level)
++                      ebitmap_destroy(&levdatum->level->cat);
+               kfree(levdatum->level);
+       }
+       kfree(datum);
index 6113511df491e8b3f697a410db56320a467a4ff3..37edc2dbbc4fb1d02d02491d4233440bff437b99 100644 (file)
@@ -42,3 +42,56 @@ btrfs-wait-on-ordered-extents-on-abort-cleanup.patch
 yama-check-for-pid-death-before-checking-ancestry.patch
 scsi-core-synchronize-request-queue-pm-status-only-on-successful-resume.patch
 scsi-sd-fix-cache_type_store.patch
+mips-fix-n32-compat_ipc_parse_version.patch
+mips-bcm47xx-setup-struct-device-for-the-soc.patch
+mips-lantiq-fix-ipi-interrupt-handling.patch
+drm-i915-gvt-fix-mmap-range-check.patch
+of-properties-add-missing-of_node_put.patch
+mfd-tps6586x-handle-interrupts-on-suspend.patch
+media-v4l-ioctl-validate-num_planes-for-debug-messages.patch
+rdma-nldev-don-t-expose-unsafe-global-rkey-to-regular-user.patch
+rdma-vmw_pvrdma-return-the-correct-opcode-when-creating-wr.patch
+kbuild-disable-ld_dead_code_data_elimination-with-ftrace-gcc-4.7.patch
+net-dsa-realtek-smi-fix-of-child-node-lookup.patch
+pstore-ram-avoid-allocation-and-leak-of-platform-data.patch
+arm64-kaslr-ensure-randomized-quantities-are-clean-to-the-poc.patch
+arm64-dts-marvell-armada-ap806-reserve-psci-area.patch
+disable-msi-also-when-pcie-octeon.pcie_disable-on.patch
+fix-int_sqrt64-for-very-large-numbers.patch
+omap2fb-fix-stack-memory-disclosure.patch
+media-vivid-fix-error-handling-of-kthread_run.patch
+media-vivid-set-min-width-height-to-a-value-0.patch
+bpf-in-__bpf_redirect_no_mac-pull-mac-only-if-present.patch
+ipv6-make-icmp6_send-robust-against-null-skb-dev.patch
+lsm-check-for-null-cred-security-on-free.patch
+media-vb2-vb2_mmap-move-lock-up.patch
+sunrpc-handle-enomem-in-rpcb_getport_async.patch
+netfilter-ebtables-account-ebt_table_info-to-kmemcg.patch
+block-use-rcu_work-instead-of-call_rcu-to-avoid-sleep-in-softirq.patch
+selinux-fix-gpf-on-invalid-policy.patch
+blockdev-fix-livelocks-on-loop-device.patch
+sctp-allocate-sctp_sockaddr_entry-with-kzalloc.patch
+tipc-fix-uninit-value-in-in-tipc_conn_rcv_sub.patch
+tipc-fix-uninit-value-in-tipc_nl_compat_link_reset_stats.patch
+tipc-fix-uninit-value-in-tipc_nl_compat_bearer_enable.patch
+tipc-fix-uninit-value-in-tipc_nl_compat_link_set.patch
+tipc-fix-uninit-value-in-tipc_nl_compat_name_table_dump.patch
+tipc-fix-uninit-value-in-tipc_nl_compat_doit.patch
+block-loop-don-t-grab-struct-file-for-vfs_getattr-operation.patch
+block-loop-use-global-lock-for-ioctl-operation.patch
+loop-fold-__loop_release-into-loop_release.patch
+loop-get-rid-of-loop_index_mutex.patch
+loop-push-lo_ctl_mutex-down-into-individual-ioctls.patch
+loop-split-setting-of-lo_state-from-loop_clr_fd.patch
+loop-push-loop_ctl_mutex-down-into-loop_clr_fd.patch
+loop-push-loop_ctl_mutex-down-to-loop_get_status.patch
+loop-push-loop_ctl_mutex-down-to-loop_set_status.patch
+loop-push-loop_ctl_mutex-down-to-loop_set_fd.patch
+loop-push-loop_ctl_mutex-down-to-loop_change_fd.patch
+loop-move-special-partition-reread-handling-in-loop_clr_fd.patch
+loop-move-loop_reread_partitions-out-of-loop_ctl_mutex.patch
+loop-fix-deadlock-when-calling-blkdev_reread_part.patch
+loop-avoid-circular-locking-dependency-between-loop_ctl_mutex-and-bd_mutex.patch
+loop-get-rid-of-nested-acquisition-of-loop_ctl_mutex.patch
+loop-fix-double-mutex_unlock-loop_ctl_mutex-in-loop_control_ioctl.patch
+loop-drop-caches-if-offset-or-block_size-are-changed.patch
diff --git a/queue-4.19/sunrpc-handle-enomem-in-rpcb_getport_async.patch b/queue-4.19/sunrpc-handle-enomem-in-rpcb_getport_async.patch
new file mode 100644 (file)
index 0000000..b752f07
--- /dev/null
@@ -0,0 +1,44 @@
+From 81c88b18de1f11f70c97f28ced8d642c00bb3955 Mon Sep 17 00:00:00 2001
+From: "J. Bruce Fields" <bfields@redhat.com>
+Date: Thu, 20 Dec 2018 10:35:11 -0500
+Subject: sunrpc: handle ENOMEM in rpcb_getport_async
+
+From: J. Bruce Fields <bfields@redhat.com>
+
+commit 81c88b18de1f11f70c97f28ced8d642c00bb3955 upstream.
+
+If we ignore the error we'll hit a null dereference a little later.
+
+Reported-by: syzbot+4b98281f2401ab849f4b@syzkaller.appspotmail.com
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/sunrpc/rpcb_clnt.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/net/sunrpc/rpcb_clnt.c
++++ b/net/sunrpc/rpcb_clnt.c
+@@ -771,6 +771,12 @@ void rpcb_getport_async(struct rpc_task
+       case RPCBVERS_3:
+               map->r_netid = xprt->address_strings[RPC_DISPLAY_NETID];
+               map->r_addr = rpc_sockaddr2uaddr(sap, GFP_ATOMIC);
++              if (!map->r_addr) {
++                      status = -ENOMEM;
++                      dprintk("RPC: %5u %s: no memory available\n",
++                              task->tk_pid, __func__);
++                      goto bailout_free_args;
++              }
+               map->r_owner = "";
+               break;
+       case RPCBVERS_2:
+@@ -793,6 +799,8 @@ void rpcb_getport_async(struct rpc_task
+       rpc_put_task(child);
+       return;
++bailout_free_args:
++      kfree(map);
+ bailout_release_client:
+       rpc_release_client(rpcb_clnt);
+ bailout_nofree:
diff --git a/queue-4.19/tipc-fix-uninit-value-in-in-tipc_conn_rcv_sub.patch b/queue-4.19/tipc-fix-uninit-value-in-in-tipc_conn_rcv_sub.patch
new file mode 100644 (file)
index 0000000..902d39a
--- /dev/null
@@ -0,0 +1,60 @@
+From a88289f4ddee4165d5f796bd99e09eec3133c16b Mon Sep 17 00:00:00 2001
+From: Ying Xue <ying.xue@windriver.com>
+Date: Mon, 14 Jan 2019 17:22:24 +0800
+Subject: tipc: fix uninit-value in in tipc_conn_rcv_sub
+
+From: Ying Xue <ying.xue@windriver.com>
+
+commit a88289f4ddee4165d5f796bd99e09eec3133c16b upstream.
+
+syzbot reported:
+
+BUG: KMSAN: uninit-value in tipc_conn_rcv_sub+0x184/0x950 net/tipc/topsrv.c:373
+CPU: 0 PID: 66 Comm: kworker/u4:4 Not tainted 4.17.0-rc3+ #88
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Workqueue: tipc_rcv tipc_conn_recv_work
+Call Trace:
+ __dump_stack lib/dump_stack.c:77 [inline]
+ dump_stack+0x185/0x1d0 lib/dump_stack.c:113
+ kmsan_report+0x142/0x240 mm/kmsan/kmsan.c:1067
+ __msan_warning_32+0x6c/0xb0 mm/kmsan/kmsan_instr.c:683
+ tipc_conn_rcv_sub+0x184/0x950 net/tipc/topsrv.c:373
+ tipc_conn_rcv_from_sock net/tipc/topsrv.c:409 [inline]
+ tipc_conn_recv_work+0x3cd/0x560 net/tipc/topsrv.c:424
+ process_one_work+0x12c6/0x1f60 kernel/workqueue.c:2145
+ worker_thread+0x113c/0x24f0 kernel/workqueue.c:2279
+ kthread+0x539/0x720 kernel/kthread.c:239
+ ret_from_fork+0x35/0x40 arch/x86/entry/entry_64.S:412
+
+Local variable description: ----s.i@tipc_conn_recv_work
+Variable was created at:
+ tipc_conn_recv_work+0x65/0x560 net/tipc/topsrv.c:419
+ process_one_work+0x12c6/0x1f60 kernel/workqueue.c:2145
+
+In tipc_conn_rcv_from_sock(), it always supposes the length of message
+received from sock_recvmsg() is not smaller than the size of struct
+tipc_subscr. However, this assumption is false. Especially when the
+length of received message is shorter than struct tipc_subscr size,
+we will end up touching uninitialized fields in tipc_conn_rcv_sub().
+
+Reported-by: syzbot+8951a3065ee7fd6d6e23@syzkaller.appspotmail.com
+Reported-by: syzbot+75e6e042c5bbf691fc82@syzkaller.appspotmail.com
+Signed-off-by: Ying Xue <ying.xue@windriver.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/tipc/topsrv.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/tipc/topsrv.c
++++ b/net/tipc/topsrv.c
+@@ -404,7 +404,7 @@ static int tipc_conn_rcv_from_sock(struc
+       ret = sock_recvmsg(con->sock, &msg, MSG_DONTWAIT);
+       if (ret == -EWOULDBLOCK)
+               return -EWOULDBLOCK;
+-      if (ret > 0) {
++      if (ret == sizeof(s)) {
+               read_lock_bh(&sk->sk_callback_lock);
+               ret = tipc_conn_rcv_sub(srv, con, &s);
+               read_unlock_bh(&sk->sk_callback_lock);
diff --git a/queue-4.19/tipc-fix-uninit-value-in-tipc_nl_compat_bearer_enable.patch b/queue-4.19/tipc-fix-uninit-value-in-tipc_nl_compat_bearer_enable.patch
new file mode 100644 (file)
index 0000000..ba1353a
--- /dev/null
@@ -0,0 +1,189 @@
+From 0762216c0ad2a2fccd63890648eca491f2c83d9a Mon Sep 17 00:00:00 2001
+From: Ying Xue <ying.xue@windriver.com>
+Date: Mon, 14 Jan 2019 17:22:26 +0800
+Subject: tipc: fix uninit-value in tipc_nl_compat_bearer_enable
+
+From: Ying Xue <ying.xue@windriver.com>
+
+commit 0762216c0ad2a2fccd63890648eca491f2c83d9a upstream.
+
+syzbot reported:
+
+BUG: KMSAN: uninit-value in strlen+0x3b/0xa0 lib/string.c:484
+CPU: 1 PID: 6371 Comm: syz-executor652 Not tainted 4.19.0-rc8+ #70
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Call Trace:
+ __dump_stack lib/dump_stack.c:77 [inline]
+ dump_stack+0x306/0x460 lib/dump_stack.c:113
+ kmsan_report+0x1a2/0x2e0 mm/kmsan/kmsan.c:917
+ __msan_warning+0x7c/0xe0 mm/kmsan/kmsan_instr.c:500
+ strlen+0x3b/0xa0 lib/string.c:484
+ nla_put_string include/net/netlink.h:1011 [inline]
+ tipc_nl_compat_bearer_enable+0x238/0x7b0 net/tipc/netlink_compat.c:389
+ __tipc_nl_compat_doit net/tipc/netlink_compat.c:311 [inline]
+ tipc_nl_compat_doit+0x39f/0xae0 net/tipc/netlink_compat.c:344
+ tipc_nl_compat_recv+0x147c/0x2760 net/tipc/netlink_compat.c:1107
+ genl_family_rcv_msg net/netlink/genetlink.c:601 [inline]
+ genl_rcv_msg+0x185c/0x1a20 net/netlink/genetlink.c:626
+ netlink_rcv_skb+0x394/0x640 net/netlink/af_netlink.c:2454
+ genl_rcv+0x63/0x80 net/netlink/genetlink.c:637
+ netlink_unicast_kernel net/netlink/af_netlink.c:1317 [inline]
+ netlink_unicast+0x166d/0x1720 net/netlink/af_netlink.c:1343
+ netlink_sendmsg+0x1391/0x1420 net/netlink/af_netlink.c:1908
+ sock_sendmsg_nosec net/socket.c:621 [inline]
+ sock_sendmsg net/socket.c:631 [inline]
+ ___sys_sendmsg+0xe47/0x1200 net/socket.c:2116
+ __sys_sendmsg net/socket.c:2154 [inline]
+ __do_sys_sendmsg net/socket.c:2163 [inline]
+ __se_sys_sendmsg+0x307/0x460 net/socket.c:2161
+ __x64_sys_sendmsg+0x4a/0x70 net/socket.c:2161
+ do_syscall_64+0xbe/0x100 arch/x86/entry/common.c:291
+ entry_SYSCALL_64_after_hwframe+0x63/0xe7
+RIP: 0033:0x440179
+Code: 18 89 d0 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 fb 13 fc ff c3 66 2e 0f 1f 84 00 00 00 00
+RSP: 002b:00007fffef7beee8 EFLAGS: 00000213 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00000000004002c8 RCX: 0000000000440179
+RDX: 0000000000000000 RSI: 0000000020000100 RDI: 0000000000000003
+RBP: 00000000006ca018 R08: 0000000000000000 R09: 00000000004002c8
+R10: 0000000000000000 R11: 0000000000000213 R12: 0000000000401a00
+R13: 0000000000401a90 R14: 0000000000000000 R15: 0000000000000000
+
+Uninit was created at:
+ kmsan_save_stack_with_flags mm/kmsan/kmsan.c:255 [inline]
+ kmsan_internal_poison_shadow+0xc8/0x1d0 mm/kmsan/kmsan.c:180
+ kmsan_kmalloc+0xa4/0x120 mm/kmsan/kmsan_hooks.c:104
+ kmsan_slab_alloc+0x10/0x20 mm/kmsan/kmsan_hooks.c:113
+ slab_post_alloc_hook mm/slab.h:446 [inline]
+ slab_alloc_node mm/slub.c:2727 [inline]
+ __kmalloc_node_track_caller+0xb43/0x1400 mm/slub.c:4360
+ __kmalloc_reserve net/core/skbuff.c:138 [inline]
+ __alloc_skb+0x422/0xe90 net/core/skbuff.c:206
+ alloc_skb include/linux/skbuff.h:996 [inline]
+ netlink_alloc_large_skb net/netlink/af_netlink.c:1189 [inline]
+ netlink_sendmsg+0xcaf/0x1420 net/netlink/af_netlink.c:1883
+ sock_sendmsg_nosec net/socket.c:621 [inline]
+ sock_sendmsg net/socket.c:631 [inline]
+ ___sys_sendmsg+0xe47/0x1200 net/socket.c:2116
+ __sys_sendmsg net/socket.c:2154 [inline]
+ __do_sys_sendmsg net/socket.c:2163 [inline]
+ __se_sys_sendmsg+0x307/0x460 net/socket.c:2161
+ __x64_sys_sendmsg+0x4a/0x70 net/socket.c:2161
+ do_syscall_64+0xbe/0x100 arch/x86/entry/common.c:291
+ entry_SYSCALL_64_after_hwframe+0x63/0xe7
+
+The root cause is that we don't validate whether bear name is a valid
+string in tipc_nl_compat_bearer_enable().
+
+Meanwhile, we also fix the same issue in the following functions:
+tipc_nl_compat_bearer_disable()
+tipc_nl_compat_link_stat_dump()
+tipc_nl_compat_media_set()
+tipc_nl_compat_bearer_set()
+
+Reported-by: syzbot+b33d5cae0efd35dbfe77@syzkaller.appspotmail.com
+Signed-off-by: Ying Xue <ying.xue@windriver.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/tipc/netlink_compat.c |   26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+--- a/net/tipc/netlink_compat.c
++++ b/net/tipc/netlink_compat.c
+@@ -389,6 +389,7 @@ static int tipc_nl_compat_bearer_enable(
+       struct nlattr *prop;
+       struct nlattr *bearer;
+       struct tipc_bearer_config *b;
++      int len;
+       b = (struct tipc_bearer_config *)TLV_DATA(msg->req);
+@@ -396,6 +397,10 @@ static int tipc_nl_compat_bearer_enable(
+       if (!bearer)
+               return -EMSGSIZE;
++      len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_BEARER_NAME);
++      if (!string_is_valid(b->name, len))
++              return -EINVAL;
++
+       if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, b->name))
+               return -EMSGSIZE;
+@@ -421,6 +426,7 @@ static int tipc_nl_compat_bearer_disable
+ {
+       char *name;
+       struct nlattr *bearer;
++      int len;
+       name = (char *)TLV_DATA(msg->req);
+@@ -428,6 +434,10 @@ static int tipc_nl_compat_bearer_disable
+       if (!bearer)
+               return -EMSGSIZE;
++      len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_BEARER_NAME);
++      if (!string_is_valid(name, len))
++              return -EINVAL;
++
+       if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, name))
+               return -EMSGSIZE;
+@@ -488,6 +498,7 @@ static int tipc_nl_compat_link_stat_dump
+       struct nlattr *prop[TIPC_NLA_PROP_MAX + 1];
+       struct nlattr *stats[TIPC_NLA_STATS_MAX + 1];
+       int err;
++      int len;
+       if (!attrs[TIPC_NLA_LINK])
+               return -EINVAL;
+@@ -514,6 +525,11 @@ static int tipc_nl_compat_link_stat_dump
+               return err;
+       name = (char *)TLV_DATA(msg->req);
++
++      len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_LINK_NAME);
++      if (!string_is_valid(name, len))
++              return -EINVAL;
++
+       if (strcmp(name, nla_data(link[TIPC_NLA_LINK_NAME])) != 0)
+               return 0;
+@@ -654,6 +670,7 @@ static int tipc_nl_compat_media_set(stru
+       struct nlattr *prop;
+       struct nlattr *media;
+       struct tipc_link_config *lc;
++      int len;
+       lc = (struct tipc_link_config *)TLV_DATA(msg->req);
+@@ -661,6 +678,10 @@ static int tipc_nl_compat_media_set(stru
+       if (!media)
+               return -EMSGSIZE;
++      len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_MEDIA_NAME);
++      if (!string_is_valid(lc->name, len))
++              return -EINVAL;
++
+       if (nla_put_string(skb, TIPC_NLA_MEDIA_NAME, lc->name))
+               return -EMSGSIZE;
+@@ -681,6 +702,7 @@ static int tipc_nl_compat_bearer_set(str
+       struct nlattr *prop;
+       struct nlattr *bearer;
+       struct tipc_link_config *lc;
++      int len;
+       lc = (struct tipc_link_config *)TLV_DATA(msg->req);
+@@ -688,6 +710,10 @@ static int tipc_nl_compat_bearer_set(str
+       if (!bearer)
+               return -EMSGSIZE;
++      len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_MEDIA_NAME);
++      if (!string_is_valid(lc->name, len))
++              return -EINVAL;
++
+       if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, lc->name))
+               return -EMSGSIZE;
diff --git a/queue-4.19/tipc-fix-uninit-value-in-tipc_nl_compat_doit.patch b/queue-4.19/tipc-fix-uninit-value-in-tipc_nl_compat_doit.patch
new file mode 100644 (file)
index 0000000..2a4fc37
--- /dev/null
@@ -0,0 +1,94 @@
+From 2753ca5d9009c180dbfd4c802c80983b4b6108d1 Mon Sep 17 00:00:00 2001
+From: Ying Xue <ying.xue@windriver.com>
+Date: Mon, 14 Jan 2019 17:22:29 +0800
+Subject: tipc: fix uninit-value in tipc_nl_compat_doit
+
+From: Ying Xue <ying.xue@windriver.com>
+
+commit 2753ca5d9009c180dbfd4c802c80983b4b6108d1 upstream.
+
+BUG: KMSAN: uninit-value in tipc_nl_compat_doit+0x404/0xa10 net/tipc/netlink_compat.c:335
+CPU: 0 PID: 4514 Comm: syz-executor485 Not tainted 4.16.0+ #87
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Call Trace:
+ __dump_stack lib/dump_stack.c:17 [inline]
+ dump_stack+0x185/0x1d0 lib/dump_stack.c:53
+ kmsan_report+0x142/0x240 mm/kmsan/kmsan.c:1067
+ __msan_warning_32+0x6c/0xb0 mm/kmsan/kmsan_instr.c:683
+ tipc_nl_compat_doit+0x404/0xa10 net/tipc/netlink_compat.c:335
+ tipc_nl_compat_recv+0x164b/0x2700 net/tipc/netlink_compat.c:1153
+ genl_family_rcv_msg net/netlink/genetlink.c:599 [inline]
+ genl_rcv_msg+0x1686/0x1810 net/netlink/genetlink.c:624
+ netlink_rcv_skb+0x378/0x600 net/netlink/af_netlink.c:2447
+ genl_rcv+0x63/0x80 net/netlink/genetlink.c:635
+ netlink_unicast_kernel net/netlink/af_netlink.c:1311 [inline]
+ netlink_unicast+0x166b/0x1740 net/netlink/af_netlink.c:1337
+ netlink_sendmsg+0x1048/0x1310 net/netlink/af_netlink.c:1900
+ sock_sendmsg_nosec net/socket.c:630 [inline]
+ sock_sendmsg net/socket.c:640 [inline]
+ ___sys_sendmsg+0xec0/0x1310 net/socket.c:2046
+ __sys_sendmsg net/socket.c:2080 [inline]
+ SYSC_sendmsg+0x2a3/0x3d0 net/socket.c:2091
+ SyS_sendmsg+0x54/0x80 net/socket.c:2087
+ do_syscall_64+0x309/0x430 arch/x86/entry/common.c:287
+ entry_SYSCALL_64_after_hwframe+0x3d/0xa2
+RIP: 0033:0x43fda9
+RSP: 002b:00007ffd0c184ba8 EFLAGS: 00000213 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00000000004002c8 RCX: 000000000043fda9
+RDX: 0000000000000000 RSI: 0000000020023000 RDI: 0000000000000003
+RBP: 00000000006ca018 R08: 00000000004002c8 R09: 00000000004002c8
+R10: 00000000004002c8 R11: 0000000000000213 R12: 00000000004016d0
+R13: 0000000000401760 R14: 0000000000000000 R15: 0000000000000000
+
+Uninit was created at:
+ kmsan_save_stack_with_flags mm/kmsan/kmsan.c:278 [inline]
+ kmsan_internal_poison_shadow+0xb8/0x1b0 mm/kmsan/kmsan.c:188
+ kmsan_kmalloc+0x94/0x100 mm/kmsan/kmsan.c:314
+ kmsan_slab_alloc+0x11/0x20 mm/kmsan/kmsan.c:321
+ slab_post_alloc_hook mm/slab.h:445 [inline]
+ slab_alloc_node mm/slub.c:2737 [inline]
+ __kmalloc_node_track_caller+0xaed/0x11c0 mm/slub.c:4369
+ __kmalloc_reserve net/core/skbuff.c:138 [inline]
+ __alloc_skb+0x2cf/0x9f0 net/core/skbuff.c:206
+ alloc_skb include/linux/skbuff.h:984 [inline]
+ netlink_alloc_large_skb net/netlink/af_netlink.c:1183 [inline]
+ netlink_sendmsg+0x9a6/0x1310 net/netlink/af_netlink.c:1875
+ sock_sendmsg_nosec net/socket.c:630 [inline]
+ sock_sendmsg net/socket.c:640 [inline]
+ ___sys_sendmsg+0xec0/0x1310 net/socket.c:2046
+ __sys_sendmsg net/socket.c:2080 [inline]
+ SYSC_sendmsg+0x2a3/0x3d0 net/socket.c:2091
+ SyS_sendmsg+0x54/0x80 net/socket.c:2087
+ do_syscall_64+0x309/0x430 arch/x86/entry/common.c:287
+ entry_SYSCALL_64_after_hwframe+0x3d/0xa2
+
+In tipc_nl_compat_recv(), when the len variable returned by
+nlmsg_attrlen() is 0, the message is still treated as a valid one,
+which is obviously unresonable. When len is zero, it means the
+message not only doesn't contain any valid TLV payload, but also
+TLV header is not included. Under this stituation, tlv_type field
+in TLV header is still accessed in tipc_nl_compat_dumpit() or
+tipc_nl_compat_doit(), but the field space is obviously illegal.
+Of course, it is not initialized.
+
+Reported-by: syzbot+bca0dc46634781f08b38@syzkaller.appspotmail.com
+Reported-by: syzbot+6bdb590321a7ae40c1a6@syzkaller.appspotmail.com
+Signed-off-by: Ying Xue <ying.xue@windriver.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/tipc/netlink_compat.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/tipc/netlink_compat.c
++++ b/net/tipc/netlink_compat.c
+@@ -1249,7 +1249,7 @@ static int tipc_nl_compat_recv(struct sk
+       }
+       len = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN);
+-      if (len && !TLV_OK(msg.req, len)) {
++      if (!len || !TLV_OK(msg.req, len)) {
+               msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED);
+               err = -EOPNOTSUPP;
+               goto send;
diff --git a/queue-4.19/tipc-fix-uninit-value-in-tipc_nl_compat_link_reset_stats.patch b/queue-4.19/tipc-fix-uninit-value-in-tipc_nl_compat_link_reset_stats.patch
new file mode 100644 (file)
index 0000000..fd14498
--- /dev/null
@@ -0,0 +1,133 @@
+From 8b66fee7f8ee18f9c51260e7a43ab37db5177a05 Mon Sep 17 00:00:00 2001
+From: Ying Xue <ying.xue@windriver.com>
+Date: Mon, 14 Jan 2019 17:22:25 +0800
+Subject: tipc: fix uninit-value in tipc_nl_compat_link_reset_stats
+
+From: Ying Xue <ying.xue@windriver.com>
+
+commit 8b66fee7f8ee18f9c51260e7a43ab37db5177a05 upstream.
+
+syzbot reports following splat:
+
+BUG: KMSAN: uninit-value in strlen+0x3b/0xa0 lib/string.c:486
+CPU: 1 PID: 11057 Comm: syz-executor0 Not tainted 4.20.0-rc7+ #2
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Call Trace:
+ __dump_stack lib/dump_stack.c:77 [inline]
+ dump_stack+0x173/0x1d0 lib/dump_stack.c:113
+ kmsan_report+0x12e/0x2a0 mm/kmsan/kmsan.c:613
+ __msan_warning+0x82/0xf0 mm/kmsan/kmsan_instr.c:295
+ strlen+0x3b/0xa0 lib/string.c:486
+ nla_put_string include/net/netlink.h:1154 [inline]
+ tipc_nl_compat_link_reset_stats+0x1f0/0x360 net/tipc/netlink_compat.c:760
+ __tipc_nl_compat_doit net/tipc/netlink_compat.c:311 [inline]
+ tipc_nl_compat_doit+0x3aa/0xaf0 net/tipc/netlink_compat.c:344
+ tipc_nl_compat_handle net/tipc/netlink_compat.c:1107 [inline]
+ tipc_nl_compat_recv+0x14d7/0x2760 net/tipc/netlink_compat.c:1210
+ genl_family_rcv_msg net/netlink/genetlink.c:601 [inline]
+ genl_rcv_msg+0x185f/0x1a60 net/netlink/genetlink.c:626
+ netlink_rcv_skb+0x444/0x640 net/netlink/af_netlink.c:2477
+ genl_rcv+0x63/0x80 net/netlink/genetlink.c:637
+ netlink_unicast_kernel net/netlink/af_netlink.c:1310 [inline]
+ netlink_unicast+0xf40/0x1020 net/netlink/af_netlink.c:1336
+ netlink_sendmsg+0x127f/0x1300 net/netlink/af_netlink.c:1917
+ sock_sendmsg_nosec net/socket.c:621 [inline]
+ sock_sendmsg net/socket.c:631 [inline]
+ ___sys_sendmsg+0xdb9/0x11b0 net/socket.c:2116
+ __sys_sendmsg net/socket.c:2154 [inline]
+ __do_sys_sendmsg net/socket.c:2163 [inline]
+ __se_sys_sendmsg+0x305/0x460 net/socket.c:2161
+ __x64_sys_sendmsg+0x4a/0x70 net/socket.c:2161
+ do_syscall_64+0xbc/0xf0 arch/x86/entry/common.c:291
+ entry_SYSCALL_64_after_hwframe+0x63/0xe7
+RIP: 0033:0x457ec9
+Code: 6d b7 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 3b b7 fb ff c3 66 2e 0f 1f 84 00 00 00 00
+RSP: 002b:00007f2557338c78 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000457ec9
+RDX: 0000000000000000 RSI: 00000000200001c0 RDI: 0000000000000003
+RBP: 000000000073bf00 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 00007f25573396d4
+R13: 00000000004cb478 R14: 00000000004d86c8 R15: 00000000ffffffff
+
+Uninit was created at:
+ kmsan_save_stack_with_flags mm/kmsan/kmsan.c:204 [inline]
+ kmsan_internal_poison_shadow+0x92/0x150 mm/kmsan/kmsan.c:158
+ kmsan_kmalloc+0xa6/0x130 mm/kmsan/kmsan_hooks.c:176
+ kmsan_slab_alloc+0xe/0x10 mm/kmsan/kmsan_hooks.c:185
+ slab_post_alloc_hook mm/slab.h:446 [inline]
+ slab_alloc_node mm/slub.c:2759 [inline]
+ __kmalloc_node_track_caller+0xe18/0x1030 mm/slub.c:4383
+ __kmalloc_reserve net/core/skbuff.c:137 [inline]
+ __alloc_skb+0x309/0xa20 net/core/skbuff.c:205
+ alloc_skb include/linux/skbuff.h:998 [inline]
+ netlink_alloc_large_skb net/netlink/af_netlink.c:1182 [inline]
+ netlink_sendmsg+0xb82/0x1300 net/netlink/af_netlink.c:1892
+ sock_sendmsg_nosec net/socket.c:621 [inline]
+ sock_sendmsg net/socket.c:631 [inline]
+ ___sys_sendmsg+0xdb9/0x11b0 net/socket.c:2116
+ __sys_sendmsg net/socket.c:2154 [inline]
+ __do_sys_sendmsg net/socket.c:2163 [inline]
+ __se_sys_sendmsg+0x305/0x460 net/socket.c:2161
+ __x64_sys_sendmsg+0x4a/0x70 net/socket.c:2161
+ do_syscall_64+0xbc/0xf0 arch/x86/entry/common.c:291
+ entry_SYSCALL_64_after_hwframe+0x63/0xe7
+
+The uninitialised access happened in tipc_nl_compat_link_reset_stats:
+    nla_put_string(skb, TIPC_NLA_LINK_NAME, name)
+
+This is because name string is not validated before it's used.
+
+Reported-by: syzbot+e01d94b5a4c266be6e4c@syzkaller.appspotmail.com
+Signed-off-by: Ying Xue <ying.xue@windriver.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/tipc/netlink_compat.c |   15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+--- a/net/tipc/netlink_compat.c
++++ b/net/tipc/netlink_compat.c
+@@ -87,6 +87,11 @@ static int tipc_skb_tailroom(struct sk_b
+       return limit;
+ }
++static inline int TLV_GET_DATA_LEN(struct tlv_desc *tlv)
++{
++      return TLV_GET_LEN(tlv) - TLV_SPACE(0);
++}
++
+ static int tipc_add_tlv(struct sk_buff *skb, u16 type, void *data, u16 len)
+ {
+       struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(skb);
+@@ -166,6 +171,11 @@ static struct sk_buff *tipc_get_err_tlv(
+       return buf;
+ }
++static inline bool string_is_valid(char *s, int len)
++{
++      return memchr(s, '\0', len) ? true : false;
++}
++
+ static int __tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd,
+                                  struct tipc_nl_compat_msg *msg,
+                                  struct sk_buff *arg)
+@@ -750,6 +760,7 @@ static int tipc_nl_compat_link_reset_sta
+ {
+       char *name;
+       struct nlattr *link;
++      int len;
+       name = (char *)TLV_DATA(msg->req);
+@@ -757,6 +768,10 @@ static int tipc_nl_compat_link_reset_sta
+       if (!link)
+               return -EMSGSIZE;
++      len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_LINK_NAME);
++      if (!string_is_valid(name, len))
++              return -EINVAL;
++
+       if (nla_put_string(skb, TIPC_NLA_LINK_NAME, name))
+               return -EMSGSIZE;
diff --git a/queue-4.19/tipc-fix-uninit-value-in-tipc_nl_compat_link_set.patch b/queue-4.19/tipc-fix-uninit-value-in-tipc_nl_compat_link_set.patch
new file mode 100644 (file)
index 0000000..d95ae11
--- /dev/null
@@ -0,0 +1,76 @@
+From edf5ff04a45750ac8ce2435974f001dc9cfbf055 Mon Sep 17 00:00:00 2001
+From: Ying Xue <ying.xue@windriver.com>
+Date: Mon, 14 Jan 2019 17:22:27 +0800
+Subject: tipc: fix uninit-value in tipc_nl_compat_link_set
+
+From: Ying Xue <ying.xue@windriver.com>
+
+commit edf5ff04a45750ac8ce2435974f001dc9cfbf055 upstream.
+
+syzbot reports following splat:
+
+BUG: KMSAN: uninit-value in strlen+0x3b/0xa0 lib/string.c:486
+CPU: 1 PID: 9306 Comm: syz-executor172 Not tainted 4.20.0-rc7+ #2
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
+Google 01/01/2011
+Call Trace:
+  __dump_stack lib/dump_stack.c:77 [inline]
+  dump_stack+0x173/0x1d0 lib/dump_stack.c:113
+  kmsan_report+0x12e/0x2a0 mm/kmsan/kmsan.c:613
+  __msan_warning+0x82/0xf0 mm/kmsan/kmsan_instr.c:313
+  strlen+0x3b/0xa0 lib/string.c:486
+  nla_put_string include/net/netlink.h:1154 [inline]
+  __tipc_nl_compat_link_set net/tipc/netlink_compat.c:708 [inline]
+  tipc_nl_compat_link_set+0x929/0x1220 net/tipc/netlink_compat.c:744
+  __tipc_nl_compat_doit net/tipc/netlink_compat.c:311 [inline]
+  tipc_nl_compat_doit+0x3aa/0xaf0 net/tipc/netlink_compat.c:344
+  tipc_nl_compat_handle net/tipc/netlink_compat.c:1107 [inline]
+  tipc_nl_compat_recv+0x14d7/0x2760 net/tipc/netlink_compat.c:1210
+  genl_family_rcv_msg net/netlink/genetlink.c:601 [inline]
+  genl_rcv_msg+0x185f/0x1a60 net/netlink/genetlink.c:626
+  netlink_rcv_skb+0x444/0x640 net/netlink/af_netlink.c:2477
+  genl_rcv+0x63/0x80 net/netlink/genetlink.c:637
+  netlink_unicast_kernel net/netlink/af_netlink.c:1310 [inline]
+  netlink_unicast+0xf40/0x1020 net/netlink/af_netlink.c:1336
+  netlink_sendmsg+0x127f/0x1300 net/netlink/af_netlink.c:1917
+  sock_sendmsg_nosec net/socket.c:621 [inline]
+  sock_sendmsg net/socket.c:631 [inline]
+  ___sys_sendmsg+0xdb9/0x11b0 net/socket.c:2116
+  __sys_sendmsg net/socket.c:2154 [inline]
+  __do_sys_sendmsg net/socket.c:2163 [inline]
+  __se_sys_sendmsg+0x305/0x460 net/socket.c:2161
+  __x64_sys_sendmsg+0x4a/0x70 net/socket.c:2161
+  do_syscall_64+0xbc/0xf0 arch/x86/entry/common.c:291
+  entry_SYSCALL_64_after_hwframe+0x63/0xe7
+
+The uninitialised access happened in
+    nla_put_string(skb, TIPC_NLA_LINK_NAME, lc->name)
+
+This is because lc->name string is not validated before it's used.
+
+Reported-by: syzbot+d78b8a29241a195aefb8@syzkaller.appspotmail.com
+Signed-off-by: Ying Xue <ying.xue@windriver.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/tipc/netlink_compat.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/net/tipc/netlink_compat.c
++++ b/net/tipc/netlink_compat.c
+@@ -762,9 +762,14 @@ static int tipc_nl_compat_link_set(struc
+       struct tipc_link_config *lc;
+       struct tipc_bearer *bearer;
+       struct tipc_media *media;
++      int len;
+       lc = (struct tipc_link_config *)TLV_DATA(msg->req);
++      len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_LINK_NAME);
++      if (!string_is_valid(lc->name, len))
++              return -EINVAL;
++
+       media = tipc_media_find(lc->name);
+       if (media) {
+               cmd->doit = &__tipc_nl_media_set;
diff --git a/queue-4.19/tipc-fix-uninit-value-in-tipc_nl_compat_name_table_dump.patch b/queue-4.19/tipc-fix-uninit-value-in-tipc_nl_compat_name_table_dump.patch
new file mode 100644 (file)
index 0000000..b952cb5
--- /dev/null
@@ -0,0 +1,100 @@
+From 974cb0e3e7c963ced06c4e32c5b2884173fa5e01 Mon Sep 17 00:00:00 2001
+From: Ying Xue <ying.xue@windriver.com>
+Date: Mon, 14 Jan 2019 17:22:28 +0800
+Subject: tipc: fix uninit-value in tipc_nl_compat_name_table_dump
+
+From: Ying Xue <ying.xue@windriver.com>
+
+commit 974cb0e3e7c963ced06c4e32c5b2884173fa5e01 upstream.
+
+syzbot reported:
+
+BUG: KMSAN: uninit-value in __arch_swab32 arch/x86/include/uapi/asm/swab.h:10 [inline]
+BUG: KMSAN: uninit-value in __fswab32 include/uapi/linux/swab.h:59 [inline]
+BUG: KMSAN: uninit-value in tipc_nl_compat_name_table_dump+0x4a8/0xba0 net/tipc/netlink_compat.c:826
+CPU: 0 PID: 6290 Comm: syz-executor848 Not tainted 4.19.0-rc8+ #70
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Call Trace:
+ __dump_stack lib/dump_stack.c:77 [inline]
+ dump_stack+0x306/0x460 lib/dump_stack.c:113
+ kmsan_report+0x1a2/0x2e0 mm/kmsan/kmsan.c:917
+ __msan_warning+0x7c/0xe0 mm/kmsan/kmsan_instr.c:500
+ __arch_swab32 arch/x86/include/uapi/asm/swab.h:10 [inline]
+ __fswab32 include/uapi/linux/swab.h:59 [inline]
+ tipc_nl_compat_name_table_dump+0x4a8/0xba0 net/tipc/netlink_compat.c:826
+ __tipc_nl_compat_dumpit+0x59e/0xdb0 net/tipc/netlink_compat.c:205
+ tipc_nl_compat_dumpit+0x63a/0x820 net/tipc/netlink_compat.c:270
+ tipc_nl_compat_handle net/tipc/netlink_compat.c:1151 [inline]
+ tipc_nl_compat_recv+0x1402/0x2760 net/tipc/netlink_compat.c:1210
+ genl_family_rcv_msg net/netlink/genetlink.c:601 [inline]
+ genl_rcv_msg+0x185c/0x1a20 net/netlink/genetlink.c:626
+ netlink_rcv_skb+0x394/0x640 net/netlink/af_netlink.c:2454
+ genl_rcv+0x63/0x80 net/netlink/genetlink.c:637
+ netlink_unicast_kernel net/netlink/af_netlink.c:1317 [inline]
+ netlink_unicast+0x166d/0x1720 net/netlink/af_netlink.c:1343
+ netlink_sendmsg+0x1391/0x1420 net/netlink/af_netlink.c:1908
+ sock_sendmsg_nosec net/socket.c:621 [inline]
+ sock_sendmsg net/socket.c:631 [inline]
+ ___sys_sendmsg+0xe47/0x1200 net/socket.c:2116
+ __sys_sendmsg net/socket.c:2154 [inline]
+ __do_sys_sendmsg net/socket.c:2163 [inline]
+ __se_sys_sendmsg+0x307/0x460 net/socket.c:2161
+ __x64_sys_sendmsg+0x4a/0x70 net/socket.c:2161
+ do_syscall_64+0xbe/0x100 arch/x86/entry/common.c:291
+ entry_SYSCALL_64_after_hwframe+0x63/0xe7
+RIP: 0033:0x440179
+Code: 18 89 d0 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 fb 13 fc ff c3 66 2e 0f 1f 84 00 00 00 00
+RSP: 002b:00007ffecec49318 EFLAGS: 00000213 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00000000004002c8 RCX: 0000000000440179
+RDX: 0000000000000000 RSI: 0000000020000100 RDI: 0000000000000003
+RBP: 00000000006ca018 R08: 0000000000000000 R09: 00000000004002c8
+R10: 0000000000000000 R11: 0000000000000213 R12: 0000000000401a00
+R13: 0000000000401a90 R14: 0000000000000000 R15: 0000000000000000
+
+Uninit was created at:
+ kmsan_save_stack_with_flags mm/kmsan/kmsan.c:255 [inline]
+ kmsan_internal_poison_shadow+0xc8/0x1d0 mm/kmsan/kmsan.c:180
+ kmsan_kmalloc+0xa4/0x120 mm/kmsan/kmsan_hooks.c:104
+ kmsan_slab_alloc+0x10/0x20 mm/kmsan/kmsan_hooks.c:113
+ slab_post_alloc_hook mm/slab.h:446 [inline]
+ slab_alloc_node mm/slub.c:2727 [inline]
+ __kmalloc_node_track_caller+0xb43/0x1400 mm/slub.c:4360
+ __kmalloc_reserve net/core/skbuff.c:138 [inline]
+ __alloc_skb+0x422/0xe90 net/core/skbuff.c:206
+ alloc_skb include/linux/skbuff.h:996 [inline]
+ netlink_alloc_large_skb net/netlink/af_netlink.c:1189 [inline]
+ netlink_sendmsg+0xcaf/0x1420 net/netlink/af_netlink.c:1883
+ sock_sendmsg_nosec net/socket.c:621 [inline]
+ sock_sendmsg net/socket.c:631 [inline]
+ ___sys_sendmsg+0xe47/0x1200 net/socket.c:2116
+ __sys_sendmsg net/socket.c:2154 [inline]
+ __do_sys_sendmsg net/socket.c:2163 [inline]
+ __se_sys_sendmsg+0x307/0x460 net/socket.c:2161
+ __x64_sys_sendmsg+0x4a/0x70 net/socket.c:2161
+ do_syscall_64+0xbe/0x100 arch/x86/entry/common.c:291
+ entry_SYSCALL_64_after_hwframe+0x63/0xe7
+
+We cannot take for granted the thing that the length of data contained
+in TLV is longer than the size of struct tipc_name_table_query in
+tipc_nl_compat_name_table_dump().
+
+Reported-by: syzbot+06e771a754829716a327@syzkaller.appspotmail.com
+Signed-off-by: Ying Xue <ying.xue@windriver.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/tipc/netlink_compat.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/tipc/netlink_compat.c
++++ b/net/tipc/netlink_compat.c
+@@ -824,6 +824,8 @@ static int tipc_nl_compat_name_table_dum
+       };
+       ntq = (struct tipc_name_table_query *)TLV_DATA(msg->req);
++      if (TLV_GET_DATA_LEN(msg->req) < sizeof(struct tipc_name_table_query))
++              return -EINVAL;
+       depth = ntohl(ntq->depth);