From: Greg Kroah-Hartman Date: Tue, 1 Oct 2024 10:28:05 +0000 (+0200) Subject: 4.19-stable patches X-Git-Tag: v6.6.54~77 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c5faa2c35d1c0f4d0915f91571092c32ce7bdfdd;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: firmware_loader-block-path-traversal.patch tty-rp2-fix-reset-with-non-forgiving-pcie-host-bridges.patch usb-appledisplay-close-race-between-probe-and-completion-handler.patch usb-misc-cypress_cy7c63-check-for-short-transfer.patch --- diff --git a/queue-4.19/firmware_loader-block-path-traversal.patch b/queue-4.19/firmware_loader-block-path-traversal.patch new file mode 100644 index 00000000000..c37b5d4a4e1 --- /dev/null +++ b/queue-4.19/firmware_loader-block-path-traversal.patch @@ -0,0 +1,106 @@ +From f0e5311aa8022107d63c54e2f03684ec097d1394 Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Wed, 28 Aug 2024 01:45:48 +0200 +Subject: firmware_loader: Block path traversal + +From: Jann Horn + +commit f0e5311aa8022107d63c54e2f03684ec097d1394 upstream. + +Most firmware names are hardcoded strings, or are constructed from fairly +constrained format strings where the dynamic parts are just some hex +numbers or such. + +However, there are a couple codepaths in the kernel where firmware file +names contain string components that are passed through from a device or +semi-privileged userspace; the ones I could find (not counting interfaces +that require root privileges) are: + + - lpfc_sli4_request_firmware_update() seems to construct the firmware + filename from "ModelName", a string that was previously parsed out of + some descriptor ("Vital Product Data") in lpfc_fill_vpd() + - nfp_net_fw_find() seems to construct a firmware filename from a model + name coming from nfp_hwinfo_lookup(pf->hwinfo, "nffw.partno"), which I + think parses some descriptor that was read from the device. + (But this case likely isn't exploitable because the format string looks + like "netronome/nic_%s", and there shouldn't be any *folders* starting + with "netronome/nic_". The previous case was different because there, + the "%s" is *at the start* of the format string.) + - module_flash_fw_schedule() is reachable from the + ETHTOOL_MSG_MODULE_FW_FLASH_ACT netlink command, which is marked as + GENL_UNS_ADMIN_PERM (meaning CAP_NET_ADMIN inside a user namespace is + enough to pass the privilege check), and takes a userspace-provided + firmware name. + (But I think to reach this case, you need to have CAP_NET_ADMIN over a + network namespace that a special kind of ethernet device is mapped into, + so I think this is not a viable attack path in practice.) + +Fix it by rejecting any firmware names containing ".." path components. + +For what it's worth, I went looking and haven't found any USB device +drivers that use the firmware loader dangerously. + +Cc: stable@vger.kernel.org +Reviewed-by: Danilo Krummrich +Fixes: abb139e75c2c ("firmware: teach the kernel to load firmware files directly from the filesystem") +Signed-off-by: Jann Horn +Acked-by: Luis Chamberlain +Link: https://lore.kernel.org/r/20240828-firmware-traversal-v3-1-c76529c63b5f@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/base/firmware_loader/main.c | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +--- a/drivers/base/firmware_loader/main.c ++++ b/drivers/base/firmware_loader/main.c +@@ -565,6 +565,26 @@ static void fw_abort_batch_reqs(struct f + mutex_unlock(&fw_lock); + } + ++/* ++ * Reject firmware file names with ".." path components. ++ * There are drivers that construct firmware file names from device-supplied ++ * strings, and we don't want some device to be able to tell us "I would like to ++ * be sent my firmware from ../../../etc/shadow, please". ++ * ++ * Search for ".." surrounded by either '/' or start/end of string. ++ * ++ * This intentionally only looks at the firmware name, not at the firmware base ++ * directory or at symlink contents. ++ */ ++static bool name_contains_dotdot(const char *name) ++{ ++ size_t name_len = strlen(name); ++ ++ return strcmp(name, "..") == 0 || strncmp(name, "../", 3) == 0 || ++ strstr(name, "/../") != NULL || ++ (name_len >= 3 && strcmp(name+name_len-3, "/..") == 0); ++} ++ + /* called from request_firmware() and request_firmware_work_func() */ + static int + _request_firmware(const struct firmware **firmware_p, const char *name, +@@ -582,6 +602,14 @@ _request_firmware(const struct firmware + goto out; + } + ++ if (name_contains_dotdot(name)) { ++ dev_warn(device, ++ "Firmware load for '%s' refused, path contains '..' component\n", ++ name); ++ ret = -EINVAL; ++ goto out; ++ } ++ + ret = _request_firmware_prepare(&fw, name, device, buf, size, + opt_flags); + if (ret <= 0) /* error or already assigned */ +@@ -622,6 +650,8 @@ _request_firmware(const struct firmware + * @name will be used as $FIRMWARE in the uevent environment and + * should be distinctive enough not to be confused with any other + * firmware image for this or any other device. ++ * It must not contain any ".." path components - "foo/bar..bin" is ++ * allowed, but "foo/../bar.bin" is not. + * + * Caller must hold the reference count of @device. + * diff --git a/queue-4.19/series b/queue-4.19/series index 1af868ed390..d68c4d6b829 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -112,3 +112,7 @@ netfilter-ctnetlink-compile-ctnetlink_label_size-wit.patch crypto-aead-cipher-zeroize-key-buffer-after-use.patch remove-.orig-pattern-from-.gitignore.patch soc-versatile-integrator-fix-of-node-leak-in-probe-error-path.patch +usb-appledisplay-close-race-between-probe-and-completion-handler.patch +usb-misc-cypress_cy7c63-check-for-short-transfer.patch +firmware_loader-block-path-traversal.patch +tty-rp2-fix-reset-with-non-forgiving-pcie-host-bridges.patch diff --git a/queue-4.19/tty-rp2-fix-reset-with-non-forgiving-pcie-host-bridges.patch b/queue-4.19/tty-rp2-fix-reset-with-non-forgiving-pcie-host-bridges.patch new file mode 100644 index 00000000000..c6eb679d45b --- /dev/null +++ b/queue-4.19/tty-rp2-fix-reset-with-non-forgiving-pcie-host-bridges.patch @@ -0,0 +1,44 @@ +From f16dd10ba342c429b1e36ada545fb36d4d1f0e63 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli +Date: Fri, 6 Sep 2024 15:54:33 -0700 +Subject: tty: rp2: Fix reset with non forgiving PCIe host bridges + +From: Florian Fainelli + +commit f16dd10ba342c429b1e36ada545fb36d4d1f0e63 upstream. + +The write to RP2_GLOBAL_CMD followed by an immediate read of +RP2_GLOBAL_CMD in rp2_reset_asic() is intented to flush out the write, +however by then the device is already in reset and cannot respond to a +memory cycle access. + +On platforms such as the Raspberry Pi 4 and others using the +pcie-brcmstb.c driver, any memory access to a device that cannot respond +is met with a fatal system error, rather than being substituted with all +1s as is usually the case on PC platforms. + +Swapping the delay and the read ensures that the device has finished +resetting before we attempt to read from it. + +Fixes: 7d9f49afa451 ("serial: rp2: New driver for Comtrol RocketPort 2 cards") +Cc: stable +Suggested-by: Jim Quinlan +Signed-off-by: Florian Fainelli +Link: https://lore.kernel.org/r/20240906225435.707837-1-florian.fainelli@broadcom.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/rp2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/tty/serial/rp2.c ++++ b/drivers/tty/serial/rp2.c +@@ -600,8 +600,8 @@ static void rp2_reset_asic(struct rp2_ca + u32 clk_cfg; + + writew(1, base + RP2_GLOBAL_CMD); +- readw(base + RP2_GLOBAL_CMD); + msleep(100); ++ readw(base + RP2_GLOBAL_CMD); + writel(0, base + RP2_CLK_PRESCALER); + + /* TDM clock configuration */ diff --git a/queue-4.19/usb-appledisplay-close-race-between-probe-and-completion-handler.patch b/queue-4.19/usb-appledisplay-close-race-between-probe-and-completion-handler.patch new file mode 100644 index 00000000000..21966c51c02 --- /dev/null +++ b/queue-4.19/usb-appledisplay-close-race-between-probe-and-completion-handler.patch @@ -0,0 +1,66 @@ +From 8265d06b7794493d82c5c21a12d7ba43eccc30cb Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Thu, 12 Sep 2024 14:32:59 +0200 +Subject: USB: appledisplay: close race between probe and completion handler + +From: Oliver Neukum + +commit 8265d06b7794493d82c5c21a12d7ba43eccc30cb upstream. + +There is a small window during probing when IO is running +but the backlight is not registered. Processing events +during that time will crash. The completion handler +needs to check for a backlight before scheduling work. + +The bug is as old as the driver. + +Signed-off-by: Oliver Neukum +CC: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240912123317.1026049-1-oneukum@suse.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/misc/appledisplay.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +--- a/drivers/usb/misc/appledisplay.c ++++ b/drivers/usb/misc/appledisplay.c +@@ -111,7 +111,12 @@ static void appledisplay_complete(struct + case ACD_BTN_BRIGHT_UP: + case ACD_BTN_BRIGHT_DOWN: + pdata->button_pressed = 1; +- schedule_delayed_work(&pdata->work, 0); ++ /* ++ * there is a window during which no device ++ * is registered ++ */ ++ if (pdata->bd ) ++ schedule_delayed_work(&pdata->work, 0); + break; + case ACD_BTN_NONE: + default: +@@ -208,6 +213,7 @@ static int appledisplay_probe(struct usb + const struct usb_device_id *id) + { + struct backlight_properties props; ++ struct backlight_device *backlight; + struct appledisplay *pdata; + struct usb_device *udev = interface_to_usbdev(iface); + struct usb_endpoint_descriptor *endpoint; +@@ -278,13 +284,14 @@ static int appledisplay_probe(struct usb + memset(&props, 0, sizeof(struct backlight_properties)); + props.type = BACKLIGHT_RAW; + props.max_brightness = 0xff; +- pdata->bd = backlight_device_register(bl_name, NULL, pdata, ++ backlight = backlight_device_register(bl_name, NULL, pdata, + &appledisplay_bl_data, &props); +- if (IS_ERR(pdata->bd)) { ++ if (IS_ERR(backlight)) { + dev_err(&iface->dev, "Backlight registration failed\n"); +- retval = PTR_ERR(pdata->bd); ++ retval = PTR_ERR(backlight); + goto error; + } ++ pdata->bd = backlight; + + /* Try to get brightness */ + brightness = appledisplay_bl_get_brightness(pdata->bd); diff --git a/queue-4.19/usb-misc-cypress_cy7c63-check-for-short-transfer.patch b/queue-4.19/usb-misc-cypress_cy7c63-check-for-short-transfer.patch new file mode 100644 index 00000000000..5a3754bcb5f --- /dev/null +++ b/queue-4.19/usb-misc-cypress_cy7c63-check-for-short-transfer.patch @@ -0,0 +1,42 @@ +From 49cd2f4d747eeb3050b76245a7f72aa99dbd3310 Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Thu, 12 Sep 2024 14:54:43 +0200 +Subject: USB: misc: cypress_cy7c63: check for short transfer + +From: Oliver Neukum + +commit 49cd2f4d747eeb3050b76245a7f72aa99dbd3310 upstream. + +As we process the second byte of a control transfer, transfers +of less than 2 bytes must be discarded. + +This bug is as old as the driver. + +SIgned-off-by: Oliver Neukum +CC: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240912125449.1030536-1-oneukum@suse.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/misc/cypress_cy7c63.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/misc/cypress_cy7c63.c ++++ b/drivers/usb/misc/cypress_cy7c63.c +@@ -88,6 +88,9 @@ static int vendor_command(struct cypress + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER, + address, data, iobuf, CYPRESS_MAX_REQSIZE, + USB_CTRL_GET_TIMEOUT); ++ /* we must not process garbage */ ++ if (retval < 2) ++ goto err_buf; + + /* store returned data (more READs to be added) */ + switch (request) { +@@ -107,6 +110,7 @@ static int vendor_command(struct cypress + break; + } + ++err_buf: + kfree(iobuf); + error: + return retval;