From: Greg Kroah-Hartman Date: Fri, 4 Sep 2020 09:12:41 +0000 (+0200) Subject: 5.8-stable patches X-Git-Tag: v5.4.63~10 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6f75461db6d4bdd2f860313af6020061ec1f0467;p=thirdparty%2Fkernel%2Fstable-queue.git 5.8-stable patches added patches: hid-core-correctly-handle-reportsize-being-zero.patch hid-core-sanitize-event-code-and-type-when-mapping-input.patch kvm-arm64-add-kvm_extable-for-vaxorcism-code.patch kvm-arm64-survive-synchronous-exceptions-caused-by-at-instructions.patch media-media-v4l2-core-fix-kernel-infoleak-in-video_put_user.patch mm-fix-pin-vs.-gup-mismatch-with-gate-pages.patch netfilter-nft_set_rbtree-handle-outcomes-of-tree-rotations-in-overlap-detection.patch perf-record-stat-explicitly-call-out-event-modifiers-in-the-documentation.patch selftests-x86-test_vsyscall-improve-the-process_vm_readv-test.patch --- diff --git a/queue-5.8/hid-core-correctly-handle-reportsize-being-zero.patch b/queue-5.8/hid-core-correctly-handle-reportsize-being-zero.patch new file mode 100644 index 00000000000..1d746e17792 --- /dev/null +++ b/queue-5.8/hid-core-correctly-handle-reportsize-being-zero.patch @@ -0,0 +1,63 @@ +From bce1305c0ece3dc549663605e567655dd701752c Mon Sep 17 00:00:00 2001 +From: Marc Zyngier +Date: Sat, 29 Aug 2020 12:26:01 +0100 +Subject: HID: core: Correctly handle ReportSize being zero + +From: Marc Zyngier + +commit bce1305c0ece3dc549663605e567655dd701752c upstream. + +It appears that a ReportSize value of zero is legal, even if a bit +non-sensical. Most of the HID code seems to handle that gracefully, +except when computing the total size in bytes. When fed as input to +memset, this leads to some funky outcomes. + +Detect the corner case and correctly compute the size. + +Cc: stable@vger.kernel.org +Signed-off-by: Marc Zyngier +Signed-off-by: Benjamin Tissoires +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-core.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1598,6 +1598,17 @@ static void hid_output_field(const struc + } + + /* ++ * Compute the size of a report. ++ */ ++static size_t hid_compute_report_size(struct hid_report *report) ++{ ++ if (report->size) ++ return ((report->size - 1) >> 3) + 1; ++ ++ return 0; ++} ++ ++/* + * Create a report. 'data' has to be allocated using + * hid_alloc_report_buf() so that it has proper size. + */ +@@ -1609,7 +1620,7 @@ void hid_output_report(struct hid_report + if (report->id > 0) + *data++ = report->id; + +- memset(data, 0, ((report->size - 1) >> 3) + 1); ++ memset(data, 0, hid_compute_report_size(report)); + for (n = 0; n < report->maxfield; n++) + hid_output_field(report->device, report->field[n], data); + } +@@ -1739,7 +1750,7 @@ int hid_report_raw_event(struct hid_devi + csize--; + } + +- rsize = ((report->size - 1) >> 3) + 1; ++ rsize = hid_compute_report_size(report); + + if (report_enum->numbered && rsize >= HID_MAX_BUFFER_SIZE) + rsize = HID_MAX_BUFFER_SIZE - 1; diff --git a/queue-5.8/hid-core-sanitize-event-code-and-type-when-mapping-input.patch b/queue-5.8/hid-core-sanitize-event-code-and-type-when-mapping-input.patch new file mode 100644 index 00000000000..9548c025ca9 --- /dev/null +++ b/queue-5.8/hid-core-sanitize-event-code-and-type-when-mapping-input.patch @@ -0,0 +1,132 @@ +From 35556bed836f8dc07ac55f69c8d17dce3e7f0e25 Mon Sep 17 00:00:00 2001 +From: Marc Zyngier +Date: Tue, 1 Sep 2020 10:52:33 +0100 +Subject: HID: core: Sanitize event code and type when mapping input + +From: Marc Zyngier + +commit 35556bed836f8dc07ac55f69c8d17dce3e7f0e25 upstream. + +When calling into hid_map_usage(), the passed event code is +blindly stored as is, even if it doesn't fit in the associated bitmap. + +This event code can come from a variety of sources, including devices +masquerading as input devices, only a bit more "programmable". + +Instead of taking the event code at face value, check that it actually +fits the corresponding bitmap, and if it doesn't: +- spit out a warning so that we know which device is acting up +- NULLify the bitmap pointer so that we catch unexpected uses + +Code paths that can make use of untrusted inputs can now check +that the mapping was indeed correct and bail out if not. + +Cc: stable@vger.kernel.org +Signed-off-by: Marc Zyngier +Signed-off-by: Benjamin Tissoires +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-input.c | 4 ++++ + drivers/hid/hid-multitouch.c | 2 ++ + include/linux/hid.h | 42 +++++++++++++++++++++++++++++------------- + 3 files changed, 35 insertions(+), 13 deletions(-) + +--- a/drivers/hid/hid-input.c ++++ b/drivers/hid/hid-input.c +@@ -1132,6 +1132,10 @@ static void hidinput_configure_usage(str + } + + mapped: ++ /* Mapping failed, bail out */ ++ if (!bit) ++ return; ++ + if (device->driver->input_mapped && + device->driver->input_mapped(device, hidinput, field, usage, + &bit, &max) < 0) { +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -856,6 +856,8 @@ static int mt_touch_input_mapping(struct + code = BTN_0 + ((usage->hid - 1) & HID_USAGE); + + hid_map_usage(hi, usage, bit, max, EV_KEY, code); ++ if (!*bit) ++ return -1; + input_set_capability(hi->input, EV_KEY, code); + return 1; + +--- a/include/linux/hid.h ++++ b/include/linux/hid.h +@@ -959,34 +959,49 @@ static inline void hid_device_io_stop(st + * @max: maximal valid usage->code to consider later (out parameter) + * @type: input event type (EV_KEY, EV_REL, ...) + * @c: code which corresponds to this usage and type ++ * ++ * The value pointed to by @bit will be set to NULL if either @type is ++ * an unhandled event type, or if @c is out of range for @type. This ++ * can be used as an error condition. + */ + static inline void hid_map_usage(struct hid_input *hidinput, + struct hid_usage *usage, unsigned long **bit, int *max, +- __u8 type, __u16 c) ++ __u8 type, unsigned int c) + { + struct input_dev *input = hidinput->input; +- +- usage->type = type; +- usage->code = c; ++ unsigned long *bmap = NULL; ++ unsigned int limit = 0; + + switch (type) { + case EV_ABS: +- *bit = input->absbit; +- *max = ABS_MAX; ++ bmap = input->absbit; ++ limit = ABS_MAX; + break; + case EV_REL: +- *bit = input->relbit; +- *max = REL_MAX; ++ bmap = input->relbit; ++ limit = REL_MAX; + break; + case EV_KEY: +- *bit = input->keybit; +- *max = KEY_MAX; ++ bmap = input->keybit; ++ limit = KEY_MAX; + break; + case EV_LED: +- *bit = input->ledbit; +- *max = LED_MAX; ++ bmap = input->ledbit; ++ limit = LED_MAX; + break; + } ++ ++ if (unlikely(c > limit || !bmap)) { ++ pr_warn_ratelimited("%s: Invalid code %d type %d\n", ++ input->name, c, type); ++ *bit = NULL; ++ return; ++ } ++ ++ usage->type = type; ++ usage->code = c; ++ *max = limit; ++ *bit = bmap; + } + + /** +@@ -1000,7 +1015,8 @@ static inline void hid_map_usage_clear(s + __u8 type, __u16 c) + { + hid_map_usage(hidinput, usage, bit, max, type, c); +- clear_bit(c, *bit); ++ if (*bit) ++ clear_bit(usage->code, *bit); + } + + /** diff --git a/queue-5.8/kvm-arm64-add-kvm_extable-for-vaxorcism-code.patch b/queue-5.8/kvm-arm64-add-kvm_extable-for-vaxorcism-code.patch new file mode 100644 index 00000000000..42ab0d17259 --- /dev/null +++ b/queue-5.8/kvm-arm64-add-kvm_extable-for-vaxorcism-code.patch @@ -0,0 +1,235 @@ +From e9ee186bb735bfc17fa81dbc9aebf268aee5b41e Mon Sep 17 00:00:00 2001 +From: James Morse +Date: Fri, 21 Aug 2020 15:07:05 +0100 +Subject: KVM: arm64: Add kvm_extable for vaxorcism code + +From: James Morse + +commit e9ee186bb735bfc17fa81dbc9aebf268aee5b41e upstream. + +KVM has a one instruction window where it will allow an SError exception +to be consumed by the hypervisor without treating it as a hypervisor bug. +This is used to consume asynchronous external abort that were caused by +the guest. + +As we are about to add another location that survives unexpected exceptions, +generalise this code to make it behave like the host's extable. + +KVM's version has to be mapped to EL2 to be accessible on nVHE systems. + +The SError vaxorcism code is a one instruction window, so has two entries +in the extable. Because the KVM code is copied for VHE and nVHE, we end up +with four entries, half of which correspond with code that isn't mapped. + +Signed-off-by: James Morse +Reviewed-by: Marc Zyngier +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/include/asm/kvm_asm.h | 15 +++++++++++ + arch/arm64/kernel/vmlinux.lds.S | 8 ++++++ + arch/arm64/kvm/hyp/entry.S | 15 ++++++----- + arch/arm64/kvm/hyp/hyp-entry.S | 51 +++++++++++++++++++++++---------------- + arch/arm64/kvm/hyp/switch.c | 31 +++++++++++++++++++++++ + 5 files changed, 94 insertions(+), 26 deletions(-) + +--- a/arch/arm64/include/asm/kvm_asm.h ++++ b/arch/arm64/include/asm/kvm_asm.h +@@ -146,6 +146,21 @@ extern char __smccc_workaround_1_smc[__S + kern_hyp_va \vcpu + .endm + ++/* ++ * KVM extable for unexpected exceptions. ++ * In the same format _asm_extable, but output to a different section so that ++ * it can be mapped to EL2. The KVM version is not sorted. The caller must ++ * ensure: ++ * x18 has the hypervisor value to allow any Shadow-Call-Stack instrumented ++ * code to write to it, and that SPSR_EL2 and ELR_EL2 are restored by the fixup. ++ */ ++.macro _kvm_extable, from, to ++ .pushsection __kvm_ex_table, "a" ++ .align 3 ++ .long (\from - .), (\to - .) ++ .popsection ++.endm ++ + #endif + + #endif /* __ARM_KVM_ASM_H__ */ +--- a/arch/arm64/kernel/vmlinux.lds.S ++++ b/arch/arm64/kernel/vmlinux.lds.S +@@ -21,6 +21,13 @@ ENTRY(_text) + + jiffies = jiffies_64; + ++ ++#define HYPERVISOR_EXTABLE \ ++ . = ALIGN(SZ_8); \ ++ __start___kvm_ex_table = .; \ ++ *(__kvm_ex_table) \ ++ __stop___kvm_ex_table = .; ++ + #define HYPERVISOR_TEXT \ + /* \ + * Align to 4 KB so that \ +@@ -36,6 +43,7 @@ jiffies = jiffies_64; + __hyp_idmap_text_end = .; \ + __hyp_text_start = .; \ + *(.hyp.text) \ ++ HYPERVISOR_EXTABLE \ + __hyp_text_end = .; + + #define IDMAP_TEXT \ +--- a/arch/arm64/kvm/hyp/entry.S ++++ b/arch/arm64/kvm/hyp/entry.S +@@ -198,20 +198,23 @@ alternative_endif + // This is our single instruction exception window. A pending + // SError is guaranteed to occur at the earliest when we unmask + // it, and at the latest just after the ISB. +- .global abort_guest_exit_start + abort_guest_exit_start: + + isb + +- .global abort_guest_exit_end + abort_guest_exit_end: + + msr daifset, #4 // Mask aborts ++ ret + +- // If the exception took place, restore the EL1 exception +- // context so that we can report some information. +- // Merge the exception code with the SError pending bit. +- tbz x0, #ARM_EXIT_WITH_SERROR_BIT, 1f ++ _kvm_extable abort_guest_exit_start, 9997f ++ _kvm_extable abort_guest_exit_end, 9997f ++9997: ++ msr daifset, #4 // Mask aborts ++ mov x0, #(1 << ARM_EXIT_WITH_SERROR_BIT) ++ ++ // restore the EL1 exception context so that we can report some ++ // information. Merge the exception code with the SError pending bit. + msr elr_el2, x2 + msr esr_el2, x3 + msr spsr_el2, x4 +--- a/arch/arm64/kvm/hyp/hyp-entry.S ++++ b/arch/arm64/kvm/hyp/hyp-entry.S +@@ -15,6 +15,30 @@ + #include + #include + ++.macro save_caller_saved_regs_vect ++ /* x0 and x1 were saved in the vector entry */ ++ stp x2, x3, [sp, #-16]! ++ stp x4, x5, [sp, #-16]! ++ stp x6, x7, [sp, #-16]! ++ stp x8, x9, [sp, #-16]! ++ stp x10, x11, [sp, #-16]! ++ stp x12, x13, [sp, #-16]! ++ stp x14, x15, [sp, #-16]! ++ stp x16, x17, [sp, #-16]! ++.endm ++ ++.macro restore_caller_saved_regs_vect ++ ldp x16, x17, [sp], #16 ++ ldp x14, x15, [sp], #16 ++ ldp x12, x13, [sp], #16 ++ ldp x10, x11, [sp], #16 ++ ldp x8, x9, [sp], #16 ++ ldp x6, x7, [sp], #16 ++ ldp x4, x5, [sp], #16 ++ ldp x2, x3, [sp], #16 ++ ldp x0, x1, [sp], #16 ++.endm ++ + .text + .pushsection .hyp.text, "ax" + +@@ -156,27 +180,14 @@ el2_sync: + + + el2_error: +- ldp x0, x1, [sp], #16 ++ save_caller_saved_regs_vect ++ stp x29, x30, [sp, #-16]! ++ ++ bl kvm_unexpected_el2_exception ++ ++ ldp x29, x30, [sp], #16 ++ restore_caller_saved_regs_vect + +- /* +- * Only two possibilities: +- * 1) Either we come from the exit path, having just unmasked +- * PSTATE.A: change the return code to an EL2 fault, and +- * carry on, as we're already in a sane state to handle it. +- * 2) Or we come from anywhere else, and that's a bug: we panic. +- * +- * For (1), x0 contains the original return code and x1 doesn't +- * contain anything meaningful at that stage. We can reuse them +- * as temp registers. +- * For (2), who cares? +- */ +- mrs x0, elr_el2 +- adr x1, abort_guest_exit_start +- cmp x0, x1 +- adr x1, abort_guest_exit_end +- ccmp x0, x1, #4, ne +- b.ne __hyp_panic +- mov x0, #(1 << ARM_EXIT_WITH_SERROR_BIT) + eret + sb + +--- a/arch/arm64/kvm/hyp/switch.c ++++ b/arch/arm64/kvm/hyp/switch.c +@@ -14,6 +14,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -24,6 +25,9 @@ + #include + #include + ++extern struct exception_table_entry __start___kvm_ex_table; ++extern struct exception_table_entry __stop___kvm_ex_table; ++ + /* Check whether the FP regs were dirtied while in the host-side run loop: */ + static bool __hyp_text update_fp_enabled(struct kvm_vcpu *vcpu) + { +@@ -934,3 +938,30 @@ void __hyp_text __noreturn hyp_panic(str + + unreachable(); + } ++ ++asmlinkage void __hyp_text kvm_unexpected_el2_exception(void) ++{ ++ unsigned long addr, fixup; ++ struct kvm_cpu_context *host_ctxt; ++ struct exception_table_entry *entry, *end; ++ unsigned long elr_el2 = read_sysreg(elr_el2); ++ ++ entry = hyp_symbol_addr(__start___kvm_ex_table); ++ end = hyp_symbol_addr(__stop___kvm_ex_table); ++ host_ctxt = &__hyp_this_cpu_ptr(kvm_host_data)->host_ctxt; ++ ++ while (entry < end) { ++ addr = (unsigned long)&entry->insn + entry->insn; ++ fixup = (unsigned long)&entry->fixup + entry->fixup; ++ ++ if (addr != elr_el2) { ++ entry++; ++ continue; ++ } ++ ++ write_sysreg(fixup, elr_el2); ++ return; ++ } ++ ++ hyp_panic(host_ctxt); ++} diff --git a/queue-5.8/kvm-arm64-survive-synchronous-exceptions-caused-by-at-instructions.patch b/queue-5.8/kvm-arm64-survive-synchronous-exceptions-caused-by-at-instructions.patch new file mode 100644 index 00000000000..66b249a40bc --- /dev/null +++ b/queue-5.8/kvm-arm64-survive-synchronous-exceptions-caused-by-at-instructions.patch @@ -0,0 +1,129 @@ +From 88a84ccccb3966bcc3f309cdb76092a9892c0260 Mon Sep 17 00:00:00 2001 +From: James Morse +Date: Fri, 21 Aug 2020 15:07:06 +0100 +Subject: KVM: arm64: Survive synchronous exceptions caused by AT instructions + +From: James Morse + +commit 88a84ccccb3966bcc3f309cdb76092a9892c0260 upstream. + +KVM doesn't expect any synchronous exceptions when executing, any such +exception leads to a panic(). AT instructions access the guest page +tables, and can cause a synchronous external abort to be taken. + +The arm-arm is unclear on what should happen if the guest has configured +the hardware update of the access-flag, and a memory type in TCR_EL1 that +does not support atomic operations. B2.2.6 "Possible implementation +restrictions on using atomic instructions" from DDI0487F.a lists +synchronous external abort as a possible behaviour of atomic instructions +that target memory that isn't writeback cacheable, but the page table +walker may behave differently. + +Make KVM robust to synchronous exceptions caused by AT instructions. +Add a get_user() style helper for AT instructions that returns -EFAULT +if an exception was generated. + +While KVM's version of the exception table mixes synchronous and +asynchronous exceptions, only one of these can occur at each location. + +Re-enter the guest when the AT instructions take an exception on the +assumption the guest will take the same exception. This isn't guaranteed +to make forward progress, as the AT instructions may always walk the page +tables, but guest execution may use the translation cached in the TLB. + +This isn't a problem, as since commit 5dcd0fdbb492 ("KVM: arm64: Defer guest +entry when an asynchronous exception is pending"), KVM will return to the +host to process IRQs allowing the rest of the system to keep running. + +Cc: stable@vger.kernel.org # +Reviewed-by: Marc Zyngier +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/include/asm/kvm_asm.h | 28 ++++++++++++++++++++++++++++ + arch/arm64/kvm/hyp/hyp-entry.S | 14 ++++++++++---- + arch/arm64/kvm/hyp/switch.c | 8 ++++---- + 3 files changed, 42 insertions(+), 8 deletions(-) + +--- a/arch/arm64/include/asm/kvm_asm.h ++++ b/arch/arm64/include/asm/kvm_asm.h +@@ -121,6 +121,34 @@ extern char __smccc_workaround_1_smc[__S + *__hyp_this_cpu_ptr(sym); \ + }) + ++#define __KVM_EXTABLE(from, to) \ ++ " .pushsection __kvm_ex_table, \"a\"\n" \ ++ " .align 3\n" \ ++ " .long (" #from " - .), (" #to " - .)\n" \ ++ " .popsection\n" ++ ++ ++#define __kvm_at(at_op, addr) \ ++( { \ ++ int __kvm_at_err = 0; \ ++ u64 spsr, elr; \ ++ asm volatile( \ ++ " mrs %1, spsr_el2\n" \ ++ " mrs %2, elr_el2\n" \ ++ "1: at "at_op", %3\n" \ ++ " isb\n" \ ++ " b 9f\n" \ ++ "2: msr spsr_el2, %1\n" \ ++ " msr elr_el2, %2\n" \ ++ " mov %w0, %4\n" \ ++ "9:\n" \ ++ __KVM_EXTABLE(1b, 2b) \ ++ : "+r" (__kvm_at_err), "=&r" (spsr), "=&r" (elr) \ ++ : "r" (addr), "i" (-EFAULT)); \ ++ __kvm_at_err; \ ++} ) ++ ++ + #else /* __ASSEMBLY__ */ + + .macro hyp_adr_this_cpu reg, sym, tmp +--- a/arch/arm64/kvm/hyp/hyp-entry.S ++++ b/arch/arm64/kvm/hyp/hyp-entry.S +@@ -166,13 +166,19 @@ el1_error: + b __guest_exit + + el2_sync: +- /* Check for illegal exception return, otherwise panic */ ++ /* Check for illegal exception return */ + mrs x0, spsr_el2 ++ tbnz x0, #20, 1f + +- /* if this was something else, then panic! */ +- tst x0, #PSR_IL_BIT +- b.eq __hyp_panic ++ save_caller_saved_regs_vect ++ stp x29, x30, [sp, #-16]! ++ bl kvm_unexpected_el2_exception ++ ldp x29, x30, [sp], #16 ++ restore_caller_saved_regs_vect + ++ eret ++ ++1: + /* Let's attempt a recovery from the illegal exception return */ + get_vcpu_ptr x1, x0 + mov x0, #ARM_EXCEPTION_IL +--- a/arch/arm64/kvm/hyp/switch.c ++++ b/arch/arm64/kvm/hyp/switch.c +@@ -303,10 +303,10 @@ static bool __hyp_text __translate_far_t + * saved the guest context yet, and we may return early... + */ + par = read_sysreg(par_el1); +- asm volatile("at s1e1r, %0" : : "r" (far)); +- isb(); +- +- tmp = read_sysreg(par_el1); ++ if (!__kvm_at("s1e1r", far)) ++ tmp = read_sysreg(par_el1); ++ else ++ tmp = SYS_PAR_EL1_F; /* back to the guest */ + write_sysreg(par, par_el1); + + if (unlikely(tmp & SYS_PAR_EL1_F)) diff --git a/queue-5.8/media-media-v4l2-core-fix-kernel-infoleak-in-video_put_user.patch b/queue-5.8/media-media-v4l2-core-fix-kernel-infoleak-in-video_put_user.patch new file mode 100644 index 00000000000..bf93c2c4c88 --- /dev/null +++ b/queue-5.8/media-media-v4l2-core-fix-kernel-infoleak-in-video_put_user.patch @@ -0,0 +1,96 @@ +From 4ffb879ea648c2b42da4ca992ed3db87e564af69 Mon Sep 17 00:00:00 2001 +From: Peilin Ye +Date: Mon, 27 Jul 2020 10:00:02 +0200 +Subject: media: media/v4l2-core: Fix kernel-infoleak in video_put_user() + +From: Peilin Ye + +commit 4ffb879ea648c2b42da4ca992ed3db87e564af69 upstream. + +video_put_user() is copying uninitialized stack memory to userspace due +to the compiler not initializing holes in the structures declared on the +stack. Fix it by initializing `ev32` and `vb32` using memset(). + +Reported-and-tested-by: syzbot+79d751604cb6f29fbf59@syzkaller.appspotmail.com +Link: https://syzkaller.appspot.com/bug?extid=79d751604cb6f29fbf59 + +Cc: stable@vger.kernel.org +Fixes: 1a6c0b36dd19 ("media: v4l2-core: fix VIDIOC_DQEVENT for time64 ABI") +Fixes: 577c89b0ce72 ("media: v4l2-core: fix v4l2_buffer handling for time64 ABI") +Reviewed-by: Laurent Pinchart +Reviewed-by: Arnd Bergmann +Signed-off-by: Peilin Ye +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/v4l2-core/v4l2-ioctl.c | 50 ++++++++++++++++++----------------- + 1 file changed, 27 insertions(+), 23 deletions(-) + +--- a/drivers/media/v4l2-core/v4l2-ioctl.c ++++ b/drivers/media/v4l2-core/v4l2-ioctl.c +@@ -3186,14 +3186,16 @@ static int video_put_user(void __user *a + #ifdef CONFIG_COMPAT_32BIT_TIME + case VIDIOC_DQEVENT_TIME32: { + struct v4l2_event *ev = parg; +- struct v4l2_event_time32 ev32 = { +- .type = ev->type, +- .pending = ev->pending, +- .sequence = ev->sequence, +- .timestamp.tv_sec = ev->timestamp.tv_sec, +- .timestamp.tv_nsec = ev->timestamp.tv_nsec, +- .id = ev->id, +- }; ++ struct v4l2_event_time32 ev32; ++ ++ memset(&ev32, 0, sizeof(ev32)); ++ ++ ev32.type = ev->type; ++ ev32.pending = ev->pending; ++ ev32.sequence = ev->sequence; ++ ev32.timestamp.tv_sec = ev->timestamp.tv_sec; ++ ev32.timestamp.tv_nsec = ev->timestamp.tv_nsec; ++ ev32.id = ev->id; + + memcpy(&ev32.u, &ev->u, sizeof(ev->u)); + memcpy(&ev32.reserved, &ev->reserved, sizeof(ev->reserved)); +@@ -3207,21 +3209,23 @@ static int video_put_user(void __user *a + case VIDIOC_DQBUF_TIME32: + case VIDIOC_PREPARE_BUF_TIME32: { + struct v4l2_buffer *vb = parg; +- struct v4l2_buffer_time32 vb32 = { +- .index = vb->index, +- .type = vb->type, +- .bytesused = vb->bytesused, +- .flags = vb->flags, +- .field = vb->field, +- .timestamp.tv_sec = vb->timestamp.tv_sec, +- .timestamp.tv_usec = vb->timestamp.tv_usec, +- .timecode = vb->timecode, +- .sequence = vb->sequence, +- .memory = vb->memory, +- .m.userptr = vb->m.userptr, +- .length = vb->length, +- .request_fd = vb->request_fd, +- }; ++ struct v4l2_buffer_time32 vb32; ++ ++ memset(&vb32, 0, sizeof(vb32)); ++ ++ vb32.index = vb->index; ++ vb32.type = vb->type; ++ vb32.bytesused = vb->bytesused; ++ vb32.flags = vb->flags; ++ vb32.field = vb->field; ++ vb32.timestamp.tv_sec = vb->timestamp.tv_sec; ++ vb32.timestamp.tv_usec = vb->timestamp.tv_usec; ++ vb32.timecode = vb->timecode; ++ vb32.sequence = vb->sequence; ++ vb32.memory = vb->memory; ++ vb32.m.userptr = vb->m.userptr; ++ vb32.length = vb->length; ++ vb32.request_fd = vb->request_fd; + + if (copy_to_user(arg, &vb32, sizeof(vb32))) + return -EFAULT; diff --git a/queue-5.8/mm-fix-pin-vs.-gup-mismatch-with-gate-pages.patch b/queue-5.8/mm-fix-pin-vs.-gup-mismatch-with-gate-pages.patch new file mode 100644 index 00000000000..5723cdb840c --- /dev/null +++ b/queue-5.8/mm-fix-pin-vs.-gup-mismatch-with-gate-pages.patch @@ -0,0 +1,82 @@ +From 9fa2dd946743ae6f30dc4830da19147bf100a7f2 Mon Sep 17 00:00:00 2001 +From: Dave Hansen +Date: Thu, 3 Sep 2020 13:40:28 -0700 +Subject: mm: fix pin vs. gup mismatch with gate pages + +From: Dave Hansen + +commit 9fa2dd946743ae6f30dc4830da19147bf100a7f2 upstream. + +Gate pages were missed when converting from get to pin_user_pages(). +This can lead to refcount imbalances. This is reliably and quickly +reproducible running the x86 selftests when vsyscall=emulate is enabled +(the default). Fix by using try_grab_page() with appropriate flags +passed. + +The long story: + +Today, pin_user_pages() and get_user_pages() are similar interfaces for +manipulating page reference counts. However, "pins" use a "bias" value +and manipulate the actual reference count by 1024 instead of 1 used by +plain "gets". + +That means that pin_user_pages() must be matched with unpin_user_pages() +and can't be mixed with a plain put_user_pages() or put_page(). + +Enter gate pages, like the vsyscall page. They are pages usually in the +kernel image, but which are mapped to userspace. Userspace is allowed +access to them, including interfaces using get/pin_user_pages(). The +refcount of these kernel pages is manipulated just like a normal user +page on the get/pin side so that the put/unpin side can work the same +for normal user pages or gate pages. + +get_gate_page() uses try_get_page() which only bumps the refcount by +1, not 1024, even if called in the pin_user_pages() path. If someone +pins a gate page, this happens: + + pin_user_pages() + get_gate_page() + try_get_page() // bump refcount +1 + ... some time later + unpin_user_pages() + page_ref_sub_and_test(page, 1024)) + +... and boom, we get a refcount off by 1023. This is reliably and +quickly reproducible running the x86 selftests when booted with +vsyscall=emulate (the default). The selftests use ptrace(), but I +suspect anything using pin_user_pages() on gate pages could hit this. + +To fix it, simply use try_grab_page() instead of try_get_page(), and +pass 'gup_flags' in so that FOLL_PIN can be respected. + +This bug traces back to the very beginning of the FOLL_PIN support in +commit 3faa52c03f44 ("mm/gup: track FOLL_PIN pages"), which showed up in +the 5.7 release. + +Signed-off-by: Dave Hansen +Fixes: 3faa52c03f44 ("mm/gup: track FOLL_PIN pages") +Reported-by: Peter Zijlstra +Reviewed-by: John Hubbard +Acked-by: Andy Lutomirski +Cc: x86@kernel.org +Cc: Jann Horn +Cc: Andrew Morton +Cc: Kirill A. Shutemov +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/gup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/gup.c ++++ b/mm/gup.c +@@ -843,7 +843,7 @@ static int get_gate_page(struct mm_struc + goto unmap; + *page = pte_page(*pte); + } +- if (unlikely(!try_get_page(*page))) { ++ if (unlikely(!try_grab_page(*page, gup_flags))) { + ret = -ENOMEM; + goto unmap; + } diff --git a/queue-5.8/netfilter-nft_set_rbtree-handle-outcomes-of-tree-rotations-in-overlap-detection.patch b/queue-5.8/netfilter-nft_set_rbtree-handle-outcomes-of-tree-rotations-in-overlap-detection.patch new file mode 100644 index 00000000000..082fda9a533 --- /dev/null +++ b/queue-5.8/netfilter-nft_set_rbtree-handle-outcomes-of-tree-rotations-in-overlap-detection.patch @@ -0,0 +1,139 @@ +From 226a88de473e475cb9f993682a1c7d0c2b451ad8 Mon Sep 17 00:00:00 2001 +From: Stefano Brivio +Date: Wed, 19 Aug 2020 23:59:14 +0200 +Subject: netfilter: nft_set_rbtree: Handle outcomes of tree rotations in overlap detection + +From: Stefano Brivio + +commit 226a88de473e475cb9f993682a1c7d0c2b451ad8 upstream. + +Checks for partial overlaps on insertion assume that end elements +are always descendant nodes of their corresponding start, because +they are inserted later. However, this is not the case if a +previous delete operation caused a tree rotation as part of +rebalancing. + +Taking the issue reported by Andreas Fischer as an example, if we +omit delete operations, the existing procedure works because, +equivalently, we are inserting a start item with value 40 in the +this region of the red-black tree with single-sized intervals: + + overlap flag + 10 (start) + / \ false + 20 (start) + / \ false + 30 (start) + / \ false + 60 (start) + / \ false + 50 (end) + / \ false + 20 (end) + / \ false + 40 (start) + +if we now delete interval 30 - 30, the tree can be rearranged in +a way similar to this (note the rotation involving 50 - 50): + + overlap flag + 10 (start) + / \ false + 20 (start) + / \ false + 25 (start) + / \ false + 70 (start) + / \ false + 50 (end) + / \ true (from rule a1.) + 50 (start) + / \ true + 40 (start) + +and we traverse interval 50 - 50 from the opposite direction +compared to what was expected. + +To deal with those cases, add a start-before-start rule, b4., +that covers traversal of existing intervals from the right. + +We now need to restrict start-after-end rule b3. to cases +where there are no occurring nodes between existing start and +end elements, because addition of rule b4. isn't sufficient to +ensure that the pre-existing end element we encounter while +descending the tree corresponds to a start element of an +interval that we already traversed entirely. + +Different types of overlap detection on trees with rotations +resulting from re-balancing will be covered by nft test case +sets/0044interval_overlap_1. + +Reported-by: Andreas Fischer +Bugzilla: https://bugzilla.netfilter.org/show_bug.cgi?id=1449 +Cc: # 5.6.x +Fixes: 7c84d41416d8 ("netfilter: nft_set_rbtree: Detect partial overlaps on insertion") +Signed-off-by: Stefano Brivio +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nft_set_rbtree.c | 23 ++++++++++++++--------- + 1 file changed, 14 insertions(+), 9 deletions(-) + +--- a/net/netfilter/nft_set_rbtree.c ++++ b/net/netfilter/nft_set_rbtree.c +@@ -238,21 +238,27 @@ static int __nft_rbtree_insert(const str + * + * b1. _ _ __>| !_ _ __| (insert end before existing start) + * b2. _ _ ___| !_ _ _>| (insert end after existing start) +- * b3. _ _ ___! >|_ _ __| (insert start after existing end) ++ * b3. _ _ ___! >|_ _ __| (insert start after existing end, as a leaf) ++ * '--' no nodes falling in this range ++ * b4. >|_ _ ! (insert start before existing start) + * + * Case a3. resolves to b3.: + * - if the inserted start element is the leftmost, because the '0' + * element in the tree serves as end element +- * - otherwise, if an existing end is found. Note that end elements are +- * always inserted after corresponding start elements. ++ * - otherwise, if an existing end is found immediately to the left. If ++ * there are existing nodes in between, we need to further descend the ++ * tree before we can conclude the new start isn't causing an overlap ++ * ++ * or to b4., which, preceded by a3., means we already traversed one or ++ * more existing intervals entirely, from the right. + * + * For a new, rightmost pair of elements, we'll hit cases b3. and b2., + * in that order. + * + * The flag is also cleared in two special cases: + * +- * b4. |__ _ _!|<_ _ _ (insert start right before existing end) +- * b5. |__ _ >|!__ _ _ (insert end right after existing start) ++ * b5. |__ _ _!|<_ _ _ (insert start right before existing end) ++ * b6. |__ _ >|!__ _ _ (insert end right after existing start) + * + * which always happen as last step and imply that no further + * overlapping is possible. +@@ -272,7 +278,7 @@ static int __nft_rbtree_insert(const str + if (nft_rbtree_interval_start(new)) { + if (nft_rbtree_interval_end(rbe) && + nft_set_elem_active(&rbe->ext, genmask) && +- !nft_set_elem_expired(&rbe->ext)) ++ !nft_set_elem_expired(&rbe->ext) && !*p) + overlap = false; + } else { + overlap = nft_rbtree_interval_end(rbe) && +@@ -288,10 +294,9 @@ static int __nft_rbtree_insert(const str + nft_set_elem_active(&rbe->ext, + genmask) && + !nft_set_elem_expired(&rbe->ext); +- } else if (nft_rbtree_interval_end(rbe) && +- nft_set_elem_active(&rbe->ext, genmask) && ++ } else if (nft_set_elem_active(&rbe->ext, genmask) && + !nft_set_elem_expired(&rbe->ext)) { +- overlap = true; ++ overlap = nft_rbtree_interval_end(rbe); + } + } else { + if (nft_rbtree_interval_end(rbe) && diff --git a/queue-5.8/perf-record-stat-explicitly-call-out-event-modifiers-in-the-documentation.patch b/queue-5.8/perf-record-stat-explicitly-call-out-event-modifiers-in-the-documentation.patch new file mode 100644 index 00000000000..0d281bc9270 --- /dev/null +++ b/queue-5.8/perf-record-stat-explicitly-call-out-event-modifiers-in-the-documentation.patch @@ -0,0 +1,63 @@ +From e48a73a312ebf19cc3d72aa74985db25c30757c1 Mon Sep 17 00:00:00 2001 +From: Kim Phillips +Date: Tue, 1 Sep 2020 16:58:53 -0500 +Subject: perf record/stat: Explicitly call out event modifiers in the documentation + +From: Kim Phillips + +commit e48a73a312ebf19cc3d72aa74985db25c30757c1 upstream. + +Event modifiers are not mentioned in the perf record or perf stat +manpages. Add them to orient new users more effectively by pointing +them to the perf list manpage for details. + +Fixes: 2055fdaf8703 ("perf list: Document precise event sampling for AMD IBS") +Signed-off-by: Kim Phillips +Cc: Adrian Hunter +Cc: Alexander Shishkin +Cc: Alexey Budankov +Cc: Ian Rogers +Cc: Jin Yao +Cc: Jiri Olsa +Cc: Mark Rutland +Cc: Namhyung Kim +Cc: Paul Clarke +Cc: Peter Zijlstra +Cc: Stephane Eranian +Cc: Tony Jones +Cc: stable@vger.kernel.org +Link: http://lore.kernel.org/lkml/20200901215853.276234-1-kim.phillips@amd.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Greg Kroah-Hartman + +--- + tools/perf/Documentation/perf-record.txt | 4 ++++ + tools/perf/Documentation/perf-stat.txt | 4 ++++ + 2 files changed, 8 insertions(+) + +--- a/tools/perf/Documentation/perf-record.txt ++++ b/tools/perf/Documentation/perf-record.txt +@@ -33,6 +33,10 @@ OPTIONS + - a raw PMU event (eventsel+umask) in the form of rNNN where NNN is a + hexadecimal event descriptor. + ++ - a symbolic or raw PMU event followed by an optional colon ++ and a list of event modifiers, e.g., cpu-cycles:p. See the ++ linkperf:perf-list[1] man page for details on event modifiers. ++ + - a symbolically formed PMU event like 'pmu/param1=0x3,param2/' where + 'param1', 'param2', etc are defined as formats for the PMU in + /sys/bus/event_source/devices//format/*. +--- a/tools/perf/Documentation/perf-stat.txt ++++ b/tools/perf/Documentation/perf-stat.txt +@@ -39,6 +39,10 @@ report:: + - a raw PMU event (eventsel+umask) in the form of rNNN where NNN is a + hexadecimal event descriptor. + ++ - a symbolic or raw PMU event followed by an optional colon ++ and a list of event modifiers, e.g., cpu-cycles:p. See the ++ linkperf:perf-list[1] man page for details on event modifiers. ++ + - a symbolically formed event like 'pmu/param1=0x3,param2/' where + param1 and param2 are defined as formats for the PMU in + /sys/bus/event_source/devices//format/* diff --git a/queue-5.8/selftests-x86-test_vsyscall-improve-the-process_vm_readv-test.patch b/queue-5.8/selftests-x86-test_vsyscall-improve-the-process_vm_readv-test.patch new file mode 100644 index 00000000000..9e9c815cc9f --- /dev/null +++ b/queue-5.8/selftests-x86-test_vsyscall-improve-the-process_vm_readv-test.patch @@ -0,0 +1,75 @@ +From 8891adc61dce2a8a41fc0c23262b681c3ec4b73a Mon Sep 17 00:00:00 2001 +From: Andy Lutomirski +Date: Thu, 3 Sep 2020 13:40:30 -0700 +Subject: selftests/x86/test_vsyscall: Improve the process_vm_readv() test + +From: Andy Lutomirski + +commit 8891adc61dce2a8a41fc0c23262b681c3ec4b73a upstream. + +The existing code accepted process_vm_readv() success or failure as long +as it didn't return garbage. This is too weak: if the vsyscall page is +readable, then process_vm_readv() should succeed and, if the page is not +readable, then it should fail. + +Signed-off-by: Andy Lutomirski +Signed-off-by: Dave Hansen +Cc: x86@kernel.org +Cc: Peter Zijlstra +Cc: Andy Lutomirski +Cc: Jann Horn +Cc: John Hubbard +Cc: Andrew Morton +Cc: Kirill A. Shutemov +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + tools/testing/selftests/x86/test_vsyscall.c | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +--- a/tools/testing/selftests/x86/test_vsyscall.c ++++ b/tools/testing/selftests/x86/test_vsyscall.c +@@ -462,6 +462,17 @@ static int test_vsys_x(void) + return 0; + } + ++/* ++ * Debuggers expect ptrace() to be able to peek at the vsyscall page. ++ * Use process_vm_readv() as a proxy for ptrace() to test this. We ++ * want it to work in the vsyscall=emulate case and to fail in the ++ * vsyscall=xonly case. ++ * ++ * It's worth noting that this ABI is a bit nutty. write(2) can't ++ * read from the vsyscall page on any kernel version or mode. The ++ * fact that ptrace() ever worked was a nice courtesy of old kernels, ++ * but the code to support it is fairly gross. ++ */ + static int test_process_vm_readv(void) + { + #ifdef __x86_64__ +@@ -477,8 +488,12 @@ static int test_process_vm_readv(void) + remote.iov_len = 4096; + ret = process_vm_readv(getpid(), &local, 1, &remote, 1, 0); + if (ret != 4096) { +- printf("[OK]\tprocess_vm_readv() failed (ret = %d, errno = %d)\n", ret, errno); +- return 0; ++ /* ++ * We expect process_vm_readv() to work if and only if the ++ * vsyscall page is readable. ++ */ ++ printf("[%s]\tprocess_vm_readv() failed (ret = %d, errno = %d)\n", vsyscall_map_r ? "FAIL" : "OK", ret, errno); ++ return vsyscall_map_r ? 1 : 0; + } + + if (vsyscall_map_r) { +@@ -488,6 +503,9 @@ static int test_process_vm_readv(void) + printf("[FAIL]\tIt worked but returned incorrect data\n"); + return 1; + } ++ } else { ++ printf("[FAIL]\tprocess_rm_readv() succeeded, but it should have failed in this configuration\n"); ++ return 1; + } + #endif + diff --git a/queue-5.8/series b/queue-5.8/series index 291c582dfe4..5afbbab9818 100644 --- a/queue-5.8/series +++ b/queue-5.8/series @@ -4,3 +4,6 @@ netfilter-nft_set_rbtree-handle-outcomes-of-tree-rotations-in-overlap-detection. mm-fix-pin-vs.-gup-mismatch-with-gate-pages.patch selftests-x86-test_vsyscall-improve-the-process_vm_readv-test.patch perf-record-stat-explicitly-call-out-event-modifiers-in-the-documentation.patch +media-media-v4l2-core-fix-kernel-infoleak-in-video_put_user.patch +kvm-arm64-add-kvm_extable-for-vaxorcism-code.patch +kvm-arm64-survive-synchronous-exceptions-caused-by-at-instructions.patch