From: Greg Kroah-Hartman Date: Mon, 21 Jan 2019 11:53:03 +0000 (+0100) Subject: 4.19-stable patches X-Git-Tag: v4.20.4~21 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=118bd8ec17d20b54b95db7bb1a000eb4fe0c97f2;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches 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 --- 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 index 00000000000..6497599c8db --- /dev/null +++ b/queue-4.19/arm64-dts-marvell-armada-ap806-reserve-psci-area.patch @@ -0,0 +1,49 @@ +From 132ac39cffbcfed80ada38ef0fc6d34d95da7be6 Mon Sep 17 00:00:00 2001 +From: Heinrich Schuchardt +Date: Fri, 21 Dec 2018 17:45:03 +0100 +Subject: arm64: dts: marvell: armada-ap806: reserve PSCI area + +From: Heinrich Schuchardt + +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 +Signed-off-by: Gregory CLEMENT +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..0ebc88edd7b --- /dev/null +++ b/queue-4.19/arm64-kaslr-ensure-randomized-quantities-are-clean-to-the-poc.patch @@ -0,0 +1,70 @@ +From 1598ecda7b239e9232dda032bfddeed9d89fab6c Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel +Date: Tue, 15 Jan 2019 20:47:07 +0100 +Subject: arm64: kaslr: ensure randomized quantities are clean to the PoC + +From: Ard Biesheuvel + +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 +Fixes: f80fb3a3d508 ("arm64: add support for kernel ASLR") +Cc: # v4.6+ +Signed-off-by: Ard Biesheuvel +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + #include + ++#include + #include + #include + #include +@@ -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 index 00000000000..62364c8ee02 --- /dev/null +++ b/queue-4.19/block-loop-don-t-grab-struct-file-for-vfs_getattr-operation.patch @@ -0,0 +1,54 @@ +From b1ab5fa309e6c49e4e06270ec67dd7b3e9971d04 Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Thu, 8 Nov 2018 14:01:01 +0100 +Subject: block/loop: Don't grab "struct file" for vfs_getattr() operation. + +From: Tetsuo Handa + +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 +Reviewed-by: Jan Kara +Signed-off-by: Jan Kara +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..c6d8c0fd199 --- /dev/null +++ b/queue-4.19/block-loop-use-global-lock-for-ioctl-operation.patch @@ -0,0 +1,267 @@ +From 310ca162d779efee8a2dc3731439680f3e9c1e86 Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Thu, 8 Nov 2018 14:01:02 +0100 +Subject: block/loop: Use global lock for ioctl() operation. + +From: Tetsuo Handa + +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 +Reported-by: syzbot +Reviewed-by: Jan Kara +Signed-off-by: Jan Kara +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..d317e642bad --- /dev/null +++ b/queue-4.19/block-use-rcu_work-instead-of-call_rcu-to-avoid-sleep-in-softirq.patch @@ -0,0 +1,115 @@ +From 94a2c3a32b62e868dc1e3d854326745a7f1b8c7a Mon Sep 17 00:00:00 2001 +From: Yufen Yu +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 + +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: + [] __dump_stack lib/dump_stack.c:15 [inline] + [] dump_stack+0x114/0x1a0 lib/dump_stack.c:51 + [] ___might_sleep+0x291/0x490 kernel/sched/core.c:7675 + [] __might_sleep+0xb3/0x270 kernel/sched/core.c:7637 + [] slab_pre_alloc_hook mm/slab.h:361 [inline] + [] slab_alloc_node mm/slub.c:2610 [inline] + [] slab_alloc mm/slub.c:2692 [inline] + [] kmem_cache_alloc_trace+0x2c3/0x5c0 mm/slub.c:2709 + [] kmalloc include/linux/slab.h:479 [inline] + [] kzalloc include/linux/slab.h:623 [inline] + [] kobject_uevent_env+0x2c7/0x1150 lib/kobject_uevent.c:227 + [] kobject_uevent+0x1f/0x30 lib/kobject_uevent.c:374 + [] kobject_cleanup lib/kobject.c:633 [inline] + [] kobject_release+0x229/0x440 lib/kobject.c:675 + [] kref_sub include/linux/kref.h:73 [inline] + [] kref_put include/linux/kref.h:98 [inline] + [] kobject_put+0x72/0xd0 lib/kobject.c:692 + [] put_device+0x25/0x30 drivers/base/core.c:1237 + [] delete_partition_rcu_cb+0x1d4/0x2f0 block/partition-generic.c:232 + [] __rcu_reclaim kernel/rcu/rcu.h:118 [inline] + [] rcu_do_batch kernel/rcu/tree.c:2705 [inline] + [] invoke_rcu_callbacks kernel/rcu/tree.c:2973 [inline] + [] __rcu_process_callbacks kernel/rcu/tree.c:2940 [inline] + [] rcu_process_callbacks+0x59c/0x1c70 kernel/rcu/tree.c:2957 + [] __do_softirq+0x299/0xe20 kernel/softirq.c:273 + [] invoke_softirq kernel/softirq.c:350 [inline] + [] irq_exit+0x216/0x2c0 kernel/softirq.c:391 + [] exiting_irq arch/x86/include/asm/apic.h:652 [inline] + [] smp_apic_timer_interrupt+0x8b/0xc0 arch/x86/kernel/apic/apic.c:926 + [] apic_timer_interrupt+0xa5/0xb0 arch/x86/entry/entry_64.S:746 + [] ? audit_kill_trees+0x180/0x180 + [] fd_install+0x57/0x80 fs/file.c:626 + [] do_sys_open+0x45e/0x550 fs/open.c:1043 + [] SYSC_open fs/open.c:1055 [inline] + [] SyS_open+0x32/0x40 fs/open.c:1050 + [] 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 +Signed-off-by: Yufen Yu +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..b69b8a09453 --- /dev/null +++ b/queue-4.19/blockdev-fix-livelocks-on-loop-device.patch @@ -0,0 +1,123 @@ +From 04906b2f542c23626b0ef6219b808406f8dddbe9 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Mon, 14 Jan 2019 09:48:10 +0100 +Subject: blockdev: Fix livelocks on loop device + +From: Jan Kara + +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 for help with +debugging the problem. + +Reported-by: syzbot+9933e4476f365f5d5a1b@syzkaller.appspotmail.com +Signed-off-by: Jan Kara +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a492fec6442 --- /dev/null +++ b/queue-4.19/bpf-in-__bpf_redirect_no_mac-pull-mac-only-if-present.patch @@ -0,0 +1,115 @@ +From e7c87bd6cc4ec7b0ac1ed0a88a58f8206c577488 Mon Sep 17 00:00:00 2001 +From: Willem de Bruijn +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 + +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 +Signed-off-by: Willem de Bruijn +Acked-by: Martin KaFai Lau +Signed-off-by: Daniel Borkmann +Signed-off-by: Greg Kroah-Hartman + +--- + 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 ? : ""); + 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 index 00000000000..195aaafdf83 --- /dev/null +++ b/queue-4.19/disable-msi-also-when-pcie-octeon.pcie_disable-on.patch @@ -0,0 +1,40 @@ +From a214720cbf50cd8c3f76bbb9c3f5c283910e9d33 Mon Sep 17 00:00:00 2001 +From: YunQiang Su +Date: Tue, 8 Jan 2019 13:45:10 +0800 +Subject: Disable MSI also when pcie-octeon.pcie_disable on + +From: YunQiang Su + +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 +Signed-off-by: Paul Burton +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 + +--- + 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 index 00000000000..b44fa4e23a6 --- /dev/null +++ b/queue-4.19/drm-i915-gvt-fix-mmap-range-check.patch @@ -0,0 +1,58 @@ +From 51b00d8509dc69c98740da2ad07308b630d3eb7d Mon Sep 17 00:00:00 2001 +From: Zhenyu Wang +Date: Fri, 11 Jan 2019 13:58:53 +0800 +Subject: drm/i915/gvt: Fix mmap range check + +From: Zhenyu Wang + +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" +Cc: "Orrala Contreras, Alfredo" +Cc: stable@vger.kernel.org # v4.10+ +Reviewed-by: Hang Yuan +Signed-off-by: Zhenyu Wang +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..378c591014d --- /dev/null +++ b/queue-4.19/fix-int_sqrt64-for-very-large-numbers.patch @@ -0,0 +1,43 @@ +From fbfaf851902cd9293f392f3a1735e0543016d530 Mon Sep 17 00:00:00 2001 +From: Florian La Roche +Date: Sat, 19 Jan 2019 16:14:50 +0100 +Subject: fix int_sqrt64() for very large numbers + +From: Florian La Roche + +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 +Acked-by: Will Deacon +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..9d13b6dbaa5 --- /dev/null +++ b/queue-4.19/ipv6-make-icmp6_send-robust-against-null-skb-dev.patch @@ -0,0 +1,81 @@ +From 8d933670452107e41165bea70a30dffbd281bef1 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Fri, 4 Jan 2019 11:00:00 -0800 +Subject: ipv6: make icmp6_send() robust against null skb->dev + +From: Eric Dumazet + +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 +Cc: Piotr Sawicki +Cc: Casey Schaufler +Reported-by: syzbot +Acked-by: Casey Schaufler +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e8a464c97d6 --- /dev/null +++ b/queue-4.19/kbuild-disable-ld_dead_code_data_elimination-with-ftrace-gcc-4.7.patch @@ -0,0 +1,51 @@ +From 16fd20aa98080c2fa666dc384036ec08c80af710 Mon Sep 17 00:00:00 2001 +From: Paul Burton +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 + +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 +Fixes: e85d1d65cd8a ("kbuild: test dead code/data elimination support in Kconfig") +Reported-by: Geert Uytterhoeven +Cc: Nicholas Piggin +Cc: stable@vger.kernel.org # v4.19+ +Signed-off-by: Masahiro Yamada +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a1855bc4006 --- /dev/null +++ b/queue-4.19/loop-avoid-circular-locking-dependency-between-loop_ctl_mutex-and-bd_mutex.patch @@ -0,0 +1,98 @@ +From 1dded9acf6dc9a34cd27fcf8815507e4e65b3c4f Mon Sep 17 00:00:00 2001 +From: Jan Kara +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 + +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 +Signed-off-by: Jan Kara +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..31d2394d14f --- /dev/null +++ b/queue-4.19/loop-drop-caches-if-offset-or-block_size-are-changed.patch @@ -0,0 +1,101 @@ +From 5db470e229e22b7eda6e23b5566e532c96fb5bc3 Mon Sep 17 00:00:00 2001 +From: Jaegeuk Kim +Date: Wed, 9 Jan 2019 19:17:14 -0800 +Subject: loop: drop caches if offset or block_size are changed + +From: Jaegeuk Kim + +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 +Cc: linux-block@vger.kernel.org +Reported-by: Martijn Coenen +Reviewed-by: Bart Van Assche +Signed-off-by: Jaegeuk Kim +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e1286d92f6e --- /dev/null +++ b/queue-4.19/loop-fix-deadlock-when-calling-blkdev_reread_part.patch @@ -0,0 +1,109 @@ +From 0da03cab87e6323ff2e05b14bc7d5c6fcc531efd Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 8 Nov 2018 14:01:14 +0100 +Subject: loop: Fix deadlock when calling blkdev_reread_part() + +From: Jan Kara + +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 +Signed-off-by: Jan Kara +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..424952e751d --- /dev/null +++ b/queue-4.19/loop-fix-double-mutex_unlock-loop_ctl_mutex-in-loop_control_ioctl.patch @@ -0,0 +1,40 @@ +From 628bd85947091830a8c4872adfd5ed1d515a9cf2 Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +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 + +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 +Reviewed-by: Ming Lei +Reviewed-by: Jan Kara +Signed-off-by: Tetsuo Handa +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..463ae1a351c --- /dev/null +++ b/queue-4.19/loop-fold-__loop_release-into-loop_release.patch @@ -0,0 +1,64 @@ +From 967d1dc144b50ad005e5eecdfadfbcfb399ffff6 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 8 Nov 2018 14:01:03 +0100 +Subject: loop: Fold __loop_release into loop_release + +From: Jan Kara + +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 +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..537db5b7658 --- /dev/null +++ b/queue-4.19/loop-get-rid-of-loop_index_mutex.patch @@ -0,0 +1,163 @@ +From 0a42e99b58a208839626465af194cfe640ef9493 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 8 Nov 2018 14:01:04 +0100 +Subject: loop: Get rid of loop_index_mutex + +From: Jan Kara + +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 +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + + 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 index 00000000000..9de23cfeeb3 --- /dev/null +++ b/queue-4.19/loop-get-rid-of-nested-acquisition-of-loop_ctl_mutex.patch @@ -0,0 +1,79 @@ +From c28445fa06a3a54e06938559b9514c5a7f01c90f Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 8 Nov 2018 14:01:16 +0100 +Subject: loop: Get rid of 'nested' acquisition of loop_ctl_mutex + +From: Jan Kara + +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 +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..7374c84110e --- /dev/null +++ b/queue-4.19/loop-move-loop_reread_partitions-out-of-loop_ctl_mutex.patch @@ -0,0 +1,104 @@ +From 85b0a54a82e4fbceeb1aebb7cb6909edd1a24668 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 8 Nov 2018 14:01:13 +0100 +Subject: loop: Move loop_reread_partitions() out of loop_ctl_mutex + +From: Jan Kara + +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 +Signed-off-by: Jan Kara +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..48d9d0664f7 --- /dev/null +++ b/queue-4.19/loop-move-special-partition-reread-handling-in-loop_clr_fd.patch @@ -0,0 +1,77 @@ +From d57f3374ba4817f7c8d26fae8a13d20ac8d31b92 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 8 Nov 2018 14:01:12 +0100 +Subject: loop: Move special partition reread handling in loop_clr_fd() + +From: Jan Kara + +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 +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..3a7ca72cabc --- /dev/null +++ b/queue-4.19/loop-push-lo_ctl_mutex-down-into-individual-ioctls.patch @@ -0,0 +1,159 @@ +From a13165441d58b216adbd50252a9cc829d78a6bce Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 8 Nov 2018 14:01:05 +0100 +Subject: loop: Push lo_ctl_mutex down into individual ioctls + +From: Jan Kara + +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 +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..3f278a3c806 --- /dev/null +++ b/queue-4.19/loop-push-loop_ctl_mutex-down-into-loop_clr_fd.patch @@ -0,0 +1,135 @@ +From 7ccd0791d98531df7cd59e92d55e4f063d48a070 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 8 Nov 2018 14:01:07 +0100 +Subject: loop: Push loop_ctl_mutex down into loop_clr_fd() + +From: Jan Kara + +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 +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..751488c16fa --- /dev/null +++ b/queue-4.19/loop-push-loop_ctl_mutex-down-to-loop_change_fd.patch @@ -0,0 +1,78 @@ +From c371077000f4138ee3c15fbed50101ff24bdc91d Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 8 Nov 2018 14:01:11 +0100 +Subject: loop: Push loop_ctl_mutex down to loop_change_fd() + +From: Jan Kara + +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 +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a0e5e921540 --- /dev/null +++ b/queue-4.19/loop-push-loop_ctl_mutex-down-to-loop_get_status.patch @@ -0,0 +1,112 @@ +From 4a5ce9ba5877e4640200d84a735361306ad1a1b8 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 8 Nov 2018 14:01:08 +0100 +Subject: loop: Push loop_ctl_mutex down to loop_get_status() + +From: Jan Kara + +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 +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..b23dc51731e --- /dev/null +++ b/queue-4.19/loop-push-loop_ctl_mutex-down-to-loop_set_fd.patch @@ -0,0 +1,86 @@ +From 757ecf40b7e029529768eb5f9562d5eeb3002106 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 8 Nov 2018 14:01:10 +0100 +Subject: loop: Push loop_ctl_mutex down to loop_set_fd() + +From: Jan Kara + +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 +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..c3107341c58 --- /dev/null +++ b/queue-4.19/loop-push-loop_ctl_mutex-down-to-loop_set_status.patch @@ -0,0 +1,148 @@ +From 550df5fdacff94229cde0ed9b8085155654c1696 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 8 Nov 2018 14:01:09 +0100 +Subject: loop: Push loop_ctl_mutex down to loop_set_status() + +From: Jan Kara + +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 +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..2750e6be948 --- /dev/null +++ b/queue-4.19/loop-split-setting-of-lo_state-from-loop_clr_fd.patch @@ -0,0 +1,121 @@ +From a2505b799a496b7b84d9a4a14ec870ff9e42e11b Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 8 Nov 2018 14:01:06 +0100 +Subject: loop: Split setting of lo_state from loop_clr_fd + +From: Jan Kara + +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 +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +- * /do something like mkfs/losetup -d 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 ++ * /do something like mkfs/losetup -d 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 index 00000000000..8ba7c51fe31 --- /dev/null +++ b/queue-4.19/lsm-check-for-null-cred-security-on-free.patch @@ -0,0 +1,41 @@ +From a5795fd38ee8194451ba3f281f075301a3696ce2 Mon Sep 17 00:00:00 2001 +From: James Morris +Date: Wed, 16 Jan 2019 15:41:11 -0800 +Subject: LSM: Check for NULL cred-security on free + +From: James Morris + +commit a5795fd38ee8194451ba3f281f075301a3696ce2 upstream. + +From: Casey Schaufler + +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 +Acked-by: John Johansen +Signed-off-by: James Morris +Reported-by: syzbot+69ca07954461f189e808@syzkaller.appspotmail.com +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..c9d4c0da385 --- /dev/null +++ b/queue-4.19/media-v4l-ioctl-validate-num_planes-for-debug-messages.patch @@ -0,0 +1,45 @@ +From 7fe9f01c04c2673bd6662c35b664f0f91888b96f Mon Sep 17 00:00:00 2001 +From: Sakari Ailus +Date: Thu, 10 Jan 2019 09:24:26 -0500 +Subject: media: v4l: ioctl: Validate num_planes for debug messages + +From: Sakari Ailus + +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 +Cc: stable@vger.kernel.org +Reviewed-by: Thierry Reding +Signed-off-by: Hans Verkuil +Cc: # for v4.12 and up +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e3ec70c9126 --- /dev/null +++ b/queue-4.19/media-vb2-vb2_mmap-move-lock-up.patch @@ -0,0 +1,65 @@ +From cd26d1c4d1bc947b56ae404998ae2276df7b39b7 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Tue, 13 Nov 2018 09:06:46 -0500 +Subject: media: vb2: vb2_mmap: move lock up + +From: Hans Verkuil + +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 +Reported-by: syzbot+be93025dd45dccd8923c@syzkaller.appspotmail.com +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..d0a615d94b1 --- /dev/null +++ b/queue-4.19/media-vivid-fix-error-handling-of-kthread_run.patch @@ -0,0 +1,57 @@ +From 701f49bc028edb19ffccd101997dd84f0d71e279 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Mon, 29 Oct 2018 06:15:31 -0400 +Subject: media: vivid: fix error handling of kthread_run + +From: Hans Verkuil + +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 +Reported-by: syzbot+53d5b2df0d9744411e2e@syzkaller.appspotmail.com +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..7bac9151dce --- /dev/null +++ b/queue-4.19/media-vivid-set-min-width-height-to-a-value-0.patch @@ -0,0 +1,35 @@ +From 9729d6d282a6d7ce88e64c9119cecdf79edf4e88 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Mon, 29 Oct 2018 13:32:38 -0400 +Subject: media: vivid: set min width/height to a value > 0 + +From: Hans Verkuil + +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 +Reported-by: syzbot+57c3d83d71187054d56f@syzkaller.appspotmail.com +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..8c143e23953 --- /dev/null +++ b/queue-4.19/mfd-tps6586x-handle-interrupts-on-suspend.patch @@ -0,0 +1,94 @@ +From ac4ca4b9f4623ba5e1ea7a582f286567c611e027 Mon Sep 17 00:00:00 2001 +From: Jonathan Hunter +Date: Tue, 13 Nov 2018 08:56:31 +0000 +Subject: mfd: tps6586x: Handle interrupts on suspend + +From: Jonathan Hunter + +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 +Reviewed-by: Dmitry Osipenko +Tested-by: Dmitry Osipenko +Acked-by: Thierry Reding +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..c6d2fff41c3 --- /dev/null +++ b/queue-4.19/mips-bcm47xx-setup-struct-device-for-the-soc.patch @@ -0,0 +1,144 @@ +From 321c46b91550adc03054125fa7a1639390608e1a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +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 + +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 +Signed-off-by: Paul Burton +Acked-by: Hauke Mehrtens +Cc: Christoph Hellwig +Cc: Linus Walleij +Cc: linux-wireless@vger.kernel.org +Cc: Ralf Baechle +Cc: James Hogan +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 + +--- + 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 index 00000000000..1c5fb9cdbdb --- /dev/null +++ b/queue-4.19/mips-fix-n32-compat_ipc_parse_version.patch @@ -0,0 +1,41 @@ +From 5a9372f751b5350e0ce3d2ee91832f1feae2c2e5 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Thu, 10 Jan 2019 17:24:31 +0100 +Subject: mips: fix n32 compat_ipc_parse_version + +From: Arnd Bergmann + +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 +Signed-off-by: Paul Burton +Cc: linux-mips@vger.kernel.org +Cc: stable@vger.kernel.org # 3.19+ +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..daa48be4e9f --- /dev/null +++ b/queue-4.19/mips-lantiq-fix-ipi-interrupt-handling.patch @@ -0,0 +1,146 @@ +From 2b4dba55b04b212a7fd1f0395b41d79ee3a9801b Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Sun, 6 Jan 2019 19:44:11 +0100 +Subject: MIPS: lantiq: Fix IPI interrupt handling + +From: Hauke Mehrtens + +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 +Signed-off-by: Paul Burton +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 + +--- + 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 = <q_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 index 00000000000..ce1487f6cd4 --- /dev/null +++ b/queue-4.19/net-dsa-realtek-smi-fix-of-child-node-lookup.patch @@ -0,0 +1,76 @@ +From 3f1bb6abdf19cfa89860b3bc9e7f31b44b6a0ba1 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Wed, 16 Jan 2019 11:27:08 +0100 +Subject: net: dsa: realtek-smi: fix OF child-node lookup + +From: Johan Hovold + +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 # 4.19: 36156f9241cb0 +Cc: Linus Walleij +Signed-off-by: Johan Hovold +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..0553f1b967d --- /dev/null +++ b/queue-4.19/netfilter-ebtables-account-ebt_table_info-to-kmemcg.patch @@ -0,0 +1,56 @@ +From e2c8d550a973bb34fc28bc8d0ec996f84562fb8a Mon Sep 17 00:00:00 2001 +From: Shakeel Butt +Date: Wed, 2 Jan 2019 19:14:31 -0800 +Subject: netfilter: ebtables: account ebt_table_info to kmemcg + +From: Shakeel Butt + +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 +Reviewed-by: Kirill Tkhai +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..565558a47cf --- /dev/null +++ b/queue-4.19/of-properties-add-missing-of_node_put.patch @@ -0,0 +1,51 @@ +From 28b170e88bc0c7509e6724717c15cb4b5686026e Mon Sep 17 00:00:00 2001 +From: Julia Lawall +Date: Sun, 13 Jan 2019 10:44:50 +0100 +Subject: OF: properties: add missing of_node_put + +From: Julia Lawall + +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): + +// +@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 ...; +) +// + +Signed-off-by: Julia Lawall +Cc: stable@vger.kernel.org +Signed-off-by: Rob Herring +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..7052b558964 --- /dev/null +++ b/queue-4.19/omap2fb-fix-stack-memory-disclosure.patch @@ -0,0 +1,41 @@ +From a01421e4484327fe44f8e126793ed5a48a221e24 Mon Sep 17 00:00:00 2001 +From: Vlad Tsyrklevich +Date: Fri, 11 Jan 2019 14:34:38 +0100 +Subject: omap2fb: Fix stack memory disclosure + +From: Vlad Tsyrklevich + +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 +Reviewed-by: Kees Cook +Fixes: b39a982ddecf ("OMAP: DSS2: omapfb driver") +Cc: security@kernel.org +[b.zolnierkie: prefix patch subject with "omap2fb: "] +Signed-off-by: Bartlomiej Zolnierkiewicz +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..772b0e76475 --- /dev/null +++ b/queue-4.19/pstore-ram-avoid-allocation-and-leak-of-platform-data.patch @@ -0,0 +1,47 @@ +From 5631e8576a3caf606cdc375f97425a67983b420c Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Sun, 20 Jan 2019 14:33:34 -0800 +Subject: pstore/ram: Avoid allocation and leak of platform data + +From: Kees Cook + +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 +Fixes: 35da60941e44 ("pstore/ram: add Device Tree bindings") +Cc: stable@vger.kernel.org +Signed-off-by: Kees Cook +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..cf646487524 --- /dev/null +++ b/queue-4.19/rdma-nldev-don-t-expose-unsafe-global-rkey-to-regular-user.patch @@ -0,0 +1,38 @@ +From a9666c1cae8dbcd1a9aacd08a778bf2a28eea300 Mon Sep 17 00:00:00 2001 +From: Leon Romanovsky +Date: Mon, 24 Dec 2018 11:05:16 +0200 +Subject: RDMA/nldev: Don't expose unsafe global rkey to regular user + +From: Leon Romanovsky + +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: # 4.16 +Fixes: 29cf1351d450 ("RDMA/nldev: provide detailed PD information") +Signed-off-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a6b889f5592 --- /dev/null +++ b/queue-4.19/rdma-vmw_pvrdma-return-the-correct-opcode-when-creating-wr.patch @@ -0,0 +1,97 @@ +From 6325e01b6cdf4636b721cf7259c1616e3cf28ce2 Mon Sep 17 00:00:00 2001 +From: Adit Ranadive +Date: Wed, 9 Jan 2019 23:08:49 +0000 +Subject: RDMA/vmw_pvrdma: Return the correct opcode when creating WR + +From: Adit Ranadive + +commit 6325e01b6cdf4636b721cf7259c1616e3cf28ce2 upstream. + +Since the IB_WR_REG_MR opcode value changed, let's set the PVRDMA device +opcodes explicitly. + +Reported-by: Ruishuang Wang +Fixes: 9a59739bd01f ("IB/rxe: Revise the ib_wr_opcode enum") +Cc: stable@vger.kernel.org +Reviewed-by: Bryan Tan +Reviewed-by: Ruishuang Wang +Reviewed-by: Vishnu Dasa +Signed-off-by: Adit Ranadive +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..ddcbd29f37a --- /dev/null +++ b/queue-4.19/sctp-allocate-sctp_sockaddr_entry-with-kzalloc.patch @@ -0,0 +1,74 @@ +From 400b8b9a2a17918f8ce00786f596f530e7f30d50 Mon Sep 17 00:00:00 2001 +From: Xin Long +Date: Mon, 14 Jan 2019 18:34:02 +0800 +Subject: sctp: allocate sctp_sockaddr_entry with kzalloc + +From: Xin Long + +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 +Signed-off-by: Xin Long +Reported-by: syzbot+ae0c70c0c2d40c51bb92@syzkaller.appspotmail.com +Acked-by: Marcelo Ricardo Leitner +Acked-by: Neil Horman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..21b3afac579 --- /dev/null +++ b/queue-4.19/selinux-fix-gpf-on-invalid-policy.patch @@ -0,0 +1,34 @@ +From 5b0e7310a2a33c06edc7eb81ffc521af9b2c5610 Mon Sep 17 00:00:00 2001 +From: Stephen Smalley +Date: Wed, 9 Jan 2019 10:55:10 -0500 +Subject: selinux: fix GPF on invalid policy + +From: Stephen Smalley + +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 +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-4.19/series b/queue-4.19/series index 6113511df49..37edc2dbbc4 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -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 index 00000000000..b752f071669 --- /dev/null +++ b/queue-4.19/sunrpc-handle-enomem-in-rpcb_getport_async.patch @@ -0,0 +1,44 @@ +From 81c88b18de1f11f70c97f28ced8d642c00bb3955 Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Thu, 20 Dec 2018 10:35:11 -0500 +Subject: sunrpc: handle ENOMEM in rpcb_getport_async + +From: J. Bruce Fields + +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 +Signed-off-by: Anna Schumaker +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..902d39a07ef --- /dev/null +++ b/queue-4.19/tipc-fix-uninit-value-in-in-tipc_conn_rcv_sub.patch @@ -0,0 +1,60 @@ +From a88289f4ddee4165d5f796bd99e09eec3133c16b Mon Sep 17 00:00:00 2001 +From: Ying Xue +Date: Mon, 14 Jan 2019 17:22:24 +0800 +Subject: tipc: fix uninit-value in in tipc_conn_rcv_sub + +From: Ying Xue + +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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..ba1353ac576 --- /dev/null +++ b/queue-4.19/tipc-fix-uninit-value-in-tipc_nl_compat_bearer_enable.patch @@ -0,0 +1,189 @@ +From 0762216c0ad2a2fccd63890648eca491f2c83d9a Mon Sep 17 00:00:00 2001 +From: Ying Xue +Date: Mon, 14 Jan 2019 17:22:26 +0800 +Subject: tipc: fix uninit-value in tipc_nl_compat_bearer_enable + +From: Ying Xue + +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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..2a4fc3777b1 --- /dev/null +++ b/queue-4.19/tipc-fix-uninit-value-in-tipc_nl_compat_doit.patch @@ -0,0 +1,94 @@ +From 2753ca5d9009c180dbfd4c802c80983b4b6108d1 Mon Sep 17 00:00:00 2001 +From: Ying Xue +Date: Mon, 14 Jan 2019 17:22:29 +0800 +Subject: tipc: fix uninit-value in tipc_nl_compat_doit + +From: Ying Xue + +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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..fd14498854d --- /dev/null +++ b/queue-4.19/tipc-fix-uninit-value-in-tipc_nl_compat_link_reset_stats.patch @@ -0,0 +1,133 @@ +From 8b66fee7f8ee18f9c51260e7a43ab37db5177a05 Mon Sep 17 00:00:00 2001 +From: Ying Xue +Date: Mon, 14 Jan 2019 17:22:25 +0800 +Subject: tipc: fix uninit-value in tipc_nl_compat_link_reset_stats + +From: Ying Xue + +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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..d95ae11a082 --- /dev/null +++ b/queue-4.19/tipc-fix-uninit-value-in-tipc_nl_compat_link_set.patch @@ -0,0 +1,76 @@ +From edf5ff04a45750ac8ce2435974f001dc9cfbf055 Mon Sep 17 00:00:00 2001 +From: Ying Xue +Date: Mon, 14 Jan 2019 17:22:27 +0800 +Subject: tipc: fix uninit-value in tipc_nl_compat_link_set + +From: Ying Xue + +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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..b952cb5e4a5 --- /dev/null +++ b/queue-4.19/tipc-fix-uninit-value-in-tipc_nl_compat_name_table_dump.patch @@ -0,0 +1,100 @@ +From 974cb0e3e7c963ced06c4e32c5b2884173fa5e01 Mon Sep 17 00:00:00 2001 +From: Ying Xue +Date: Mon, 14 Jan 2019 17:22:28 +0800 +Subject: tipc: fix uninit-value in tipc_nl_compat_name_table_dump + +From: Ying Xue + +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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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); +