--- /dev/null
+From 26504844613fb44c7cab1c5f6fcff77861709baa Mon Sep 17 00:00:00 2001
+From: Lucas Martins Alves <lucas.alves@lumal21.com.br>
+Date: Tue, 14 Jul 2026 16:48:57 +0000
+Subject: can: c_can: c_can_chip_config(): keep controller in init mode until bittiming is configured
+
+From: Lucas Martins Alves <lucas.alves@lumal21.com.br>
+
+commit 26504844613fb44c7cab1c5f6fcff77861709baa upstream.
+
+c_can_chip_config() was programming C_CAN_CTRL_REG without CONTROL_INIT,
+which may allow the controller to become active before
+c_can_set_bittiming() finishes.
+
+That creates a short timing window where the peripheral can interact with
+the bus using a different/default bitrate, potentially generating bus
+errors and corrupting traffic.
+
+Set CONTROL_INIT together with the control-mode writes in
+c_can_chip_config() (normal, loopback and listen-only paths), so the
+controller stays halted until bit timing is fully programmed.
+
+This prevents transient bus disturbance during startup when the configured
+bitrate differs from the active bus bitrate.
+
+Signed-off-by: Lucas Martins Alves <lucas.alves@lumal21.com.br>
+Link: https://patch.msgid.link/20260714164839.771123-1-lucas.alves@lumal21.com.br
+Fixes: 881ff67ad450 ("can: c_can: Added support for Bosch C_CAN controller")
+Cc: stable@kernel.org
+[mkl: remove space before close parenthesis]
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/c_can/c_can_main.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/can/c_can/c_can_main.c
++++ b/drivers/net/can/c_can/c_can_main.c
+@@ -597,20 +597,20 @@ static int c_can_chip_config(struct net_
+ return err;
+
+ /* enable automatic retransmission */
+- priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_ENABLE_AR);
++ priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_ENABLE_AR | CONTROL_INIT);
+
+ if ((priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) &&
+ (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)) {
+ /* loopback + silent mode : useful for hot self-test */
+- priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST);
++ priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST | CONTROL_INIT);
+ priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK | TEST_SILENT);
+ } else if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
+ /* loopback mode : useful for self-test function */
+- priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST);
++ priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST | CONTROL_INIT);
+ priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK);
+ } else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) {
+ /* silent mode : bus-monitoring mode */
+- priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST);
++ priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST | CONTROL_INIT);
+ priv->write_reg(priv, C_CAN_TEST_REG, TEST_SILENT);
+ }
+
--- /dev/null
+From d937bdb244a751fe5967052ea2d64a7b2c476cc0 Mon Sep 17 00:00:00 2001
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Date: Sat, 4 Jul 2026 23:19:57 +0800
+Subject: can: ctucanfd: add missing MODULE_DEVICE_TABLE()
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+commit d937bdb244a751fe5967052ea2d64a7b2c476cc0 upstream.
+
+The driver has a match table for the pci bus wired into its driver
+structure, but the table is not exported with MODULE_DEVICE_TABLE().
+
+Add the missing MODULE_DEVICE_TABLE() entry so module alias information
+is generated for automatic module loading.
+
+This is a source-level fix. It does not claim dynamic hardware
+reproduction; the evidence is the driver-owned match table, its use by
+the driver registration structure, and the missing module alias
+publication.
+
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Acked-by: Pavel Pisa <pisa@fel.cvut.cz>
+Link: https://patch.msgid.link/20260704151957.48194-1-pengpeng@iscas.ac.cn
+Fixes: 792a5b678e81 ("can: ctucanfd: CTU CAN FD open-source IP core - PCI bus support.")
+Cc: stable@kernel.org
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/ctucanfd/ctucanfd_pci.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/can/ctucanfd/ctucanfd_pci.c
++++ b/drivers/net/can/ctucanfd/ctucanfd_pci.c
+@@ -278,6 +278,7 @@ static const struct pci_device_id ctucan
+ CTUCAN_WITH_CTUCAN_ID)},
+ {},
+ };
++MODULE_DEVICE_TABLE(pci, ctucan_pci_tbl);
+
+ static struct pci_driver ctucan_pci_driver = {
+ .name = KBUILD_MODNAME,
--- /dev/null
+From e74bae899529f49c0f375307983d12e8ecad7d4b Mon Sep 17 00:00:00 2001
+From: Avi Weiss <thnkslprpt@gmail.com>
+Date: Thu, 23 Jul 2026 10:44:03 +0300
+Subject: can: ctucanfd: handle bus error interrupts
+
+From: Avi Weiss <thnkslprpt@gmail.com>
+
+commit e74bae899529f49c0f375307983d12e8ecad7d4b upstream.
+
+Include REG_INT_STAT_BEI in the top-level error interrupt condition.
+
+BEI is enabled when CAN_CTRLMODE_BERR_REPORTING is requested and
+ctucan_err_interrupt() already handles it. Without checking and
+clearing BEI in the top-level handler, bus error interrupts are not
+handled or acknowledged.
+
+Fixes: 2dcb8e8782d8 ("can: ctucanfd: add support for CTU CAN FD open-source IP core - bus independent part.")
+Signed-off-by: Avi Weiss <thnkslprpt@gmail.com>
+Acked-by: Pavel Pisa <pisa@fel.cvut.cz>
+Link: https://patch.msgid.link/20260723074403.131575-1-thnkslprpt@gmail.com
+Cc: stable@kernel.org
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/ctucanfd/ctucanfd_base.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/can/ctucanfd/ctucanfd_base.c
++++ b/drivers/net/can/ctucanfd/ctucanfd_base.c
+@@ -1135,8 +1135,12 @@ static irqreturn_t ctucan_interrupt(int
+ /* Error interrupts */
+ if (FIELD_GET(REG_INT_STAT_EWLI, isr) ||
+ FIELD_GET(REG_INT_STAT_FCSI, isr) ||
+- FIELD_GET(REG_INT_STAT_ALI, isr)) {
+- icr = isr & (REG_INT_STAT_EWLI | REG_INT_STAT_FCSI | REG_INT_STAT_ALI);
++ FIELD_GET(REG_INT_STAT_ALI, isr) ||
++ FIELD_GET(REG_INT_STAT_BEI, isr)) {
++ icr = isr & (REG_INT_STAT_EWLI |
++ REG_INT_STAT_FCSI |
++ REG_INT_STAT_ALI |
++ REG_INT_STAT_BEI);
+
+ ctucan_netdev_dbg(ndev, "some ERR interrupt: clearing 0x%08x\n", icr);
+ ctucan_write32(priv, CTUCANFD_INT_STAT, icr);
--- /dev/null
+From 4e735cbe3affe88001428fdd9cae8e685ce92f21 Mon Sep 17 00:00:00 2001
+From: Avi Weiss <thnkslprpt@gmail.com>
+Date: Thu, 23 Jul 2026 18:55:43 +0300
+Subject: can: ctucanfd: mark error-active controller status valid
+
+From: Avi Weiss <thnkslprpt@gmail.com>
+
+commit 4e735cbe3affe88001428fdd9cae8e685ce92f21 upstream.
+
+In the CAN_STATE_ERROR_ACTIVE case, cf->data[1] is set to
+CAN_ERR_CRTL_ACTIVE, but cf->can_id is not set with CAN_ERR_CRTL in
+that path.
+
+Set CAN_ERR_CRTL so consumers know the controller-status information
+in cf->data[1] is valid.
+
+Fixes: 9bd24927e3ee ("can: ctucanfd: handle skb allocation failure")
+Signed-off-by: Avi Weiss <thnkslprpt@gmail.com>
+Link: https://patch.msgid.link/20260723155543.318414-1-thnkslprpt@gmail.com
+Cc: stable@kernel.org
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/ctucanfd/ctucanfd_base.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/can/ctucanfd/ctucanfd_base.c
++++ b/drivers/net/can/ctucanfd/ctucanfd_base.c
+@@ -868,7 +868,7 @@ static void ctucan_err_interrupt(struct
+ break;
+ case CAN_STATE_ERROR_ACTIVE:
+ if (skb) {
+- cf->can_id |= CAN_ERR_CNT;
++ cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
+ cf->data[1] = CAN_ERR_CRTL_ACTIVE;
+ cf->data[6] = bec.txerr;
+ cf->data[7] = bec.rxerr;
--- /dev/null
+From a6873910f983096746d1a2e0af94f36b8003e839 Mon Sep 17 00:00:00 2001
+From: Avi Weiss <thnkslprpt@gmail.com>
+Date: Thu, 23 Jul 2026 12:59:34 +0300
+Subject: can: ctucanfd: unmap BAR0 using base address
+
+From: Avi Weiss <thnkslprpt@gmail.com>
+
+commit a6873910f983096746d1a2e0af94f36b8003e839 upstream.
+
+BAR0 is mapped into bar0_base, while cra_addr points to an offset
+within that mapping and is used for other purposes.
+
+Pass bar0_base to pci_iounmap(), instead of cra_addr, on the probe error
+path so the address returned by pci_iomap() is used for unmapping.
+
+Fixes: 792a5b678e81 ("can: ctucanfd: CTU CAN FD open-source IP core - PCI bus support.")
+Signed-off-by: Avi Weiss <thnkslprpt@gmail.com>
+Acked-by: Pavel Pisa <pisa@fel.cvut.cz>
+Link: https://patch.msgid.link/20260723095934.181042-1-thnkslprpt@gmail.com
+Cc: stable@kernel.org
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/ctucanfd/ctucanfd_pci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/can/ctucanfd/ctucanfd_pci.c
++++ b/drivers/net/can/ctucanfd/ctucanfd_pci.c
+@@ -202,7 +202,7 @@ err_free_board:
+ pci_set_drvdata(pdev, NULL);
+ kfree(bdata);
+ err_pci_iounmap_bar0:
+- pci_iounmap(pdev, cra_addr);
++ pci_iounmap(pdev, bar0_base);
+ err_pci_iounmap_bar1:
+ pci_iounmap(pdev, addr);
+ err_release_regions:
--- /dev/null
+From c31a435933f18be0f874302161333e9f16e200a0 Mon Sep 17 00:00:00 2001
+From: Avi Weiss <thnkslprpt@gmail.com>
+Date: Wed, 22 Jul 2026 22:27:26 +0300
+Subject: can: ctucanfd: use self-test mode for PRESUME_ACK
+
+From: Avi Weiss <thnkslprpt@gmail.com>
+
+commit c31a435933f18be0f874302161333e9f16e200a0 upstream.
+
+Use self-test mode for CAN_CTRLMODE_PRESUME_ACK so transmitted
+frames can complete without receiving an ACK.
+
+ACK forbidden mode prevents the controller from acknowledging
+received frames and does not implement the presume-ack behavior.
+
+Fixes: 2dcb8e8782d8 ("can: ctucanfd: add support for CTU CAN FD open-source IP core - bus independent part.")
+Signed-off-by: Avi Weiss <thnkslprpt@gmail.com>
+Acked-by: Pavel Pisa <pisa@fel.cvut.cz>
+Link: https://patch.msgid.link/20260722192726.230729-1-thnkslprpt@gmail.com
+Cc: stable@kernel.org
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/ctucanfd/ctucanfd_base.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/can/ctucanfd/ctucanfd_base.c
++++ b/drivers/net/can/ctucanfd/ctucanfd_base.c
+@@ -340,8 +340,8 @@ static void ctucan_set_mode(struct ctuca
+ (mode_reg & ~REG_MODE_FDE);
+
+ mode_reg = (mode->flags & CAN_CTRLMODE_PRESUME_ACK) ?
+- (mode_reg | REG_MODE_ACF) :
+- (mode_reg & ~REG_MODE_ACF);
++ (mode_reg | REG_MODE_STM) :
++ (mode_reg & ~REG_MODE_STM);
+
+ mode_reg = (mode->flags & CAN_CTRLMODE_FD_NON_ISO) ?
+ (mode_reg | REG_MODE_NISOFD) :
--- /dev/null
+From 02925f51377f2a42a6724f00549167499c9302e5 Mon Sep 17 00:00:00 2001
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Date: Mon, 6 Jul 2026 17:27:52 +0800
+Subject: can: ems_usb: validate CPC message lengths
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+commit 02925f51377f2a42a6724f00549167499c9302e5 upstream.
+
+ems_usb_read_bulk_callback() walks CPC messages packed in one USB
+receive buffer.
+
+Check that each declared message fits in the URB payload. Also require the
+type-specific payload to cover the fields used by the CAN, state, error and
+overrun handlers.
+
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Link: https://patch.msgid.link/20260706092752.79600-1-pengpeng@iscas.ac.cn
+Fixes: 702171adeed3 ("ems_usb: Added support for EMS CPC-USB/ARM7 CAN/USB interface")
+Cc: stable@vger.kernel.org
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/usb/ems_usb.c | 43 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 43 insertions(+)
+
+--- a/drivers/net/can/usb/ems_usb.c
++++ b/drivers/net/can/usb/ems_usb.c
+@@ -409,6 +409,40 @@ static void ems_usb_rx_err(struct ems_us
+ netif_rx(skb);
+ }
+
++static bool ems_usb_rx_msg_len_valid(struct ems_cpc_msg *msg)
++{
++ size_t len = msg->length;
++ size_t can_len;
++
++ switch (msg->type) {
++ case CPC_MSG_TYPE_CAN_STATE:
++ return len >= sizeof(msg->msg.can_state);
++
++ case CPC_MSG_TYPE_CAN_FRAME:
++ case CPC_MSG_TYPE_EXT_CAN_FRAME:
++ case CPC_MSG_TYPE_RTR_FRAME:
++ case CPC_MSG_TYPE_EXT_RTR_FRAME:
++ if (len < CPC_CAN_MSG_MIN_SIZE)
++ return false;
++
++ if (msg->type == CPC_MSG_TYPE_RTR_FRAME ||
++ msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME)
++ return true;
++
++ can_len = can_cc_dlc2len(msg->msg.can_msg.length & 0xf);
++ return len >= CPC_CAN_MSG_MIN_SIZE + can_len;
++
++ case CPC_MSG_TYPE_CAN_FRAME_ERROR:
++ return len >= sizeof(msg->msg.error);
++
++ case CPC_MSG_TYPE_OVERRUN:
++ return len >= sizeof(msg->msg.overrun);
++
++ default:
++ return true;
++ }
++}
++
+ /*
+ * callback for bulk IN urb
+ */
+@@ -451,6 +485,15 @@ static void ems_usb_read_bulk_callback(s
+ }
+
+ msg = (struct ems_cpc_msg *)&ibuf[start];
++ if (msg->length >
++ urb->actual_length - start - CPC_MSG_HEADER_LEN) {
++ netdev_err(netdev, "format error\n");
++ break;
++ }
++ if (!ems_usb_rx_msg_len_valid(msg)) {
++ netdev_err(netdev, "format error\n");
++ break;
++ }
+
+ switch (msg->type) {
+ case CPC_MSG_TYPE_CAN_STATE:
--- /dev/null
+From 7a0cf2b2497c757c3cb1286eddf2986abb0d387b Mon Sep 17 00:00:00 2001
+From: Guangshuo Li <lgs201920130244@gmail.com>
+Date: Mon, 6 Jul 2026 09:46:01 +0800
+Subject: can: etas_es58x: es58x_read_bulk_callback(): fix RX buffer leak on URB resubmit failure
+
+From: Guangshuo Li <lgs201920130244@gmail.com>
+
+commit 7a0cf2b2497c757c3cb1286eddf2986abb0d387b upstream.
+
+es58x_read_bulk_callback() resubmits the RX URB after processing a received
+packet. If the resubmit succeeds, the URB remains anchored and will be
+handled by the normal RX path or by teardown.
+
+However, if usb_submit_urb() fails, the callback unanchors the URB and then
+returns directly. This skips the existing free_urb path, so the coherent
+transfer buffer allocated with usb_alloc_coherent() is not released.
+
+Reuse the existing free_urb path after a resubmit failure so that the RX
+coherent buffer is freed before leaving the callback.
+
+Fixes: 5eaad4f76826 ("can: usb: etas_es58x: correctly anchor the urb in the read bulk callback")
+Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
+Reviewed-by: Vincent Mailhol <mailhol@kernel.org>
+Link: https://patch.msgid.link/20260706014601.415445-1-lgs201920130244@gmail.com
+Cc: stable@kernel.org
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/usb/etas_es58x/es58x_core.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/net/can/usb/etas_es58x/es58x_core.c
++++ b/drivers/net/can/usb/etas_es58x/es58x_core.c
+@@ -1475,7 +1475,6 @@ static void es58x_read_bulk_callback(str
+ dev_err_ratelimited(dev,
+ "Failed resubmitting read bulk urb: %pe\n",
+ ERR_PTR(ret));
+- return;
+
+ free_urb:
+ usb_free_coherent(urb->dev, urb->transfer_buffer_length,
--- /dev/null
+From eb96c58907922546e415e545fe9a14ea63b02719 Mon Sep 17 00:00:00 2001
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+Date: Tue, 28 Jul 2026 07:58:35 +0200
+Subject: can: j1939: transport: j1939_session_fresh_new(): initialize receive buffer
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+commit eb96c58907922546e415e545fe9a14ea63b02719 upstream.
+
+Zero the allocated buffer in j1939_session_fresh_new() to ensure it
+contains no residual data.
+
+While there is a potential performance impact if users allocate maximum
+sized ETP buffers, most real-world use cases are not noticeably affected
+since the maximum known buffer size is typically around 65K.
+
+Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol")
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Message-ID: <CAPAUci5dykCLjoijqkUtFqJFesgncrD7+S6y_V=gjbFkY2Tifg@mail.gmail.com>
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://patch.msgid.link/20260728055835.1151785-3-o.rempel@pengutronix.de
+Cc: stable@kernel.org
+[mkl: add Message-ID]
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/can/j1939/transport.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/can/j1939/transport.c
++++ b/net/can/j1939/transport.c
+@@ -1562,7 +1562,7 @@ j1939_session *j1939_session_fresh_new(s
+ }
+
+ /* alloc data area */
+- skb_put(skb, size);
++ skb_put_zero(skb, size);
+ /* skb is recounted in j1939_session_new() */
+ return session;
+ }
--- /dev/null
+From d2fb981384b3a45f690616d550b29046e8ad16a4 Mon Sep 17 00:00:00 2001
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Date: Tue, 28 Jul 2026 07:58:34 +0200
+Subject: can: j1939: use netdevice_tracker for j1939_{priv,session,ecu} tracking
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+commit d2fb981384b3a45f690616d550b29046e8ad16a4 upstream.
+
+syzbot is still reporting
+
+ unregister_netdevice: waiting for vcan0 to become free. Usage count = 2
+
+problem. A debug printk() patch in linux-next-20260508 identified that
+there is dev_hold()/dev_put() imbalance in j1939_priv management.
+
+ Call trace for vcan0[26] +4 at
+ __dev_hold include/linux/netdevice.h:4470 [inline]
+ netdev_hold include/linux/netdevice.h:4513 [inline]
+ dev_hold include/linux/netdevice.h:4536 [inline]
+ j1939_priv_create net/can/j1939/main.c:140 [inline]
+ j1939_netdev_start+0x36b/0xc10 net/can/j1939/main.c:268
+ j1939_sk_bind+0x853/0xb30 net/can/j1939/socket.c:506
+ __sys_bind_socket net/socket.c:1948 [inline]
+ __sys_bind+0x2e9/0x410 net/socket.c:1979
+
+ Call trace for vcan0[28] -3 at
+ __dev_put include/linux/netdevice.h:4456 [inline]
+ netdev_put include/linux/netdevice.h:4523 [inline]
+ dev_put include/linux/netdevice.h:4548 [inline]
+ __j1939_priv_release net/can/j1939/main.c:166 [inline]
+ kref_put include/linux/kref.h:65 [inline]
+ j1939_priv_put+0x128/0x270 net/can/j1939/main.c:172
+ j1939_sk_sock_destruct+0x52/0x90 net/can/j1939/socket.c:388
+ __sk_destruct+0x8d/0x9d0 net/core/sock.c:2352
+ rcu_do_batch kernel/rcu/tree.c:2617 [inline]
+ rcu_core kernel/rcu/tree.c:2869 [inline]
+ rcu_cpu_kthread+0x99e/0x1470 kernel/rcu/tree.c:2957
+ smpboot_thread_fn+0x541/0xa50 kernel/smpboot.c:160
+ kthread+0x388/0x470 kernel/kthread.c:436
+ ret_from_fork+0x514/0xb70 arch/x86/kernel/process.c:158
+ ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
+
+This refcount leak in j1939_priv might be caused by a refcount leak in
+j1939_{session,ecu} because j1939_{session,ecu} holds a ref on j1939_priv.
+For further investigation using upstream kernels, enable netdevice_tracker
+in j1939_{priv,session,ecu} management.
+
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://patch.msgid.link/20260728055835.1151785-2-o.rempel@pengutronix.de
+Cc: stable@kernel.org
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/can/j1939/bus.c | 2 ++
+ net/can/j1939/j1939-priv.h | 3 +++
+ net/can/j1939/main.c | 8 ++++----
+ net/can/j1939/transport.c | 2 ++
+ 4 files changed, 11 insertions(+), 4 deletions(-)
+
+--- a/net/can/j1939/bus.c
++++ b/net/can/j1939/bus.c
+@@ -20,6 +20,7 @@ static void __j1939_ecu_release(struct k
+ struct j1939_priv *priv = ecu->priv;
+
+ list_del(&ecu->list);
++ netdev_put(priv->ndev, &ecu->priv_dev_tracker);
+ kfree(ecu);
+ j1939_priv_put(priv);
+ }
+@@ -155,6 +156,7 @@ struct j1939_ecu *j1939_ecu_create_locke
+ if (!ecu)
+ return ERR_PTR(-ENOMEM);
+ kref_init(&ecu->kref);
++ netdev_hold(priv->ndev, &ecu->priv_dev_tracker, gfp_any());
+ ecu->addr = J1939_IDLE_ADDR;
+ ecu->name = name;
+
+--- a/net/can/j1939/j1939-priv.h
++++ b/net/can/j1939/j1939-priv.h
+@@ -38,6 +38,7 @@ struct j1939_ecu {
+ struct hrtimer ac_timer;
+ struct kref kref;
+ struct j1939_priv *priv;
++ netdevice_tracker priv_dev_tracker;
+
+ /* count users, to help transport protocol decide for interaction */
+ int nusers;
+@@ -60,6 +61,7 @@ struct j1939_priv {
+ rwlock_t lock;
+
+ struct net_device *ndev;
++ netdevice_tracker dev_tracker;
+
+ /* list of 256 ecu ptrs, that cache the claimed addresses.
+ * also protected by the above lock
+@@ -229,6 +231,7 @@ enum j1939_session_state {
+
+ struct j1939_session {
+ struct j1939_priv *priv;
++ netdevice_tracker priv_dev_tracker;
+ struct list_head active_session_list_entry;
+ struct list_head sk_session_queue_entry;
+ struct kref kref;
+--- a/net/can/j1939/main.c
++++ b/net/can/j1939/main.c
+@@ -137,7 +137,7 @@ static struct j1939_priv *j1939_priv_cre
+ priv->ndev = ndev;
+ kref_init(&priv->kref);
+ kref_init(&priv->rx_kref);
+- dev_hold(ndev);
++ netdev_hold(ndev, &priv->dev_tracker, GFP_KERNEL);
+
+ netdev_dbg(priv->ndev, "%s : 0x%p\n", __func__, priv);
+
+@@ -163,7 +163,7 @@ static void __j1939_priv_release(struct
+ WARN_ON_ONCE(!list_empty(&priv->ecus));
+ WARN_ON_ONCE(!list_empty(&priv->j1939_socks));
+
+- dev_put(ndev);
++ netdev_put(ndev, &priv->dev_tracker);
+ kfree(priv);
+ }
+
+@@ -281,7 +281,7 @@ struct j1939_priv *j1939_netdev_start(st
+ */
+ kref_get(&priv_new->rx_kref);
+ mutex_unlock(&j1939_netdev_lock);
+- dev_put(ndev);
++ netdev_put(ndev, &priv->dev_tracker);
+ kfree(priv);
+ return priv_new;
+ }
+@@ -298,7 +298,7 @@ struct j1939_priv *j1939_netdev_start(st
+ j1939_priv_set(ndev, NULL);
+ mutex_unlock(&j1939_netdev_lock);
+
+- dev_put(ndev);
++ netdev_put(ndev, &priv->dev_tracker);
+ kfree(priv);
+
+ return ERR_PTR(ret);
+--- a/net/can/j1939/transport.c
++++ b/net/can/j1939/transport.c
+@@ -282,6 +282,7 @@ static void j1939_session_destroy(struct
+ kfree_skb(skb);
+ }
+ __j1939_session_drop(session);
++ netdev_put(session->priv->ndev, &session->priv_dev_tracker);
+ j1939_priv_put(session->priv);
+ kfree(session);
+ }
+@@ -1510,6 +1511,7 @@ static struct j1939_session *j1939_sessi
+ INIT_LIST_HEAD(&session->active_session_list_entry);
+ INIT_LIST_HEAD(&session->sk_session_queue_entry);
+ kref_init(&session->kref);
++ netdev_hold(priv->ndev, &session->priv_dev_tracker, gfp_any());
+
+ j1939_priv_get(priv);
+ session->priv = priv;
--- /dev/null
+From 941eaf9a6d3b33dea49f2c0a1da7546a03b6ff71 Mon Sep 17 00:00:00 2001
+From: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+Date: Wed, 22 Jul 2026 16:09:03 +0530
+Subject: can: kvaser_usb: kvaser_usb_hydra_get_busparams(): fix memory leak in kvaser_usb_hydra_get_busparams()
+
+From: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+
+commit 941eaf9a6d3b33dea49f2c0a1da7546a03b6ff71 upstream.
+
+The memory allocated for cmd is not freed after the call to
+kvaser_usb_send_cmd() in both the normal and error paths.
+Fix that by adding a kfree() immediately after the call.
+
+Fixes: 39d3df6b0ea8 ("can: kvaser_usb: Compare requested bittiming parameters with actual parameters in do_set_{,data}_bittiming")
+Cc: stable@vger.kernel.org
+Signed-off-by: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+Link: https://patch.msgid.link/20260722103906.108571-1-nihaal@cse.iitm.ac.in
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+@@ -1605,6 +1605,7 @@ static int kvaser_usb_hydra_get_busparam
+ reinit_completion(&priv->get_busparams_comp);
+
+ err = kvaser_usb_send_cmd(dev, cmd, cmd_len);
++ kfree(cmd);
+ if (err)
+ return err;
+
--- /dev/null
+From 0293dd153f9dbc1ddf5dacdccc76b363bce4a8ee Mon Sep 17 00:00:00 2001
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Date: Wed, 22 Jul 2026 12:22:21 +0800
+Subject: can: kvaser_usb_leaf: kvaser_usb_leaf_wait_cmd(): validate received command extents
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+commit 0293dd153f9dbc1ddf5dacdccc76b363bce4a8ee upstream.
+
+The wait and bulk receive paths walk variable-length commands from a
+USB buffer. A nonzero command shorter than CMD_HEADER_LEN can still be
+dispatched, and the wait path copies a matching command into a fixed
+caller-owned struct kvaser_cmd using the device-provided length.
+
+Reject nonzero commands that do not contain the fixed header or that
+extend beyond the current USB buffer item. In the wait path, also reject
+a matching command that exceeds the destination before copying it.
+
+Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Link: https://patch.msgid.link/20260722042221.44066-1-pengpeng@iscas.ac.cn
+Cc: stable@kernel.org
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -614,13 +614,22 @@ static int kvaser_usb_leaf_wait_cmd(cons
+ continue;
+ }
+
+- if (pos + tmp->len > actual_len) {
++ if (tmp->len < CMD_HEADER_LEN ||
++ tmp->len > actual_len - pos) {
+ dev_err_ratelimited(&dev->intf->dev,
+ "Format error\n");
+ break;
+ }
+
+ if (tmp->id == id) {
++ if (tmp->len > sizeof(*cmd)) {
++ dev_err_ratelimited(&dev->intf->dev,
++ "Received command %u too large (%u)\n",
++ tmp->id, tmp->len);
++ err = -EIO;
++ goto end;
++ }
++
+ memcpy(cmd, tmp, tmp->len);
+ goto end;
+ }
+@@ -1572,7 +1581,7 @@ static void kvaser_usb_leaf_read_bulk_ca
+ continue;
+ }
+
+- if (pos + cmd->len > len) {
++ if (cmd->len < CMD_HEADER_LEN || cmd->len > len - pos) {
+ dev_err_ratelimited(&dev->intf->dev, "Format error\n");
+ break;
+ }
--- /dev/null
+From 39132f166ca8ce00ae60d8a9068e06a60943cc4b Mon Sep 17 00:00:00 2001
+From: James Gao <jamesgao5@outlook.com>
+Date: Wed, 20 May 2026 13:40:03 +0800
+Subject: can: peak_usb: add bounds check for USB channel index
+
+From: James Gao <jamesgao5@outlook.com>
+
+commit 39132f166ca8ce00ae60d8a9068e06a60943cc4b upstream.
+
+The channel control index ctrl_idx is derived from rx->len which comes
+directly from a device USB payload. The mask 0x0f allows values 0-15, but
+the array size of usb_if->dev[] is only 2. Values 2-15 cause heap
+out-of-bounds read, eventually causing kernel panic in the IRQ context.
+
+Add bounds checking for ctrl_idx before the array access in both
+pcan_usb_pro_handle_canmsg() and pcan_usb_pro_handle_error().
+
+Fixes: d8a199355f8f ("can: usb: PEAK-System Technik PCAN-USB Pro specific part")
+Signed-off-by: James Gao <jamesgao5@outlook.com>
+Reviewed-by: Vincent Mailhol <mailhol@kernel.org>
+Link: https://patch.msgid.link/TYWPR01MB8559DBAAAA6A7F410400329CF0012@TYWPR01MB8559.jpnprd01.prod.outlook.com
+Cc: stable@kernel.org
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/usb/peak_usb/pcan_usb_pro.c | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
++++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+@@ -520,12 +520,18 @@ static int pcan_usb_pro_handle_canmsg(st
+ struct pcan_usb_pro_rxmsg *rx)
+ {
+ const unsigned int ctrl_idx = (rx->len >> 4) & 0x0f;
+- struct peak_usb_device *dev = usb_if->dev[ctrl_idx];
+- struct net_device *netdev = dev->netdev;
++ struct peak_usb_device *dev;
++ struct net_device *netdev;
+ struct can_frame *can_frame;
+ struct sk_buff *skb;
+ struct skb_shared_hwtstamps *hwts;
+
++ if (ctrl_idx >= ARRAY_SIZE(usb_if->dev))
++ return -EINVAL;
++
++ dev = usb_if->dev[ctrl_idx];
++ netdev = dev->netdev;
++
+ skb = alloc_can_skb(netdev, &can_frame);
+ if (!skb)
+ return -ENOMEM;
+@@ -559,14 +565,20 @@ static int pcan_usb_pro_handle_error(str
+ {
+ const u16 raw_status = le16_to_cpu(er->status);
+ const unsigned int ctrl_idx = (er->channel >> 4) & 0x0f;
+- struct peak_usb_device *dev = usb_if->dev[ctrl_idx];
+- struct net_device *netdev = dev->netdev;
++ struct peak_usb_device *dev;
++ struct net_device *netdev;
+ struct can_frame *can_frame;
+ enum can_state new_state = CAN_STATE_ERROR_ACTIVE;
+ u8 err_mask = 0;
+ struct sk_buff *skb;
+ struct skb_shared_hwtstamps *hwts;
+
++ if (ctrl_idx >= ARRAY_SIZE(usb_if->dev))
++ return -EINVAL;
++
++ dev = usb_if->dev[ctrl_idx];
++ netdev = dev->netdev;
++
+ /* nothing should be sent while in BUS_OFF state */
+ if (dev->can.state == CAN_STATE_BUS_OFF)
+ return 0;
--- /dev/null
+From 9b3d5a6d952c38bbcf07f903cbeadefdb56b9bc9 Mon Sep 17 00:00:00 2001
+From: Maoyi Xie <maoyixie.tju@gmail.com>
+Date: Wed, 17 Jun 2026 02:15:31 +0800
+Subject: can: peak_usb: peak_usb_start(): fix double free of transfer buffer on URB submit error
+
+From: Maoyi Xie <maoyixie.tju@gmail.com>
+
+commit 9b3d5a6d952c38bbcf07f903cbeadefdb56b9bc9 upstream.
+
+In peak_usb_start(), each RX URB transfer buffer is allocated with kmalloc()
+and the URB is flagged URB_FREE_BUFFER so that the final usb_free_urb() also
+frees the transfer buffer.
+
+If usb_submit_urb() fails, the error path frees the buffer explicitly with
+kfree(buf) and then calls usb_free_urb(urb). Because URB_FREE_BUFFER is set,
+usb_free_urb() -> urb_destroy() frees the same buffer a second time, a double
+free of the transfer buffer.
+
+ BUG: KASAN: double-free in usb_free_urb.part.0+0x91/0xb0
+ Free of addr ffff8881069ccb80 by task trigger.sh/285
+
+ Call Trace:
+ kfree+0x113/0x3c0
+ usb_free_urb.part.0+0x91/0xb0
+
+Drop the redundant kfree(buf); usb_free_urb() already releases the transfer
+buffer. This mirrors commit 03819abbeb11 ("net: usb: lan78xx: Fix double free
+issue with interrupt buffer allocation").
+
+Fixes: bb4785551f64 ("can: usb: PEAK-System Technik USB adapters driver core")
+Closes: https://lore.kernel.org/linux-can/178159320216.2154888.16953451793788581739@maoyixie.com/T/#u
+Cc: stable@vger.kernel.org
+Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
+Reviewed-by: Vincent Mailhol <mailhol@kernel.org>
+Link: https://patch.msgid.link/178163373110.2507866.216458825145756798@maoyixie.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/usb/peak_usb/pcan_usb_core.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
++++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+@@ -461,7 +461,6 @@ static int peak_usb_start(struct peak_us
+ netif_device_detach(dev->netdev);
+
+ usb_unanchor_urb(urb);
+- kfree(buf);
+ usb_free_urb(urb);
+ break;
+ }
--- /dev/null
+From 93fcab2c6968446316bbb49548848df604d6346f Mon Sep 17 00:00:00 2001
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Date: Mon, 6 Jul 2026 17:28:36 +0800
+Subject: can: peak_usb: validate uCAN receive record lengths
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+commit 93fcab2c6968446316bbb49548848df604d6346f upstream.
+
+pcan_usb_fd_decode_buf() walks uCAN records packed in one USB
+receive buffer.
+
+Require each record to contain the fixed header for its type, and verify
+CAN payload bytes before copying them into the skb.
+
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Link: https://patch.msgid.link/20260706092836.79754-1-pengpeng@iscas.ac.cn
+Fixes: 0a25e1f4f185 ("can: peak_usb: add support for PEAK new CANFD USB adapters")
+Cc: stable@vger.kernel.org
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 40 ++++++++++++++++++++++++++++-
+ 1 file changed, 39 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
++++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+@@ -519,6 +519,13 @@ static int pcan_usb_fd_decode_canmsg(str
+ dev->can.ctrlmode);
+ }
+
++ if (!(rx_msg_flags & PUCAN_MSG_RTR) &&
++ le16_to_cpu(rx_msg->size) - offsetof(struct pucan_rx_msg, d) <
++ cfd->len) {
++ kfree_skb(skb);
++ return -EBADMSG;
++ }
++
+ cfd->can_id = le32_to_cpu(rm->can_id);
+
+ if (rx_msg_flags & PUCAN_MSG_EXT_ID)
+@@ -667,6 +674,24 @@ static void pcan_usb_fd_decode_ts(struct
+ peak_usb_set_ts_now(&usb_if->time_ref, le32_to_cpu(ts->ts_low));
+ }
+
++static size_t pcan_usb_fd_rx_msg_min_size(u16 rx_msg_type)
++{
++ switch (rx_msg_type) {
++ case PUCAN_MSG_CAN_RX:
++ return offsetof(struct pucan_rx_msg, d);
++ case PCAN_UFD_MSG_CALIBRATION:
++ return sizeof(struct pcan_ufd_ts_msg);
++ case PUCAN_MSG_ERROR:
++ return sizeof(struct pucan_error_msg);
++ case PUCAN_MSG_STATUS:
++ return sizeof(struct pucan_status_msg);
++ case PCAN_UFD_MSG_OVERRUN:
++ return sizeof(struct pcan_ufd_ovr_msg);
++ default:
++ return sizeof(struct pucan_msg);
++ }
++}
++
+ /* callback for bulk IN urb */
+ static int pcan_usb_fd_decode_buf(struct peak_usb_device *dev, struct urb *urb)
+ {
+@@ -681,6 +706,12 @@ static int pcan_usb_fd_decode_buf(struct
+ msg_end = urb->transfer_buffer + urb->actual_length;
+ for (; msg_ptr < msg_end;) {
+ u16 rx_msg_type, rx_msg_size;
++ size_t rx_msg_min_size;
++
++ if (msg_end - msg_ptr < sizeof(*rx_msg)) {
++ err = -EBADMSG;
++ break;
++ }
+
+ rx_msg = (struct pucan_msg *)msg_ptr;
+ if (!rx_msg->size) {
+@@ -692,12 +723,19 @@ static int pcan_usb_fd_decode_buf(struct
+ rx_msg_type = le16_to_cpu(rx_msg->type);
+
+ /* check if the record goes out of current packet */
+- if (msg_ptr + rx_msg_size > msg_end) {
++ if (rx_msg_size > msg_end - msg_ptr) {
+ netdev_err(netdev,
+ "got frag rec: should inc usb rx buf sze\n");
+ err = -EBADMSG;
+ break;
+ }
++
++ rx_msg_min_size = pcan_usb_fd_rx_msg_min_size(rx_msg_type);
++ if (rx_msg_size < rx_msg_min_size) {
++ netdev_err(netdev, "got short rec\n");
++ err = -EBADMSG;
++ break;
++ }
+
+ switch (rx_msg_type) {
+ case PUCAN_MSG_CAN_RX:
--- /dev/null
+From 856d6cb04e5407523566b075841dcd6423757d1c Mon Sep 17 00:00:00 2001
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Date: Wed, 22 Jul 2026 12:43:47 +0800
+Subject: can: softing: fw_parse(): validate firmware record spans
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+commit 856d6cb04e5407523566b075841dcd6423757d1c upstream.
+
+fw_parse() reads a fixed record header, a firmware-provided payload,
+and a trailing checksum without knowing the end of the firmware blob. A
+truncated record can therefore make those reads exceed the blob.
+
+The same record also supplies addresses and lengths for writes into
+DPRAM. The generic loader uses wrap-prone mixed signed arithmetic for its
+bounds check, while the application loader does not bound the staging
+copy at all.
+
+Pass the firmware end to the parser and validate the full source record.
+Use a signed wide offset for generic DPRAM records and validate the
+application staging span against the mapped DPRAM before copying.
+
+Fixes: 03fd3cf5a179 ("can: add driver for Softing card")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Link: https://patch.msgid.link/20260722044347.2708-1-pengpeng@iscas.ac.cn
+Cc: stable@kernel.org
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/softing/softing_fw.c | 46 ++++++++++++++++++++++++-----------
+ 1 file changed, 32 insertions(+), 14 deletions(-)
+
+--- a/drivers/net/can/softing/softing_fw.c
++++ b/drivers/net/can/softing/softing_fw.c
+@@ -91,12 +91,12 @@ int softing_bootloader_command(struct so
+ return ret;
+ }
+
+-static int fw_parse(const uint8_t **pmem, uint16_t *ptype, uint32_t *paddr,
+- uint16_t *plen, const uint8_t **pdat)
++static int fw_parse(const u8 **pmem, const u8 *limit, u16 *ptype,
++ u32 *paddr, u16 *plen, const u8 **pdat)
+ {
+ uint16_t checksum[2];
+- const uint8_t *mem;
+- const uint8_t *end;
++ const u8 *mem;
++ const u8 *record_end;
+
+ /*
+ * firmware records are a binary, unaligned stream composed of:
+@@ -114,14 +114,21 @@ static int fw_parse(const uint8_t **pmem
+ * endianness & alignment.
+ */
+ mem = *pmem;
++ /* A record needs an 8-byte prefix and a 2-byte checksum. */
++ if (mem > limit || limit - mem < 10)
++ return -EINVAL;
++
+ *ptype = le16_to_cpup((void *)&mem[0]);
+ *paddr = le32_to_cpup((void *)&mem[2]);
+ *plen = le16_to_cpup((void *)&mem[6]);
++ if (*plen > limit - mem - 10)
++ return -EINVAL;
++
+ *pdat = &mem[8];
+ /* verify checksum */
+- end = &mem[8 + *plen];
+- checksum[0] = le16_to_cpup((void *)end);
+- for (checksum[1] = 0; mem < end; ++mem)
++ record_end = &mem[8 + *plen];
++ checksum[0] = le16_to_cpup((void *)record_end);
++ for (checksum[1] = 0; mem < record_end; ++mem)
+ checksum[1] += *mem;
+ if (checksum[0] != checksum[1])
+ return -EINVAL;
+@@ -139,6 +146,7 @@ int softing_load_fw(const char *file, st
+ uint16_t type, len;
+ uint32_t addr;
+ uint8_t *buf = NULL, *new_buf;
++ s64 dpram_offset;
+ int buflen = 0;
+ int8_t type_end = 0;
+
+@@ -153,7 +161,7 @@ int softing_load_fw(const char *file, st
+ mem = fw->data;
+ end = &mem[fw->size];
+ /* look for header record */
+- ret = fw_parse(&mem, &type, &addr, &len, &dat);
++ ret = fw_parse(&mem, end, &type, &addr, &len, &dat);
+ if (ret < 0)
+ goto failed;
+ if (type != 0xffff)
+@@ -164,7 +172,7 @@ int softing_load_fw(const char *file, st
+ }
+ /* ok, we had a header */
+ while (mem < end) {
+- ret = fw_parse(&mem, &type, &addr, &len, &dat);
++ ret = fw_parse(&mem, end, &type, &addr, &len, &dat);
+ if (ret < 0)
+ goto failed;
+ if (type == 3) {
+@@ -179,9 +187,13 @@ int softing_load_fw(const char *file, st
+ goto failed;
+ }
+
+- if ((addr + len + offset) > size)
++ dpram_offset = (s64)addr + offset;
++ if (dpram_offset < 0 || dpram_offset > size ||
++ len > size - dpram_offset) {
++ ret = -EINVAL;
+ goto failed;
+- memcpy_toio(&dpram[addr + offset], dat, len);
++ }
++ memcpy_toio(&dpram[dpram_offset], dat, len);
+ /* be sure to flush caches from IO space */
+ mb();
+ if (len > buflen) {
+@@ -195,7 +207,7 @@ int softing_load_fw(const char *file, st
+ buf = new_buf;
+ }
+ /* verify record data */
+- memcpy_fromio(buf, &dpram[addr + offset], len);
++ memcpy_fromio(buf, &dpram[dpram_offset], len);
+ if (memcmp(buf, dat, len)) {
+ /* is not ok */
+ dev_alert(&card->pdev->dev, "DPRAM readback failed\n");
+@@ -237,7 +249,7 @@ int softing_load_app_fw(const char *file
+ mem = fw->data;
+ end = &mem[fw->size];
+ /* look for header record */
+- ret = fw_parse(&mem, &type, &addr, &len, &dat);
++ ret = fw_parse(&mem, end, &type, &addr, &len, &dat);
+ if (ret)
+ goto failed;
+ ret = -EINVAL;
+@@ -253,7 +265,7 @@ int softing_load_app_fw(const char *file
+ }
+ /* ok, we had a header */
+ while (mem < end) {
+- ret = fw_parse(&mem, &type, &addr, &len, &dat);
++ ret = fw_parse(&mem, end, &type, &addr, &len, &dat);
+ if (ret)
+ goto failed;
+
+@@ -279,6 +291,12 @@ int softing_load_app_fw(const char *file
+ /* work in 16bit (target) */
+ sum &= 0xffff;
+
++ if (card->pdat->app.offs > card->dpram_size ||
++ len > card->dpram_size - card->pdat->app.offs) {
++ ret = -EINVAL;
++ goto failed;
++ }
++
+ memcpy_toio(&card->dpram[card->pdat->app.offs], dat, len);
+ iowrite32(card->pdat->app.offs + card->pdat->app.addr,
+ &card->dpram[DPRAM_COMMAND + 2]);
--- /dev/null
+From 5e70f6804b4d6256058c360b10e044ee04ea4a4e Mon Sep 17 00:00:00 2001
+From: Harkirat Gill <harkirat.gill@amd.com>
+Date: Mon, 27 Jul 2026 14:37:56 -0400
+Subject: drm/amdgpu: cap GTT size to physical RAM on APUs
+
+From: Harkirat Gill <harkirat.gill@amd.com>
+
+commit 5e70f6804b4d6256058c360b10e044ee04ea4a4e upstream.
+
+On APUs, the GTT pool is backed by system RAM, but its size is not bound
+to the non-carveout memory that actually backs it. A user can end up
+with GTT + VRAM exceeding total physical memory through the following
+sequence:
+
+ - Have a large non-carveout memory space (~128GB) and accordingly set a
+ large GTT (~100GB) via the ttm module parameter.
+ - Lower the non-carveout memory space in BIOS by increasing the UMA
+ Frame Buffer Size (VRAM) to 64GB.
+ - The previously set GTT value (~100GB) persists, even though the new
+ non-carveout space (64GB) can no longer back it.
+
+This leads to a case where kernel reports GTT (100GB) + VRAM (64GB)
+despite the sum being greater than total physical memory (128GB).
+
+Cap the GTT size to totalram_pages() on APUs. totalram_pages() already
+excludes the VRAM carveout, so the resulting GTT can never exceed the
+system RAM that actually backs it.
+
+Signed-off-by: Harkirat Gill <harkirat.gill@amd.com>
+Reviewed-by: David Francis <David.Francis@amd.com>
+Assisted-by: Claude:claude-opus-4
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 5dafdd649280c7dc6c22c8f877da3f54fcc441e1)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+@@ -1862,6 +1862,18 @@ int amdgpu_ttm_init(struct amdgpu_device
+ gtt_size = (uint64_t)amdgpu_gtt_size << 20;
+ }
+
++ /* Cap GTT so that it does not exceed total physical RAM. */
++ if (adev->flags & AMD_IS_APU) {
++ u64 phys_ram = (u64)totalram_pages() << PAGE_SHIFT;
++
++ if (gtt_size > phys_ram) {
++ gtt_size = phys_ram;
++ dev_info(adev->dev,
++ "Capping GTT to %uM to not exceed available system memory\n",
++ (unsigned int)(gtt_size / (1024 * 1024)));
++ }
++ }
++
+ /* Initialize GTT memory pool */
+ r = amdgpu_gtt_mgr_init(adev, gtt_size);
+ if (r) {
--- /dev/null
+From f931c54b241ce2f36bfc34955aec43a188276b8d Mon Sep 17 00:00:00 2001
+From: Candice Li <candice.li@amd.com>
+Date: Tue, 21 Jul 2026 21:38:58 +0800
+Subject: drm/amdgpu: restore UMD profile pstate after runtime resume
+
+From: Candice Li <candice.li@amd.com>
+
+commit f931c54b241ce2f36bfc34955aec43a188276b8d upstream.
+
+Runtime suspend runs GFX hw_fini and clears perfmon clock gating while
+the UMD profile DPM level remains set in software. Re-apply stable
+pstate after a successful runtime resume when a profile mode is active.
+
+Signed-off-by: Candice Li <candice.li@amd.com>
+Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
+Reviewed-by: Yang Wang <kevinyang.wang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 138531c8850cc247aa12b104bb29ea387bcdcbb1)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+@@ -2637,6 +2637,19 @@ static int amdgpu_pmops_runtime_suspend(
+ return 0;
+ }
+
++static void amdgpu_restore_umd_profile_pstate_after_runpm(struct amdgpu_device *adev)
++{
++ enum amd_dpm_forced_level level;
++ uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD |
++ AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK |
++ AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK |
++ AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
++
++ level = amdgpu_dpm_get_performance_level(adev);
++ if (level & profile_mode_mask)
++ amdgpu_asic_update_umd_stable_pstate(adev, true);
++}
++
+ static int amdgpu_pmops_runtime_resume(struct device *dev)
+ {
+ struct pci_dev *pdev = to_pci_dev(dev);
+@@ -2680,6 +2693,8 @@ static int amdgpu_pmops_runtime_resume(s
+
+ if (amdgpu_device_supports_px(drm_dev))
+ drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
++
++ amdgpu_restore_umd_profile_pstate_after_runpm(adev);
+ adev->in_runpm = false;
+ return 0;
+ }
--- /dev/null
+From e40e20ac089e32f1d910636155dc82e61e61dcf3 Mon Sep 17 00:00:00 2001
+From: Alexander Kaplan <alexander.kaplan@sms-medipool.de>
+Date: Wed, 10 Jun 2026 21:38:25 +0200
+Subject: drm/dp: Read the PCON max FRL bandwidth only for HDMI DFPs
+
+From: Alexander Kaplan <alexander.kaplan@sms-medipool.de>
+
+commit e40e20ac089e32f1d910636155dc82e61e61dcf3 upstream.
+
+The PCON max FRL bandwidth field lives in byte 2 of the DFP Detailed
+Capability Info (DPCD 0x82 for the first DFP).
+The DP standard defines the meaning of descriptor bytes 1-3 strictly
+per DFP type, and for a DisplayPort type DFP all of them are
+reserved, with "read all 0s" semantics (DP v2.0, section 2.12.3,
+Table 2-183).
+The FRL bandwidth field is an HDMI DFP extension added by the VESA
+DP-to-HDMI PCON specification.
+drm_dp_get_pcon_max_frl_bw() however parses the byte without checking
+the DFP type, the branch presence or DETAILED_CAP_INFO_AVAILABLE.
+Without the latter the port descriptors are one byte wide and
+port_cap[2] is not even the right register.
+
+All neighbouring helpers parsing the same descriptor are scoped by
+the DFP type already, see for instance drm_dp_downstream_max_bpc()
+reading the same byte and returning 0 for a DP type DFP.
+amdgpu's DC parses the field only for HDMI(/DP++) detailed types as
+well.
+
+This is not theoretical.
+A Synaptics VMM7100 based USB-C to HDMI adapter with a macOS targeted
+firmware advertises a DisplayPort type DFP with the type byte
+replicated across the whole descriptor (08 08 08 08).
+i915 decodes that as "PCON limited to 18 Gbps FRL" and prunes every
+mode above ~750 MHz dotclock, including all the 4k@100/120 modes the
+sink EDID offers, while macOS drives 4k@120 through the same adapter
+just fine via DP DSC (and amdgpu's type-scoped parser would ignore
+the bogus field as well).
+
+Only parse the field for an HDMI DFP behind a DPCD 1.1+ branch
+device that reports detailed cap info, matching the type-scoped
+field layout of the spec and the rest of the helpers.
+
+Fixes: ce32a6239de6 ("drm/dp_helper: Add Helpers for FRL Link Training support for DP-HDMI2.1 PCON")
+Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
+Cc: Uma Shankar <uma.shankar@intel.com> (v2)
+Cc: Jani Nikula <jani.nikula@intel.com>
+Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Cc: dri-devel@lists.freedesktop.org
+Cc: <stable@vger.kernel.org> # v5.12+
+Signed-off-by: Alexander Kaplan <alexander.kaplan@sms-medipool.de>
+Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
+Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
+Link: https://patch.msgid.link/20260610193825.2933-1-alexander.kaplan@sms-medipool.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/display/drm_dp_helper.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/gpu/drm/display/drm_dp_helper.c
++++ b/drivers/gpu/drm/display/drm_dp_helper.c
+@@ -2930,6 +2930,18 @@ int drm_dp_get_pcon_max_frl_bw(const u8
+ int bw;
+ u8 buf;
+
++ if (!drm_dp_is_branch(dpcd))
++ return 0;
++
++ if (dpcd[DP_DPCD_REV] < 0x11)
++ return 0;
++
++ if ((dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE) == 0)
++ return 0;
++
++ if ((port_cap[0] & DP_DS_PORT_TYPE_MASK) != DP_DS_PORT_TYPE_HDMI)
++ return 0;
++
+ buf = port_cap[2];
+ bw = buf & DP_PCON_MAX_FRL_BW;
+
--- /dev/null
+From 6395789e4739aa5177bbec0fa0f07ccc38d249b0 Mon Sep 17 00:00:00 2001
+From: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
+Date: Mon, 27 Jul 2026 11:32:28 -0300
+Subject: drm/vc4: Supply the overflow slot size in BPOS, not the whole bin BO size
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
+
+commit 6395789e4739aa5177bbec0fa0f07ccc38d249b0 upstream.
+
+vc4_overflow_mem_work() points BPOA at a 512KB slot inside the 16MB
+binner BO, but writes the size of the whole BO to BPOS. On every binner
+out-of-memory event the PTB is therefore authorized to write tile lists
+across all the other slots (which may hold the tile state, tile alloc and
+overflow memory of in-flight jobs) and, for any slot but the first, past
+the end of the binner BO into unrelated CMA memory.
+
+Since CMA pages are recycled into page cache and user allocations, this
+is arbitrary memory corruption by GPU DMA. In practice it shows up as GPU
+hangs with corrupted control list pointers, userspace heap corruption, a
+GPU that stays permanently wedged after the first hang, and occasional
+full system crashes, whenever a job overflows the initial binner slot.
+
+The bug dates back to the conversion from a dedicated overflow BO (where
+writing the full BO size was correct) to the slotted binner BO.
+
+Fixes: 553c942f8b2c ("drm/vc4: Allow using more than 256MB of CMA memory.")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
+Reviewed-by: Maíra Canal <mcanal@igalia.com>
+Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
+Link: https://patch.msgid.link/20260727-vc4-bin-oom-fixes-v2-1-0d8a5eddc7c9@igalia.com
+Signed-off-by: Maíra Canal <mcanal@igalia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/vc4/vc4_irq.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_irq.c
++++ b/drivers/gpu/drm/vc4/vc4_irq.c
+@@ -106,7 +106,7 @@ vc4_overflow_mem_work(struct work_struct
+ vc4->bin_alloc_overflow = BIT(bin_bo_slot);
+
+ V3D_WRITE(V3D_BPOA, bo->base.dma_addr + bin_bo_slot * vc4->bin_alloc_size);
+- V3D_WRITE(V3D_BPOS, bo->base.base.size);
++ V3D_WRITE(V3D_BPOS, vc4->bin_alloc_size);
+ V3D_WRITE(V3D_INTCTL, V3D_INT_OUTOMEM);
+ V3D_WRITE(V3D_INTENA, V3D_INT_OUTOMEM);
+ spin_unlock_irqrestore(&vc4->job_lock, irqflags);
--- /dev/null
+From 48a570c964d8e37d353381e4195106277e17f5cb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ma=C3=ADra=20Canal?= <mcanal@igalia.com>
+Date: Mon, 27 Jul 2026 11:32:29 -0300
+Subject: drm/vc4: Zero the tile state data array before each BIN job
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maíra Canal <mcanal@igalia.com>
+
+commit 48a570c964d8e37d353381e4195106277e17f5cb upstream.
+
+The binner BO is a single 16MB buffer split into 512KB slots that are
+handed out to jobs at submission time and recycled as jobs complete,
+without ever being cleared. Each slot holds the job's Tile State Data
+Array (TSDA) at its start, followed by the tile allocation pool.
+
+While the tile allocation pool is only walked by the render thread
+through branches the binner generated during the current job, the
+TSDA is the PTB's own per-tile bookkeeping and is consumed by the
+hardware itself. Although the kernel sets the "Auto-initialise Tile
+State Data Array" flag in the tile binning mode configuration, the
+PTB demonstrably still acts on stale tile state left by the slot's
+previous user: the binner ends up creating invalid command streams
+with invalid primitive streams and branches, which can cause GPU hangs
+as observed in [1][2].
+
+Zero the TSDA when the job's binning slot is configured. This clears
+48 bytes per tile (~24KB for a 1080p frame) in the submission path, and
+guarantees the PTB never sees another job's tile state.
+
+The tile count is only checked for being non-zero today, so the 8-bit
+fields it comes from can describe a tile state array almost six times
+larger than the slot it has to live in. Bound it before the slot is
+handed out, since such size decides how much of the slot is left for
+the tile alloc pool.
+
+Link: https://github.com/raspberrypi/linux/issues/3221 [1]
+Link: https://github.com/raspberrypi/linux/issues/5780 [2]
+Fixes: 553c942f8b2c ("drm/vc4: Allow using more than 256MB of CMA memory.")
+Cc: stable@vger.kernel.org
+Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
+Link: https://patch.msgid.link/20260727-vc4-bin-oom-fixes-v2-2-0d8a5eddc7c9@igalia.com
+Signed-off-by: Maíra Canal <mcanal@igalia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/vc4/vc4_validate.c | 29 +++++++++++++++++++++++------
+ 1 file changed, 23 insertions(+), 6 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_validate.c
++++ b/drivers/gpu/drm/vc4/vc4_validate.c
+@@ -387,6 +387,23 @@ validate_tile_binning_config(VALIDATE_AR
+ return -EINVAL;
+ }
+
++ /* The tile state data array is 48 bytes per tile, and we put it at
++ * the start of a BO containing both it and the tile alloc.
++ */
++ tile_state_size = 48 * tile_count;
++
++ /* Since the tile alloc array will follow us, align. */
++ tile_state_size = roundup(tile_state_size, 4096);
++
++ /* Reject configurations whose tile state would leave no room for
++ * the tile alloc pool that follows it in the slot.
++ */
++ if (tile_state_size >= vc4->bin_alloc_size) {
++ DRM_DEBUG("Tile binning config of %dx%d too large\n",
++ exec->bin_tiles_x, exec->bin_tiles_y);
++ return -EINVAL;
++ }
++
+ bin_slot = vc4_v3d_get_bin_slot(vc4);
+ if (bin_slot < 0) {
+ if (bin_slot != -EINTR && bin_slot != -ERESTARTSYS) {
+@@ -402,13 +419,13 @@ validate_tile_binning_config(VALIDATE_AR
+ exec->bin_slots |= BIT(bin_slot);
+ bin_addr = vc4->bin_bo->base.dma_addr + bin_slot * vc4->bin_alloc_size;
+
+- /* The tile state data array is 48 bytes per tile, and we put it at
+- * the start of a BO containing both it and the tile alloc.
+- */
+- tile_state_size = 48 * tile_count;
++ exec->tile_alloc_offset = bin_addr + tile_state_size;
+
+- /* Since the tile alloc array will follow us, align. */
+- exec->tile_alloc_offset = bin_addr + roundup(tile_state_size, 4096);
++ /* The TSDA area must be zeroed out before use, otherwise the PTB might
++ * consume a stale tile state.
++ */
++ memset(vc4->bin_bo->base.vaddr + bin_slot * vc4->bin_alloc_size, 0,
++ tile_state_size);
+
+ *(uint8_t *)(validated + 14) =
+ ((flags & ~(VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_MASK |
i2c-jz4780-cache-host-clock-rate-at-probe-to-prevent-ccf-prepare_lock-deadlock.patch
i2c-imx-fix-slave-registration-race-and-error-handling.patch
i2c-imx-cancel-hrtimer-before-clearing-slave-pointer.patch
+can-c_can-c_can_chip_config-keep-controller-in-init-mode-until-bittiming-is-configured.patch
+can-ems_usb-validate-cpc-message-lengths.patch
+can-etas_es58x-es58x_read_bulk_callback-fix-rx-buffer-leak-on-urb-resubmit-failure.patch
+can-j1939-transport-j1939_session_fresh_new-initialize-receive-buffer.patch
+can-j1939-use-netdevice_tracker-for-j1939_-priv-session-ecu-tracking.patch
+can-kvaser_usb-kvaser_usb_hydra_get_busparams-fix-memory-leak-in-kvaser_usb_hydra_get_busparams.patch
+can-kvaser_usb_leaf-kvaser_usb_leaf_wait_cmd-validate-received-command-extents.patch
+can-softing-fw_parse-validate-firmware-record-spans.patch
+can-peak_usb-add-bounds-check-for-usb-channel-index.patch
+can-peak_usb-peak_usb_start-fix-double-free-of-transfer-buffer-on-urb-submit-error.patch
+can-peak_usb-validate-ucan-receive-record-lengths.patch
+can-ctucanfd-add-missing-module_device_table.patch
+can-ctucanfd-use-self-test-mode-for-presume_ack.patch
+can-ctucanfd-unmap-bar0-using-base-address.patch
+can-ctucanfd-handle-bus-error-interrupts.patch
+can-ctucanfd-mark-error-active-controller-status-valid.patch
+drm-dp-read-the-pcon-max-frl-bandwidth-only-for-hdmi-dfps.patch
+drm-vc4-supply-the-overflow-slot-size-in-bpos-not-the-whole-bin-bo-size.patch
+drm-vc4-zero-the-tile-state-data-array-before-each-bin-job.patch
+drm-amdgpu-restore-umd-profile-pstate-after-runtime-resume.patch
+drm-amdgpu-cap-gtt-size-to-physical-ram-on-apus.patch