From: Greg Kroah-Hartman Date: Mon, 21 May 2018 06:41:00 +0000 (+0200) Subject: 3.18-stable patches X-Git-Tag: v4.9.102~20 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d9a4bfcae9cb30d3554d1b3908ee0f6bf8349365;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: arm-8771-1-kprobes-prohibit-kprobes-on-do_undefinstr.patch arm-8772-1-kprobes-prohibit-kprobes-on-get_user-functions.patch btrfs-send-fix-invalid-access-to-commit-roots-due-to-concurrent-snapshotting.patch efi-avoid-potential-crashes-fix-the-struct-efi_pci_io_protocol_32-definition-for-mixed-mode.patch tick-broadcast-use-for_each_cpu-specially-on-up-kernels.patch --- diff --git a/queue-3.18/arm-8771-1-kprobes-prohibit-kprobes-on-do_undefinstr.patch b/queue-3.18/arm-8771-1-kprobes-prohibit-kprobes-on-do_undefinstr.patch new file mode 100644 index 00000000000..0f6d7d2ebbe --- /dev/null +++ b/queue-3.18/arm-8771-1-kprobes-prohibit-kprobes-on-do_undefinstr.patch @@ -0,0 +1,52 @@ +From eb0146daefdde65665b7f076fbff7b49dade95b9 Mon Sep 17 00:00:00 2001 +From: Masami Hiramatsu +Date: Sun, 13 May 2018 05:04:16 +0100 +Subject: ARM: 8771/1: kprobes: Prohibit kprobes on do_undefinstr + +From: Masami Hiramatsu + +commit eb0146daefdde65665b7f076fbff7b49dade95b9 upstream. + +Prohibit kprobes on do_undefinstr because kprobes on +arm is implemented by undefined instruction. This means +if we probe do_undefinstr(), it can cause infinit +recursive exception. + +Fixes: 24ba613c9d6c ("ARM kprobes: core code") +Signed-off-by: Masami Hiramatsu +Cc: stable@vger.kernel.org +Signed-off-by: Russell King +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/kernel/traps.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/arch/arm/kernel/traps.c ++++ b/arch/arm/kernel/traps.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -395,7 +396,8 @@ void unregister_undef_hook(struct undef_ + raw_spin_unlock_irqrestore(&undef_lock, flags); + } + +-static int call_undef_hook(struct pt_regs *regs, unsigned int instr) ++static nokprobe_inline ++int call_undef_hook(struct pt_regs *regs, unsigned int instr) + { + struct undef_hook *hook; + unsigned long flags; +@@ -468,6 +470,7 @@ die_sig: + + arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6); + } ++NOKPROBE_SYMBOL(do_undefinstr) + + /* + * Handle FIQ similarly to NMI on x86 systems. diff --git a/queue-3.18/arm-8772-1-kprobes-prohibit-kprobes-on-get_user-functions.patch b/queue-3.18/arm-8772-1-kprobes-prohibit-kprobes-on-get_user-functions.patch new file mode 100644 index 00000000000..6a2d87de425 --- /dev/null +++ b/queue-3.18/arm-8772-1-kprobes-prohibit-kprobes-on-get_user-functions.patch @@ -0,0 +1,118 @@ +From 0d73c3f8e7f6ee2aab1bb350f60c180f5ae21a2c Mon Sep 17 00:00:00 2001 +From: Masami Hiramatsu +Date: Sun, 13 May 2018 05:04:29 +0100 +Subject: ARM: 8772/1: kprobes: Prohibit kprobes on get_user functions + +From: Masami Hiramatsu + +commit 0d73c3f8e7f6ee2aab1bb350f60c180f5ae21a2c upstream. + +Since do_undefinstr() uses get_user to get the undefined +instruction, it can be called before kprobes processes +recursive check. This can cause an infinit recursive +exception. +Prohibit probing on get_user functions. + +Fixes: 24ba613c9d6c ("ARM kprobes: core code") +Signed-off-by: Masami Hiramatsu +Cc: stable@vger.kernel.org +Signed-off-by: Russell King +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/include/asm/assembler.h | 10 ++++++++++ + arch/arm/lib/getuser.S | 10 ++++++++++ + 2 files changed, 20 insertions(+) + +--- a/arch/arm/include/asm/assembler.h ++++ b/arch/arm/include/asm/assembler.h +@@ -448,4 +448,14 @@ THUMB( orr \reg , \reg , #PSR_T_BIT ) + #endif + .endm + ++#ifdef CONFIG_KPROBES ++#define _ASM_NOKPROBE(entry) \ ++ .pushsection "_kprobe_blacklist", "aw" ; \ ++ .balign 4 ; \ ++ .long entry; \ ++ .popsection ++#else ++#define _ASM_NOKPROBE(entry) ++#endif ++ + #endif /* __ASM_ASSEMBLER_H__ */ +--- a/arch/arm/lib/getuser.S ++++ b/arch/arm/lib/getuser.S +@@ -38,6 +38,7 @@ ENTRY(__get_user_1) + mov r0, #0 + ret lr + ENDPROC(__get_user_1) ++_ASM_NOKPROBE(__get_user_1) + + ENTRY(__get_user_2) + check_uaccess r0, 2, r1, r2, __get_user_bad +@@ -58,6 +59,7 @@ rb .req r0 + mov r0, #0 + ret lr + ENDPROC(__get_user_2) ++_ASM_NOKPROBE(__get_user_2) + + ENTRY(__get_user_4) + check_uaccess r0, 4, r1, r2, __get_user_bad +@@ -65,6 +67,7 @@ ENTRY(__get_user_4) + mov r0, #0 + ret lr + ENDPROC(__get_user_4) ++_ASM_NOKPROBE(__get_user_4) + + ENTRY(__get_user_8) + check_uaccess r0, 8, r1, r2, __get_user_bad +@@ -78,6 +81,7 @@ ENTRY(__get_user_8) + mov r0, #0 + ret lr + ENDPROC(__get_user_8) ++_ASM_NOKPROBE(__get_user_8) + + #ifdef __ARMEB__ + ENTRY(__get_user_32t_8) +@@ -91,6 +95,7 @@ ENTRY(__get_user_32t_8) + mov r0, #0 + ret lr + ENDPROC(__get_user_32t_8) ++_ASM_NOKPROBE(__get_user_32t_8) + + ENTRY(__get_user_64t_1) + check_uaccess r0, 1, r1, r2, __get_user_bad8 +@@ -98,6 +103,7 @@ ENTRY(__get_user_64t_1) + mov r0, #0 + ret lr + ENDPROC(__get_user_64t_1) ++_ASM_NOKPROBE(__get_user_64t_1) + + ENTRY(__get_user_64t_2) + check_uaccess r0, 2, r1, r2, __get_user_bad8 +@@ -114,6 +120,7 @@ rb .req r0 + mov r0, #0 + ret lr + ENDPROC(__get_user_64t_2) ++_ASM_NOKPROBE(__get_user_64t_2) + + ENTRY(__get_user_64t_4) + check_uaccess r0, 4, r1, r2, __get_user_bad8 +@@ -121,6 +128,7 @@ ENTRY(__get_user_64t_4) + mov r0, #0 + ret lr + ENDPROC(__get_user_64t_4) ++_ASM_NOKPROBE(__get_user_64t_4) + #endif + + __get_user_bad8: +@@ -131,6 +139,8 @@ __get_user_bad: + ret lr + ENDPROC(__get_user_bad) + ENDPROC(__get_user_bad8) ++_ASM_NOKPROBE(__get_user_bad) ++_ASM_NOKPROBE(__get_user_bad8) + + .pushsection __ex_table, "a" + .long 1b, __get_user_bad diff --git a/queue-3.18/btrfs-send-fix-invalid-access-to-commit-roots-due-to-concurrent-snapshotting.patch b/queue-3.18/btrfs-send-fix-invalid-access-to-commit-roots-due-to-concurrent-snapshotting.patch new file mode 100644 index 00000000000..8c320dab031 --- /dev/null +++ b/queue-3.18/btrfs-send-fix-invalid-access-to-commit-roots-due-to-concurrent-snapshotting.patch @@ -0,0 +1,136 @@ +From 6f2f0b394b54e2b159ef969a0b5274e9bbf82ff2 Mon Sep 17 00:00:00 2001 +From: Robbie Ko +Date: Mon, 14 May 2018 10:51:34 +0800 +Subject: Btrfs: send, fix invalid access to commit roots due to concurrent snapshotting + +From: Robbie Ko + +commit 6f2f0b394b54e2b159ef969a0b5274e9bbf82ff2 upstream. + +[BUG] +btrfs incremental send BUG happens when creating a snapshot of snapshot +that is being used by send. + +[REASON] +The problem can happen if while we are doing a send one of the snapshots +used (parent or send) is snapshotted, because snapshoting implies COWing +the root of the source subvolume/snapshot. + +1. When doing an incremental send, the send process will get the commit + roots from the parent and send snapshots, and add references to them + through extent_buffer_get(). + +2. When a snapshot/subvolume is snapshotted, its root node is COWed + (transaction.c:create_pending_snapshot()). + +3. COWing releases the space used by the node immediately, through: + + __btrfs_cow_block() + --btrfs_free_tree_block() + ----btrfs_add_free_space(bytenr of node) + +4. Because send doesn't hold a transaction open, it's possible that + the transaction used to create the snapshot commits, switches the + commit root and the old space used by the previous root node gets + assigned to some other node allocation. Allocation of a new node will + use the existing extent buffer found in memory, which we previously + got a reference through extent_buffer_get(), and allow the extent + buffer's content (pages) to be modified: + + btrfs_alloc_tree_block + --btrfs_reserve_extent + ----find_free_extent (get bytenr of old node) + --btrfs_init_new_buffer (use bytenr of old node) + ----btrfs_find_create_tree_block + ------alloc_extent_buffer + --------find_extent_buffer (get old node) + +5. So send can access invalid memory content and have unpredictable + behaviour. + +[FIX] +So we fix the problem by copying the commit roots of the send and +parent snapshots and use those copies. + +CallTrace looks like this: + ------------[ cut here ]------------ + kernel BUG at fs/btrfs/ctree.c:1861! + invalid opcode: 0000 [#1] SMP + CPU: 6 PID: 24235 Comm: btrfs Tainted: P O 3.10.105 #23721 + ffff88046652d680 ti: ffff88041b720000 task.ti: ffff88041b720000 + RIP: 0010:[] read_node_slot+0x108/0x110 [btrfs] + RSP: 0018:ffff88041b723b68 EFLAGS: 00010246 + RAX: ffff88043ca6b000 RBX: ffff88041b723c50 RCX: ffff880000000000 + RDX: 000000000000004c RSI: ffff880314b133f8 RDI: ffff880458b24000 + RBP: 0000000000000000 R08: 0000000000000001 R09: ffff88041b723c66 + R10: 0000000000000001 R11: 0000000000001000 R12: ffff8803f3e48890 + R13: ffff8803f3e48880 R14: ffff880466351800 R15: 0000000000000001 + FS: 00007f8c321dc8c0(0000) GS:ffff88047fcc0000(0000) + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + R2: 00007efd1006d000 CR3: 0000000213a24000 CR4: 00000000003407e0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + Stack: + ffff88041b723c50 ffff8803f3e48880 ffff8803f3e48890 ffff8803f3e48880 + ffff880466351800 0000000000000001 ffffffffa08dd9d7 ffff88041b723c50 + ffff8803f3e48880 ffff88041b723c66 ffffffffa08dde85 a9ff88042d2c4400 + Call Trace: + [] ? tree_move_down.isra.33+0x27/0x50 [btrfs] + [] ? tree_advance+0xb5/0xc0 [btrfs] + [] ? btrfs_compare_trees+0x2d4/0x760 [btrfs] + [] ? finish_inode_if_needed+0x870/0x870 [btrfs] + [] ? btrfs_ioctl_send+0xeda/0x1050 [btrfs] + [] ? btrfs_ioctl+0x1e3d/0x33f0 [btrfs] + [] ? handle_pte_fault+0x373/0x990 + [] ? atomic_notifier_call_chain+0x16/0x20 + [] ? set_task_cpu+0xb6/0x1d0 + [] ? handle_mm_fault+0x143/0x2a0 + [] ? __do_page_fault+0x1d0/0x500 + [] ? check_preempt_curr+0x57/0x90 + [] ? do_vfs_ioctl+0x4aa/0x990 + [] ? do_fork+0x113/0x3b0 + [] ? trace_hardirqs_off_thunk+0x3a/0x6c + [] ? SyS_ioctl+0x88/0xa0 + [] ? system_call_fastpath+0x16/0x1b + ---[ end trace 29576629ee80b2e1 ]--- + +Fixes: 7069830a9e38 ("Btrfs: add btrfs_compare_trees function") +CC: stable@vger.kernel.org # 3.6+ +Signed-off-by: Robbie Ko +Reviewed-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/ctree.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -5399,12 +5399,24 @@ int btrfs_compare_trees(struct btrfs_roo + down_read(&left_root->fs_info->commit_root_sem); + left_level = btrfs_header_level(left_root->commit_root); + left_root_level = left_level; +- left_path->nodes[left_level] = left_root->commit_root; ++ left_path->nodes[left_level] = ++ btrfs_clone_extent_buffer(left_root->commit_root); ++ if (!left_path->nodes[left_level]) { ++ up_read(&fs_info->commit_root_sem); ++ ret = -ENOMEM; ++ goto out; ++ } + extent_buffer_get(left_path->nodes[left_level]); + + right_level = btrfs_header_level(right_root->commit_root); + right_root_level = right_level; +- right_path->nodes[right_level] = right_root->commit_root; ++ right_path->nodes[right_level] = ++ btrfs_clone_extent_buffer(right_root->commit_root); ++ if (!right_path->nodes[right_level]) { ++ up_read(&fs_info->commit_root_sem); ++ ret = -ENOMEM; ++ goto out; ++ } + extent_buffer_get(right_path->nodes[right_level]); + up_read(&left_root->fs_info->commit_root_sem); + diff --git a/queue-3.18/efi-avoid-potential-crashes-fix-the-struct-efi_pci_io_protocol_32-definition-for-mixed-mode.patch b/queue-3.18/efi-avoid-potential-crashes-fix-the-struct-efi_pci_io_protocol_32-definition-for-mixed-mode.patch new file mode 100644 index 00000000000..259c2108876 --- /dev/null +++ b/queue-3.18/efi-avoid-potential-crashes-fix-the-struct-efi_pci_io_protocol_32-definition-for-mixed-mode.patch @@ -0,0 +1,81 @@ +From 0b3225ab9407f557a8e20f23f37aa7236c10a9b1 Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel +Date: Fri, 4 May 2018 07:59:58 +0200 +Subject: efi: Avoid potential crashes, fix the 'struct efi_pci_io_protocol_32' definition for mixed mode + +From: Ard Biesheuvel + +commit 0b3225ab9407f557a8e20f23f37aa7236c10a9b1 upstream. + +Mixed mode allows a kernel built for x86_64 to interact with 32-bit +EFI firmware, but requires us to define all struct definitions carefully +when it comes to pointer sizes. + +'struct efi_pci_io_protocol_32' currently uses a 'void *' for the +'romimage' field, which will be interpreted as a 64-bit field +on such kernels, potentially resulting in bogus memory references +and subsequent crashes. + +Tested-by: Hans de Goede +Signed-off-by: Ard Biesheuvel +Cc: +Cc: Linus Torvalds +Cc: Matt Fleming +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: linux-efi@vger.kernel.org +Link: http://lkml.kernel.org/r/20180504060003.19618-13-ard.biesheuvel@linaro.org +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/boot/compressed/eboot.c | 6 ++++-- + include/linux/efi.h | 8 ++++---- + 2 files changed, 8 insertions(+), 6 deletions(-) + +--- a/arch/x86/boot/compressed/eboot.c ++++ b/arch/x86/boot/compressed/eboot.c +@@ -365,7 +365,8 @@ __setup_efi_pci32(efi_pci_io_protocol_32 + if (status != EFI_SUCCESS) + goto free_struct; + +- memcpy(rom->romdata, pci->romimage, pci->romsize); ++ memcpy(rom->romdata, (void *)(unsigned long)pci->romimage, ++ pci->romsize); + return status; + + free_struct: +@@ -471,7 +472,8 @@ __setup_efi_pci64(efi_pci_io_protocol_64 + if (status != EFI_SUCCESS) + goto free_struct; + +- memcpy(rom->romdata, pci->romimage, pci->romsize); ++ memcpy(rom->romdata, (void *)(unsigned long)pci->romimage, ++ pci->romsize); + return status; + + free_struct: +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -360,8 +360,8 @@ typedef struct { + u32 attributes; + u32 get_bar_attributes; + u32 set_bar_attributes; +- uint64_t romsize; +- void *romimage; ++ u64 romsize; ++ u32 romimage; + } efi_pci_io_protocol_32; + + typedef struct { +@@ -380,8 +380,8 @@ typedef struct { + u64 attributes; + u64 get_bar_attributes; + u64 set_bar_attributes; +- uint64_t romsize; +- void *romimage; ++ u64 romsize; ++ u64 romimage; + } efi_pci_io_protocol_64; + + typedef struct { diff --git a/queue-3.18/series b/queue-3.18/series index 3bca1cef33d..8edf511eebf 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -35,3 +35,8 @@ s390-qdio-fix-access-to-uninitialized-qdio_q-fields.patch s390-cpum_sf-ensure-sample-frequency-of-perf-event-attributes-is-non-zero.patch s390-qdio-don-t-release-memory-in-qdio_setup_irq.patch s390-remove-indirect-branch-from-do_softirq_own_stack.patch +efi-avoid-potential-crashes-fix-the-struct-efi_pci_io_protocol_32-definition-for-mixed-mode.patch +arm-8771-1-kprobes-prohibit-kprobes-on-do_undefinstr.patch +tick-broadcast-use-for_each_cpu-specially-on-up-kernels.patch +arm-8772-1-kprobes-prohibit-kprobes-on-get_user-functions.patch +btrfs-send-fix-invalid-access-to-commit-roots-due-to-concurrent-snapshotting.patch diff --git a/queue-3.18/tick-broadcast-use-for_each_cpu-specially-on-up-kernels.patch b/queue-3.18/tick-broadcast-use-for_each_cpu-specially-on-up-kernels.patch new file mode 100644 index 00000000000..da46ef28774 --- /dev/null +++ b/queue-3.18/tick-broadcast-use-for_each_cpu-specially-on-up-kernels.patch @@ -0,0 +1,60 @@ +From 5596fe34495cf0f645f417eb928ef224df3e3cb4 Mon Sep 17 00:00:00 2001 +From: Dexuan Cui +Date: Tue, 15 May 2018 19:52:50 +0000 +Subject: tick/broadcast: Use for_each_cpu() specially on UP kernels + +From: Dexuan Cui + +commit 5596fe34495cf0f645f417eb928ef224df3e3cb4 upstream. + +for_each_cpu() unintuitively reports CPU0 as set independent of the actual +cpumask content on UP kernels. This causes an unexpected PIT interrupt +storm on a UP kernel running in an SMP virtual machine on Hyper-V, and as +a result, the virtual machine can suffer from a strange random delay of 1~20 +minutes during boot-up, and sometimes it can hang forever. + +Protect if by checking whether the cpumask is empty before entering the +for_each_cpu() loop. + +[ tglx: Use !IS_ENABLED(CONFIG_SMP) instead of #ifdeffery ] + +Signed-off-by: Dexuan Cui +Signed-off-by: Thomas Gleixner +Cc: Josh Poulson +Cc: "Michael Kelley (EOSG)" +Cc: Peter Zijlstra +Cc: Frederic Weisbecker +Cc: stable@vger.kernel.org +Cc: Rakib Mullick +Cc: Jork Loeser +Cc: Greg Kroah-Hartman +Cc: Andrew Morton +Cc: KY Srinivasan +Cc: Linus Torvalds +Cc: Alexey Dobriyan +Cc: Dmitry Vyukov +Link: https://lkml.kernel.org/r/KL1P15301MB000678289FE55BA365B3279ABF990@KL1P15301MB0006.APCP153.PROD.OUTLOOK.COM +Link: https://lkml.kernel.org/r/KL1P15301MB0006FA63BC22BEB64902EAA0BF930@KL1P15301MB0006.APCP153.PROD.OUTLOOK.COM +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/tick-broadcast.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/kernel/time/tick-broadcast.c ++++ b/kernel/time/tick-broadcast.c +@@ -585,6 +585,14 @@ again: + now = ktime_get(); + /* Find all expired events */ + for_each_cpu(cpu, tick_broadcast_oneshot_mask) { ++ /* ++ * Required for !SMP because for_each_cpu() reports ++ * unconditionally CPU0 as set on UP kernels. ++ */ ++ if (!IS_ENABLED(CONFIG_SMP) && ++ cpumask_empty(tick_broadcast_oneshot_mask)) ++ break; ++ + td = &per_cpu(tick_cpu_device, cpu); + if (td->evtdev->next_event.tv64 <= now.tv64) { + cpumask_set_cpu(cpu, tmpmask);