From: Greg Kroah-Hartman Date: Mon, 26 Jul 2021 08:31:35 +0000 (+0200) Subject: 4.14-stable patches X-Git-Tag: v4.4.277~61 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=264bad7570d0928c4817936d28b63e7493ffb0ed;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: kvm-ppc-book3s-fix-h_rtas-rets-buffer-overflow.patch usb-hub-disable-usb-3-device-initiated-lpm-if-exit-latency-is-too-high.patch --- diff --git a/queue-4.14/kvm-ppc-book3s-fix-h_rtas-rets-buffer-overflow.patch b/queue-4.14/kvm-ppc-book3s-fix-h_rtas-rets-buffer-overflow.patch new file mode 100644 index 00000000000..e9402924e99 --- /dev/null +++ b/queue-4.14/kvm-ppc-book3s-fix-h_rtas-rets-buffer-overflow.patch @@ -0,0 +1,75 @@ +From f62f3c20647ebd5fb6ecb8f0b477b9281c44c10a Mon Sep 17 00:00:00 2001 +From: Nicholas Piggin +Date: Tue, 20 Jul 2021 20:43:09 +1000 +Subject: KVM: PPC: Book3S: Fix H_RTAS rets buffer overflow + +From: Nicholas Piggin + +commit f62f3c20647ebd5fb6ecb8f0b477b9281c44c10a upstream. + +The kvmppc_rtas_hcall() sets the host rtas_args.rets pointer based on +the rtas_args.nargs that was provided by the guest. That guest nargs +value is not range checked, so the guest can cause the host rets pointer +to be pointed outside the args array. The individual rtas function +handlers check the nargs and nrets values to ensure they are correct, +but if they are not, the handlers store a -3 (0xfffffffd) failure +indication in rets[0] which corrupts host memory. + +Fix this by testing up front whether the guest supplied nargs and nret +would exceed the array size, and fail the hcall directly without storing +a failure indication to rets[0]. + +Also expand on a comment about why we kill the guest and try not to +return errors directly if we have a valid rets[0] pointer. + +Fixes: 8e591cb72047 ("KVM: PPC: Book3S: Add infrastructure to implement kernel-side RTAS calls") +Cc: stable@vger.kernel.org # v3.10+ +Reported-by: Alexey Kardashevskiy +Signed-off-by: Nicholas Piggin +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/kvm/book3s_rtas.c | 25 ++++++++++++++++++++++--- + 1 file changed, 22 insertions(+), 3 deletions(-) + +--- a/arch/powerpc/kvm/book3s_rtas.c ++++ b/arch/powerpc/kvm/book3s_rtas.c +@@ -243,6 +243,17 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *v + * value so we can restore it on the way out. + */ + orig_rets = args.rets; ++ if (be32_to_cpu(args.nargs) >= ARRAY_SIZE(args.args)) { ++ /* ++ * Don't overflow our args array: ensure there is room for ++ * at least rets[0] (even if the call specifies 0 nret). ++ * ++ * Each handler must then check for the correct nargs and nret ++ * values, but they may always return failure in rets[0]. ++ */ ++ rc = -EINVAL; ++ goto fail; ++ } + args.rets = &args.args[be32_to_cpu(args.nargs)]; + + mutex_lock(&vcpu->kvm->arch.rtas_token_lock); +@@ -270,9 +281,17 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *v + fail: + /* + * We only get here if the guest has called RTAS with a bogus +- * args pointer. That means we can't get to the args, and so we +- * can't fail the RTAS call. So fail right out to userspace, +- * which should kill the guest. ++ * args pointer or nargs/nret values that would overflow the ++ * array. That means we can't get to the args, and so we can't ++ * fail the RTAS call. So fail right out to userspace, which ++ * should kill the guest. ++ * ++ * SLOF should actually pass the hcall return value from the ++ * rtas handler call in r3, so enter_rtas could be modified to ++ * return a failure indication in r3 and we could return such ++ * errors to the guest rather than failing to host userspace. ++ * However old guests that don't test for failure could then ++ * continue silently after errors, so for now we won't do this. + */ + return rc; + } diff --git a/queue-4.14/series b/queue-4.14/series index aced57370b8..ec2fcb0d68c 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -60,3 +60,5 @@ revert-mips-add-pmd-table-accounting-into-mips-pmd_alloc_one.patch s390-ftrace-fix-ftrace_update_ftrace_func-implementation.patch alsa-sb-fix-potential-abba-deadlock-in-csp-driver.patch xhci-fix-lost-usb-2-remote-wake.patch +kvm-ppc-book3s-fix-h_rtas-rets-buffer-overflow.patch +usb-hub-disable-usb-3-device-initiated-lpm-if-exit-latency-is-too-high.patch diff --git a/queue-4.14/usb-hub-disable-usb-3-device-initiated-lpm-if-exit-latency-is-too-high.patch b/queue-4.14/usb-hub-disable-usb-3-device-initiated-lpm-if-exit-latency-is-too-high.patch new file mode 100644 index 00000000000..c8b6547682a --- /dev/null +++ b/queue-4.14/usb-hub-disable-usb-3-device-initiated-lpm-if-exit-latency-is-too-high.patch @@ -0,0 +1,119 @@ +From 1b7f56fbc7a1b66967b6114d1b5f5a257c3abae6 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Thu, 15 Jul 2021 18:01:22 +0300 +Subject: usb: hub: Disable USB 3 device initiated lpm if exit latency is too high + +From: Mathias Nyman + +commit 1b7f56fbc7a1b66967b6114d1b5f5a257c3abae6 upstream. + +The device initiated link power management U1/U2 states should not be +enabled in case the system exit latency plus one bus interval (125us) is +greater than the shortest service interval of any periodic endpoint. + +This is the case for both U1 and U2 sytstem exit latencies and link states. + +See USB 3.2 section 9.4.9 "Set Feature" for more details + +Note, before this patch the host and device initiated U1/U2 lpm states +were both enabled with lpm. After this patch it's possible to end up with +only host inititated U1/U2 lpm in case the exit latencies won't allow +device initiated lpm. + +If this case we still want to set the udev->usb3_lpm_ux_enabled flag so +that sysfs users can see the link may go to U1/U2. + +Signed-off-by: Mathias Nyman +Cc: stable +Link: https://lore.kernel.org/r/20210715150122.1995966-2-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/hub.c | 68 ++++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 56 insertions(+), 12 deletions(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -3904,6 +3904,47 @@ static int usb_set_lpm_timeout(struct us + } + + /* ++ * Don't allow device intiated U1/U2 if the system exit latency + one bus ++ * interval is greater than the minimum service interval of any active ++ * periodic endpoint. See USB 3.2 section 9.4.9 ++ */ ++static bool usb_device_may_initiate_lpm(struct usb_device *udev, ++ enum usb3_link_state state) ++{ ++ unsigned int sel; /* us */ ++ int i, j; ++ ++ if (state == USB3_LPM_U1) ++ sel = DIV_ROUND_UP(udev->u1_params.sel, 1000); ++ else if (state == USB3_LPM_U2) ++ sel = DIV_ROUND_UP(udev->u2_params.sel, 1000); ++ else ++ return false; ++ ++ for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { ++ struct usb_interface *intf; ++ struct usb_endpoint_descriptor *desc; ++ unsigned int interval; ++ ++ intf = udev->actconfig->interface[i]; ++ if (!intf) ++ continue; ++ ++ for (j = 0; j < intf->cur_altsetting->desc.bNumEndpoints; j++) { ++ desc = &intf->cur_altsetting->endpoint[j].desc; ++ ++ if (usb_endpoint_xfer_int(desc) || ++ usb_endpoint_xfer_isoc(desc)) { ++ interval = (1 << (desc->bInterval - 1)) * 125; ++ if (sel + 125 > interval) ++ return false; ++ } ++ } ++ } ++ return true; ++} ++ ++/* + * Enable the hub-initiated U1/U2 idle timeouts, and enable device-initiated + * U1/U2 entry. + * +@@ -3975,20 +4016,23 @@ static void usb_enable_link_state(struct + * U1/U2_ENABLE + */ + if (udev->actconfig && +- usb_set_device_initiated_lpm(udev, state, true) == 0) { +- if (state == USB3_LPM_U1) +- udev->usb3_lpm_u1_enabled = 1; +- else if (state == USB3_LPM_U2) +- udev->usb3_lpm_u2_enabled = 1; +- } else { +- /* Don't request U1/U2 entry if the device +- * cannot transition to U1/U2. +- */ +- usb_set_lpm_timeout(udev, state, 0); +- hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state); ++ usb_device_may_initiate_lpm(udev, state)) { ++ if (usb_set_device_initiated_lpm(udev, state, true)) { ++ /* ++ * Request to enable device initiated U1/U2 failed, ++ * better to turn off lpm in this case. ++ */ ++ usb_set_lpm_timeout(udev, state, 0); ++ hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state); ++ return; ++ } + } +-} + ++ if (state == USB3_LPM_U1) ++ udev->usb3_lpm_u1_enabled = 1; ++ else if (state == USB3_LPM_U2) ++ udev->usb3_lpm_u2_enabled = 1; ++} + /* + * Disable the hub-initiated U1/U2 idle timeouts, and disable device-initiated + * U1/U2 entry.