From: Sasha Levin Date: Sun, 15 Jan 2023 23:59:01 +0000 (-0500) Subject: Fixes for 4.14 X-Git-Tag: v4.14.303~35 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f9508fe33491597cedab54ea6cf16a8243dd58dd;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 4.14 Signed-off-by: Sasha Levin --- diff --git a/queue-4.14/hvc-xen-lock-console-list-traversal.patch b/queue-4.14/hvc-xen-lock-console-list-traversal.patch new file mode 100644 index 00000000000..fbd07957857 --- /dev/null +++ b/queue-4.14/hvc-xen-lock-console-list-traversal.patch @@ -0,0 +1,186 @@ +From e072b2b4a99a33c7086fb7a21e01d26a2a402a82 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Nov 2022 17:36:02 +0100 +Subject: hvc/xen: lock console list traversal +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Roger Pau Monne + +[ Upstream commit c0dccad87cf68fc6012aec7567e354353097ec1a ] + +The currently lockless access to the xen console list in +vtermno_to_xencons() is incorrect, as additions and removals from the +list can happen anytime, and as such the traversal of the list to get +the private console data for a given termno needs to happen with the +lock held. Note users that modify the list already do so with the +lock taken. + +Adjust current lock takers to use the _irq{save,restore} helpers, +since the context in which vtermno_to_xencons() is called can have +interrupts disabled. Use the _irq{save,restore} set of helpers to +switch the current callers to disable interrupts in the locked region. +I haven't checked if existing users could instead use the _irq +variant, as I think it's safer to use _irq{save,restore} upfront. + +While there switch from using list_for_each_entry_safe to +list_for_each_entry: the current entry cursor won't be removed as +part of the code in the loop body, so using the _safe variant is +pointless. + +Fixes: 02e19f9c7cac ('hvc_xen: implement multiconsole support') +Signed-off-by: Roger Pau Monné +Reviewed-by: Stefano Stabellini +Link: https://lore.kernel.org/r/20221130163611.14686-1-roger.pau@citrix.com +Signed-off-by: Juergen Gross +Signed-off-by: Sasha Levin +--- + drivers/tty/hvc/hvc_xen.c | 46 ++++++++++++++++++++++++--------------- + 1 file changed, 29 insertions(+), 17 deletions(-) + +diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c +index 2af089b2a343..625b5660b05f 100644 +--- a/drivers/tty/hvc/hvc_xen.c ++++ b/drivers/tty/hvc/hvc_xen.c +@@ -65,17 +65,22 @@ static DEFINE_SPINLOCK(xencons_lock); + + static struct xencons_info *vtermno_to_xencons(int vtermno) + { +- struct xencons_info *entry, *n, *ret = NULL; ++ struct xencons_info *entry, *ret = NULL; ++ unsigned long flags; + +- if (list_empty(&xenconsoles)) +- return NULL; ++ spin_lock_irqsave(&xencons_lock, flags); ++ if (list_empty(&xenconsoles)) { ++ spin_unlock_irqrestore(&xencons_lock, flags); ++ return NULL; ++ } + +- list_for_each_entry_safe(entry, n, &xenconsoles, list) { ++ list_for_each_entry(entry, &xenconsoles, list) { + if (entry->vtermno == vtermno) { + ret = entry; + break; + } + } ++ spin_unlock_irqrestore(&xencons_lock, flags); + + return ret; + } +@@ -236,7 +241,7 @@ static int xen_hvm_console_init(void) + { + int r; + uint64_t v = 0; +- unsigned long gfn; ++ unsigned long gfn, flags; + struct xencons_info *info; + + if (!xen_hvm_domain()) +@@ -271,9 +276,9 @@ static int xen_hvm_console_init(void) + goto err; + info->vtermno = HVC_COOKIE; + +- spin_lock(&xencons_lock); ++ spin_lock_irqsave(&xencons_lock, flags); + list_add_tail(&info->list, &xenconsoles); +- spin_unlock(&xencons_lock); ++ spin_unlock_irqrestore(&xencons_lock, flags); + + return 0; + err: +@@ -296,6 +301,7 @@ static int xencons_info_pv_init(struct xencons_info *info, int vtermno) + static int xen_pv_console_init(void) + { + struct xencons_info *info; ++ unsigned long flags; + + if (!xen_pv_domain()) + return -ENODEV; +@@ -312,9 +318,9 @@ static int xen_pv_console_init(void) + /* already configured */ + return 0; + } +- spin_lock(&xencons_lock); ++ spin_lock_irqsave(&xencons_lock, flags); + xencons_info_pv_init(info, HVC_COOKIE); +- spin_unlock(&xencons_lock); ++ spin_unlock_irqrestore(&xencons_lock, flags); + + return 0; + } +@@ -322,6 +328,7 @@ static int xen_pv_console_init(void) + static int xen_initial_domain_console_init(void) + { + struct xencons_info *info; ++ unsigned long flags; + + if (!xen_initial_domain()) + return -ENODEV; +@@ -336,9 +343,9 @@ static int xen_initial_domain_console_init(void) + info->irq = bind_virq_to_irq(VIRQ_CONSOLE, 0, false); + info->vtermno = HVC_COOKIE; + +- spin_lock(&xencons_lock); ++ spin_lock_irqsave(&xencons_lock, flags); + list_add_tail(&info->list, &xenconsoles); +- spin_unlock(&xencons_lock); ++ spin_unlock_irqrestore(&xencons_lock, flags); + + return 0; + } +@@ -393,10 +400,12 @@ static void xencons_free(struct xencons_info *info) + + static int xen_console_remove(struct xencons_info *info) + { ++ unsigned long flags; ++ + xencons_disconnect_backend(info); +- spin_lock(&xencons_lock); ++ spin_lock_irqsave(&xencons_lock, flags); + list_del(&info->list); +- spin_unlock(&xencons_lock); ++ spin_unlock_irqrestore(&xencons_lock, flags); + if (info->xbdev != NULL) + xencons_free(info); + else { +@@ -477,6 +486,7 @@ static int xencons_probe(struct xenbus_device *dev, + { + int ret, devid; + struct xencons_info *info; ++ unsigned long flags; + + devid = dev->nodename[strlen(dev->nodename) - 1] - '0'; + if (devid == 0) +@@ -495,9 +505,9 @@ static int xencons_probe(struct xenbus_device *dev, + ret = xencons_connect_backend(dev, info); + if (ret < 0) + goto error; +- spin_lock(&xencons_lock); ++ spin_lock_irqsave(&xencons_lock, flags); + list_add_tail(&info->list, &xenconsoles); +- spin_unlock(&xencons_lock); ++ spin_unlock_irqrestore(&xencons_lock, flags); + + return 0; + +@@ -596,10 +606,12 @@ static int __init xen_hvc_init(void) + + info->hvc = hvc_alloc(HVC_COOKIE, info->irq, ops, 256); + if (IS_ERR(info->hvc)) { ++ unsigned long flags; ++ + r = PTR_ERR(info->hvc); +- spin_lock(&xencons_lock); ++ spin_lock_irqsave(&xencons_lock, flags); + list_del(&info->list); +- spin_unlock(&xencons_lock); ++ spin_unlock_irqrestore(&xencons_lock, flags); + if (info->irq) + unbind_from_irqhandler(info->irq, NULL); + kfree(info); +-- +2.35.1 + diff --git a/queue-4.14/nfc-pn533-wait-for-out_urb-s-completion-in-pn533_usb.patch b/queue-4.14/nfc-pn533-wait-for-out_urb-s-completion-in-pn533_usb.patch new file mode 100644 index 00000000000..d11ea20ed1e --- /dev/null +++ b/queue-4.14/nfc-pn533-wait-for-out_urb-s-completion-in-pn533_usb.patch @@ -0,0 +1,129 @@ +From 6dcc32c9ada6194d35a8e10dd33ba3353a735918 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Jan 2023 17:23:44 +0900 +Subject: nfc: pn533: Wait for out_urb's completion in pn533_usb_send_frame() + +From: Minsuk Kang + +[ Upstream commit 9dab880d675b9d0dd56c6428e4e8352a3339371d ] + +Fix a use-after-free that occurs in hcd when in_urb sent from +pn533_usb_send_frame() is completed earlier than out_urb. Its callback +frees the skb data in pn533_send_async_complete() that is used as a +transfer buffer of out_urb. Wait before sending in_urb until the +callback of out_urb is called. To modify the callback of out_urb alone, +separate the complete function of out_urb and ack_urb. + +Found by a modified version of syzkaller. + +BUG: KASAN: use-after-free in dummy_timer +Call Trace: + memcpy (mm/kasan/shadow.c:65) + dummy_perform_transfer (drivers/usb/gadget/udc/dummy_hcd.c:1352) + transfer (drivers/usb/gadget/udc/dummy_hcd.c:1453) + dummy_timer (drivers/usb/gadget/udc/dummy_hcd.c:1972) + arch_static_branch (arch/x86/include/asm/jump_label.h:27) + static_key_false (include/linux/jump_label.h:207) + timer_expire_exit (include/trace/events/timer.h:127) + call_timer_fn (kernel/time/timer.c:1475) + expire_timers (kernel/time/timer.c:1519) + __run_timers (kernel/time/timer.c:1790) + run_timer_softirq (kernel/time/timer.c:1803) + +Fixes: c46ee38620a2 ("NFC: pn533: add NXP pn533 nfc device driver") +Signed-off-by: Minsuk Kang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/nfc/pn533/usb.c | 44 ++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 41 insertions(+), 3 deletions(-) + +diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c +index a2c9b3f3bc23..c7da364b6358 100644 +--- a/drivers/nfc/pn533/usb.c ++++ b/drivers/nfc/pn533/usb.c +@@ -165,10 +165,17 @@ static int pn533_usb_send_ack(struct pn533 *dev, gfp_t flags) + return usb_submit_urb(phy->ack_urb, flags); + } + ++struct pn533_out_arg { ++ struct pn533_usb_phy *phy; ++ struct completion done; ++}; ++ + static int pn533_usb_send_frame(struct pn533 *dev, + struct sk_buff *out) + { + struct pn533_usb_phy *phy = dev->phy; ++ struct pn533_out_arg arg; ++ void *cntx; + int rc; + + if (phy->priv == NULL) +@@ -180,10 +187,17 @@ static int pn533_usb_send_frame(struct pn533 *dev, + print_hex_dump_debug("PN533 TX: ", DUMP_PREFIX_NONE, 16, 1, + out->data, out->len, false); + ++ init_completion(&arg.done); ++ cntx = phy->out_urb->context; ++ phy->out_urb->context = &arg; ++ + rc = usb_submit_urb(phy->out_urb, GFP_KERNEL); + if (rc) + return rc; + ++ wait_for_completion(&arg.done); ++ phy->out_urb->context = cntx; ++ + if (dev->protocol_type == PN533_PROTO_REQ_RESP) { + /* request for response for sent packet directly */ + rc = pn533_submit_urb_for_response(phy, GFP_KERNEL); +@@ -424,7 +438,31 @@ static int pn533_acr122_poweron_rdr(struct pn533_usb_phy *phy) + return arg.rc; + } + +-static void pn533_send_complete(struct urb *urb) ++static void pn533_out_complete(struct urb *urb) ++{ ++ struct pn533_out_arg *arg = urb->context; ++ struct pn533_usb_phy *phy = arg->phy; ++ ++ switch (urb->status) { ++ case 0: ++ break; /* success */ ++ case -ECONNRESET: ++ case -ENOENT: ++ dev_dbg(&phy->udev->dev, ++ "The urb has been stopped (status %d)\n", ++ urb->status); ++ break; ++ case -ESHUTDOWN: ++ default: ++ nfc_err(&phy->udev->dev, ++ "Urb failure (status %d)\n", ++ urb->status); ++ } ++ ++ complete(&arg->done); ++} ++ ++static void pn533_ack_complete(struct urb *urb) + { + struct pn533_usb_phy *phy = urb->context; + +@@ -512,10 +550,10 @@ static int pn533_usb_probe(struct usb_interface *interface, + + usb_fill_bulk_urb(phy->out_urb, phy->udev, + usb_sndbulkpipe(phy->udev, out_endpoint), +- NULL, 0, pn533_send_complete, phy); ++ NULL, 0, pn533_out_complete, phy); + usb_fill_bulk_urb(phy->ack_urb, phy->udev, + usb_sndbulkpipe(phy->udev, out_endpoint), +- NULL, 0, pn533_send_complete, phy); ++ NULL, 0, pn533_ack_complete, phy); + + switch (id->driver_info) { + case PN533_DEVICE_STD: +-- +2.35.1 + diff --git a/queue-4.14/regulator-da9211-use-irq-handler-when-ready.patch b/queue-4.14/regulator-da9211-use-irq-handler-when-ready.patch new file mode 100644 index 00000000000..46f02196308 --- /dev/null +++ b/queue-4.14/regulator-da9211-use-irq-handler-when-ready.patch @@ -0,0 +1,66 @@ +From 65178d5bf966dfc8bb905fb123591e9e471b0463 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 27 Nov 2022 22:06:02 +0100 +Subject: regulator: da9211: Use irq handler when ready + +From: Ricardo Ribalda + +[ Upstream commit 02228f6aa6a64d588bc31e3267d05ff184d772eb ] + +If the system does not come from reset (like when it is kexec()), the +regulator might have an IRQ waiting for us. + +If we enable the IRQ handler before its structures are ready, we crash. + +This patch fixes: + +[ 1.141839] Unable to handle kernel read from unreadable memory at virtual address 0000000000000078 +[ 1.316096] Call trace: +[ 1.316101] blocking_notifier_call_chain+0x20/0xa8 +[ 1.322757] cpu cpu0: dummy supplies not allowed for exclusive requests +[ 1.327823] regulator_notifier_call_chain+0x1c/0x2c +[ 1.327825] da9211_irq_handler+0x68/0xf8 +[ 1.327829] irq_thread+0x11c/0x234 +[ 1.327833] kthread+0x13c/0x154 + +Signed-off-by: Ricardo Ribalda +Reviewed-by: Adam Ward +Link: https://lore.kernel.org/r/20221124-da9211-v2-0-1779e3c5d491@chromium.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/da9211-regulator.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c +index aa47280efd32..8879e315211e 100644 +--- a/drivers/regulator/da9211-regulator.c ++++ b/drivers/regulator/da9211-regulator.c +@@ -470,6 +470,12 @@ static int da9211_i2c_probe(struct i2c_client *i2c, + + chip->chip_irq = i2c->irq; + ++ ret = da9211_regulator_init(chip); ++ if (ret < 0) { ++ dev_err(chip->dev, "Failed to initialize regulator: %d\n", ret); ++ return ret; ++ } ++ + if (chip->chip_irq != 0) { + ret = devm_request_threaded_irq(chip->dev, chip->chip_irq, NULL, + da9211_irq_handler, +@@ -484,11 +490,6 @@ static int da9211_i2c_probe(struct i2c_client *i2c, + dev_warn(chip->dev, "No IRQ configured\n"); + } + +- ret = da9211_regulator_init(chip); +- +- if (ret < 0) +- dev_err(chip->dev, "Failed to initialize regulator: %d\n", ret); +- + return ret; + } + +-- +2.35.1 + diff --git a/queue-4.14/series b/queue-4.14/series index e572d8d1324..2afe614c527 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -332,3 +332,6 @@ ipv6-raw-deduct-extension-header-length-in-rawv6_push_pending_frames.patch netfilter-ipset-fix-overflow-before-widen-in-the-bitmap_ip_create-function.patch x86-boot-avoid-using-intel-mnemonics-in-at-t-syntax-asm.patch edac-device-fix-period-calculation-in-edac_device_reset_delay_period.patch +regulator-da9211-use-irq-handler-when-ready.patch +hvc-xen-lock-console-list-traversal.patch +nfc-pn533-wait-for-out_urb-s-completion-in-pn533_usb.patch