--- /dev/null
+From b326aa76d1d11c1df4365de1f1174262c5f655c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Nov 2024 23:15:42 +0100
+Subject: can: c_can: c_can_handle_bus_err(): update statistics if skb
+ allocation fails
+
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+[ Upstream commit 9e66242504f49e17481d8e197730faba7d99c934 ]
+
+Ensure that the statistics are always updated, even if the skb
+allocation fails.
+
+Fixes: 4d6d26537940 ("can: c_can: fix {rx,tx}_errors statistics")
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Link: https://patch.msgid.link/20241122221650.633981-2-dario.binacchi@amarulasolutions.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/c_can/c_can_main.c | 26 +++++++++++++++++---------
+ 1 file changed, 17 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/can/c_can/c_can_main.c b/drivers/net/can/c_can/c_can_main.c
+index d9595eb3e125f..875ac76bc5fdd 100644
+--- a/drivers/net/can/c_can/c_can_main.c
++++ b/drivers/net/can/c_can/c_can_main.c
+@@ -1022,49 +1022,57 @@ static int c_can_handle_bus_err(struct net_device *dev,
+
+ /* propagate the error condition to the CAN stack */
+ skb = alloc_can_err_skb(dev, &cf);
+- if (unlikely(!skb))
+- return 0;
+
+ /* check for 'last error code' which tells us the
+ * type of the last error to occur on the CAN bus
+ */
+- cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
++ if (likely(skb))
++ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+
+ switch (lec_type) {
+ case LEC_STUFF_ERROR:
+ netdev_dbg(dev, "stuff error\n");
+- cf->data[2] |= CAN_ERR_PROT_STUFF;
++ if (likely(skb))
++ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ stats->rx_errors++;
+ break;
+ case LEC_FORM_ERROR:
+ netdev_dbg(dev, "form error\n");
+- cf->data[2] |= CAN_ERR_PROT_FORM;
++ if (likely(skb))
++ cf->data[2] |= CAN_ERR_PROT_FORM;
+ stats->rx_errors++;
+ break;
+ case LEC_ACK_ERROR:
+ netdev_dbg(dev, "ack error\n");
+- cf->data[3] = CAN_ERR_PROT_LOC_ACK;
++ if (likely(skb))
++ cf->data[3] = CAN_ERR_PROT_LOC_ACK;
+ stats->tx_errors++;
+ break;
+ case LEC_BIT1_ERROR:
+ netdev_dbg(dev, "bit1 error\n");
+- cf->data[2] |= CAN_ERR_PROT_BIT1;
++ if (likely(skb))
++ cf->data[2] |= CAN_ERR_PROT_BIT1;
+ stats->tx_errors++;
+ break;
+ case LEC_BIT0_ERROR:
+ netdev_dbg(dev, "bit0 error\n");
+- cf->data[2] |= CAN_ERR_PROT_BIT0;
++ if (likely(skb))
++ cf->data[2] |= CAN_ERR_PROT_BIT0;
+ stats->tx_errors++;
+ break;
+ case LEC_CRC_ERROR:
+ netdev_dbg(dev, "CRC error\n");
+- cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
++ if (likely(skb))
++ cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+ stats->rx_errors++;
+ break;
+ default:
+ break;
+ }
+
++ if (unlikely(!skb))
++ return 0;
++
+ netif_receive_skb(skb);
+ return 1;
+ }
+--
+2.43.0
+
--- /dev/null
+From d70d4ed68726d5f383bb35554b3c3e1fe919c7e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Dec 2021 21:15:27 +0900
+Subject: can: do not increase rx statistics when generating a CAN rx error
+ message frame
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit 676068db69b847f06fe054fca15bf6b107bd24da ]
+
+The CAN error message frames (i.e. error skb) are an interface
+specific to socket CAN. The payload of the CAN error message frames
+does not correspond to any actual data sent on the wire. Only an error
+flag and a delimiter are transmitted when an error occurs (c.f. ISO
+11898-1 section 10.4.4.2 "Error flag").
+
+For this reason, it makes no sense to increment the rx_packets and
+rx_bytes fields of struct net_device_stats because no actual payload
+were transmitted on the wire.
+
+This patch fixes all the CAN drivers.
+
+Link: https://lore.kernel.org/all/20211207121531.42941-2-mailhol.vincent@wanadoo.fr
+CC: Marc Kleine-Budde <mkl@pengutronix.de>
+CC: Nicolas Ferre <nicolas.ferre@microchip.com>
+CC: Alexandre Belloni <alexandre.belloni@bootlin.com>
+CC: Ludovic Desroches <ludovic.desroches@microchip.com>
+CC: Chandrasekar Ramakrishnan <rcsekar@samsung.com>
+CC: Maxime Ripard <mripard@kernel.org>
+CC: Chen-Yu Tsai <wens@csie.org>
+CC: Jernej Skrabec <jernej.skrabec@gmail.com>
+CC: Appana Durga Kedareswara rao <appana.durga.rao@xilinx.com>
+CC: Naga Sureshkumar Relli <naga.sureshkumar.relli@xilinx.com>
+CC: Michal Simek <michal.simek@xilinx.com>
+CC: Stephane Grosjean <s.grosjean@peak-system.com>
+Tested-by: Jimmy Assarsson <extja@kvaser.com> # kvaser
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Acked-by: Stefan Mätje <stefan.maetje@esd.eu> # esd_usb2
+Tested-by: Stefan Mätje <stefan.maetje@esd.eu> # esd_usb2
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Stable-dep-of: 9e66242504f4 ("can: c_can: c_can_handle_bus_err(): update statistics if skb allocation fails")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/at91_can.c | 6 ------
+ drivers/net/can/c_can/c_can_main.c | 5 -----
+ drivers/net/can/cc770/cc770.c | 3 ---
+ drivers/net/can/dev/dev.c | 4 ----
+ drivers/net/can/dev/rx-offload.c | 6 ++++--
+ drivers/net/can/ifi_canfd/ifi_canfd.c | 5 -----
+ drivers/net/can/kvaser_pciefd.c | 5 -----
+ drivers/net/can/m_can/m_can.c | 7 -------
+ drivers/net/can/mscan/mscan.c | 9 +++++----
+ drivers/net/can/pch_can.c | 3 ---
+ drivers/net/can/peak_canfd/peak_canfd.c | 4 ----
+ drivers/net/can/rcar/rcar_can.c | 6 +-----
+ drivers/net/can/rcar/rcar_canfd.c | 4 ----
+ drivers/net/can/sja1000/sja1000.c | 2 --
+ drivers/net/can/sun4i_can.c | 7 ++-----
+ drivers/net/can/usb/ems_usb.c | 2 --
+ drivers/net/can/usb/esd_usb2.c | 2 --
+ drivers/net/can/usb/etas_es58x/es58x_core.c | 7 -------
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 2 --
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 8 --------
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 4 ----
+ drivers/net/can/usb/peak_usb/pcan_usb.c | 2 --
+ drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 3 ---
+ drivers/net/can/usb/peak_usb/pcan_usb_pro.c | 2 --
+ drivers/net/can/usb/ucan.c | 6 ++++--
+ drivers/net/can/usb/usb_8dev.c | 2 --
+ drivers/net/can/xilinx_can.c | 9 +--------
+ 27 files changed, 17 insertions(+), 108 deletions(-)
+
+diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
+index b06af90a99640..26cb3d8869789 100644
+--- a/drivers/net/can/at91_can.c
++++ b/drivers/net/can/at91_can.c
+@@ -553,8 +553,6 @@ static void at91_rx_overflow_err(struct net_device *dev)
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+ netif_receive_skb(skb);
+ }
+
+@@ -779,8 +777,6 @@ static int at91_poll_err(struct net_device *dev, int quota, u32 reg_sr)
+
+ at91_poll_err_frame(dev, cf, reg_sr);
+
+- dev->stats.rx_packets++;
+- dev->stats.rx_bytes += cf->len;
+ netif_receive_skb(skb);
+
+ return 1;
+@@ -1037,8 +1033,6 @@ static void at91_irq_err(struct net_device *dev)
+
+ at91_irq_err_state(dev, cf, new_state);
+
+- dev->stats.rx_packets++;
+- dev->stats.rx_bytes += cf->len;
+ netif_rx(skb);
+
+ priv->can.state = new_state;
+diff --git a/drivers/net/can/c_can/c_can_main.c b/drivers/net/can/c_can/c_can_main.c
+index 8ab43f1272bd9..d9595eb3e125f 100644
+--- a/drivers/net/can/c_can/c_can_main.c
++++ b/drivers/net/can/c_can/c_can_main.c
+@@ -919,7 +919,6 @@ static int c_can_handle_state_change(struct net_device *dev,
+ unsigned int reg_err_counter;
+ unsigned int rx_err_passive;
+ struct c_can_priv *priv = netdev_priv(dev);
+- struct net_device_stats *stats = &dev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ struct can_berr_counter bec;
+@@ -995,8 +994,6 @@ static int c_can_handle_state_change(struct net_device *dev,
+ break;
+ }
+
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+ netif_receive_skb(skb);
+
+ return 1;
+@@ -1068,8 +1065,6 @@ static int c_can_handle_bus_err(struct net_device *dev,
+ break;
+ }
+
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+ netif_receive_skb(skb);
+ return 1;
+ }
+diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
+index f8a130f594e2e..a5fd8ccedec21 100644
+--- a/drivers/net/can/cc770/cc770.c
++++ b/drivers/net/can/cc770/cc770.c
+@@ -499,7 +499,6 @@ static void cc770_rx(struct net_device *dev, unsigned int mo, u8 ctrl1)
+ static int cc770_err(struct net_device *dev, u8 status)
+ {
+ struct cc770_priv *priv = netdev_priv(dev);
+- struct net_device_stats *stats = &dev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ u8 lec;
+@@ -571,8 +570,6 @@ static int cc770_err(struct net_device *dev, u8 status)
+ }
+
+
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+ netif_rx(skb);
+
+ return 0;
+diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
+index 94916f2d24d41..62d3e4d1fe99e 100644
+--- a/drivers/net/can/dev/dev.c
++++ b/drivers/net/can/dev/dev.c
+@@ -136,7 +136,6 @@ EXPORT_SYMBOL_GPL(can_change_state);
+ static void can_restart(struct net_device *dev)
+ {
+ struct can_priv *priv = netdev_priv(dev);
+- struct net_device_stats *stats = &dev->stats;
+ struct sk_buff *skb;
+ struct can_frame *cf;
+ int err;
+@@ -156,9 +155,6 @@ static void can_restart(struct net_device *dev)
+
+ cf->can_id |= CAN_ERR_RESTARTED;
+
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+-
+ netif_rx_ni(skb);
+
+ restart:
+diff --git a/drivers/net/can/dev/rx-offload.c b/drivers/net/can/dev/rx-offload.c
+index 37b0cc65237b7..7dbf46b9ca5dd 100644
+--- a/drivers/net/can/dev/rx-offload.c
++++ b/drivers/net/can/dev/rx-offload.c
+@@ -54,8 +54,10 @@ static int can_rx_offload_napi_poll(struct napi_struct *napi, int quota)
+ struct can_frame *cf = (struct can_frame *)skb->data;
+
+ work_done++;
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
++ if (!(cf->can_id & CAN_ERR_FLAG)) {
++ stats->rx_packets++;
++ stats->rx_bytes += cf->len;
++ }
+ netif_receive_skb(skb);
+ }
+
+diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
+index 5bb957a26bc69..e8318e984bf2f 100644
+--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
++++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
+@@ -430,8 +430,6 @@ static int ifi_canfd_handle_lec_err(struct net_device *ndev)
+ priv->base + IFI_CANFD_INTERRUPT);
+ writel(IFI_CANFD_ERROR_CTR_ER_ENABLE, priv->base + IFI_CANFD_ERROR_CTR);
+
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+ netif_receive_skb(skb);
+
+ return 1;
+@@ -456,7 +454,6 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
+ enum can_state new_state)
+ {
+ struct ifi_canfd_priv *priv = netdev_priv(ndev);
+- struct net_device_stats *stats = &ndev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ struct can_berr_counter bec;
+@@ -522,8 +519,6 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
+ break;
+ }
+
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+ netif_receive_skb(skb);
+
+ return 1;
+diff --git a/drivers/net/can/kvaser_pciefd.c b/drivers/net/can/kvaser_pciefd.c
+index 477bc56b12060..26bc8c7ad75b9 100644
+--- a/drivers/net/can/kvaser_pciefd.c
++++ b/drivers/net/can/kvaser_pciefd.c
+@@ -1327,9 +1327,6 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can,
+ cf->data[6] = bec.txerr;
+ cf->data[7] = bec.rxerr;
+
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+-
+ netif_rx(skb);
+ return 0;
+ }
+@@ -1524,8 +1521,6 @@ static void kvaser_pciefd_handle_nack_packet(struct kvaser_pciefd_can *can,
+
+ if (skb) {
+ cf->can_id |= CAN_ERR_BUSERROR;
+- stats->rx_bytes += cf->len;
+- stats->rx_packets++;
+ netif_rx(skb);
+ } else {
+ stats->rx_dropped++;
+diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
+index a87f6ce86cea3..abc3907feb739 100644
+--- a/drivers/net/can/m_can/m_can.c
++++ b/drivers/net/can/m_can/m_can.c
+@@ -653,9 +653,6 @@ static int m_can_handle_lec_err(struct net_device *dev,
+ break;
+ }
+
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+-
+ if (cdev->is_peripheral)
+ timestamp = m_can_get_timestamp(cdev);
+
+@@ -712,7 +709,6 @@ static int m_can_handle_state_change(struct net_device *dev,
+ enum can_state new_state)
+ {
+ struct m_can_classdev *cdev = netdev_priv(dev);
+- struct net_device_stats *stats = &dev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ struct can_berr_counter bec;
+@@ -777,9 +773,6 @@ static int m_can_handle_state_change(struct net_device *dev,
+ break;
+ }
+
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+-
+ if (cdev->is_peripheral)
+ timestamp = m_can_get_timestamp(cdev);
+
+diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
+index fa32e418eb296..9e1cce0260da6 100644
+--- a/drivers/net/can/mscan/mscan.c
++++ b/drivers/net/can/mscan/mscan.c
+@@ -401,13 +401,14 @@ static int mscan_rx_poll(struct napi_struct *napi, int quota)
+ continue;
+ }
+
+- if (canrflg & MSCAN_RXF)
++ if (canrflg & MSCAN_RXF) {
+ mscan_get_rx_frame(dev, frame);
+- else if (canrflg & MSCAN_ERR_IF)
++ stats->rx_packets++;
++ stats->rx_bytes += frame->len;
++ } else if (canrflg & MSCAN_ERR_IF) {
+ mscan_get_err_frame(dev, frame, canrflg);
++ }
+
+- stats->rx_packets++;
+- stats->rx_bytes += frame->len;
+ work_done++;
+ netif_receive_skb(skb);
+ }
+diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
+index cd8d536c6fb20..da01ce36ed592 100644
+--- a/drivers/net/can/pch_can.c
++++ b/drivers/net/can/pch_can.c
+@@ -561,9 +561,6 @@ static void pch_can_error(struct net_device *ndev, u32 status)
+
+ priv->can.state = state;
+ netif_receive_skb(skb);
+-
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+ }
+
+ static irqreturn_t pch_can_interrupt(int irq, void *dev_id)
+diff --git a/drivers/net/can/peak_canfd/peak_canfd.c b/drivers/net/can/peak_canfd/peak_canfd.c
+index d08718e98e110..d5b8bc6d29804 100644
+--- a/drivers/net/can/peak_canfd/peak_canfd.c
++++ b/drivers/net/can/peak_canfd/peak_canfd.c
+@@ -409,8 +409,6 @@ static int pucan_handle_status(struct peak_canfd_priv *priv,
+ return -ENOMEM;
+ }
+
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+ pucan_netif_rx(skb, msg->ts_low, msg->ts_high);
+
+ return 0;
+@@ -438,8 +436,6 @@ static int pucan_handle_cache_critical(struct peak_canfd_priv *priv)
+ cf->data[6] = priv->bec.txerr;
+ cf->data[7] = priv->bec.rxerr;
+
+- stats->rx_bytes += cf->len;
+- stats->rx_packets++;
+ netif_rx(skb);
+
+ return 0;
+diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c
+index 945b319de841c..68ad7da5c07e0 100644
+--- a/drivers/net/can/rcar/rcar_can.c
++++ b/drivers/net/can/rcar/rcar_can.c
+@@ -223,7 +223,6 @@ static void tx_failure_cleanup(struct net_device *ndev)
+ static void rcar_can_error(struct net_device *ndev)
+ {
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+- struct net_device_stats *stats = &ndev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ u8 eifr, txerr = 0, rxerr = 0;
+@@ -362,11 +361,8 @@ static void rcar_can_error(struct net_device *ndev)
+ }
+ }
+
+- if (skb) {
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
++ if (skb)
+ netif_rx(skb);
+- }
+ }
+
+ static void rcar_can_tx_done(struct net_device *ndev)
+diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
+index 4e230e1456647..9d5b8cda8fc54 100644
+--- a/drivers/net/can/rcar/rcar_canfd.c
++++ b/drivers/net/can/rcar/rcar_canfd.c
+@@ -1033,8 +1033,6 @@ static void rcar_canfd_error(struct net_device *ndev, u32 cerfl,
+ /* Clear channel error interrupts that are handled */
+ rcar_canfd_write(priv->base, RCANFD_CERFL(ch),
+ RCANFD_CERFL_ERR(~cerfl));
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+ netif_rx(skb);
+ }
+
+@@ -1176,8 +1174,6 @@ static void rcar_canfd_state_change(struct net_device *ndev,
+ rx_state = txerr <= rxerr ? state : 0;
+
+ can_change_state(ndev, cf, tx_state, rx_state);
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+ netif_rx(skb);
+ }
+ }
+diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
+index aae2677e24f99..1e4c797679674 100644
+--- a/drivers/net/can/sja1000/sja1000.c
++++ b/drivers/net/can/sja1000/sja1000.c
+@@ -488,8 +488,6 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
+ can_bus_off(dev);
+ }
+
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+ netif_rx(skb);
+
+ return 0;
+diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
+index ad8f50807aca5..ab9adfe92a94b 100644
+--- a/drivers/net/can/sun4i_can.c
++++ b/drivers/net/can/sun4i_can.c
+@@ -621,13 +621,10 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
+ can_bus_off(dev);
+ }
+
+- if (likely(skb)) {
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
++ if (likely(skb))
+ netif_rx(skb);
+- } else {
++ else
+ return -ENOMEM;
+- }
+
+ return 0;
+ }
+diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
+index a1b7c1a451c0c..0581e70ab903e 100644
+--- a/drivers/net/can/usb/ems_usb.c
++++ b/drivers/net/can/usb/ems_usb.c
+@@ -397,8 +397,6 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg)
+ stats->rx_errors++;
+ }
+
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+ netif_rx(skb);
+ }
+
+diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c
+index 1abdf88597de0..14104cb02fb1a 100644
+--- a/drivers/net/can/usb/esd_usb2.c
++++ b/drivers/net/can/usb/esd_usb2.c
+@@ -301,8 +301,6 @@ static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv,
+ priv->bec.txerr = txerr;
+ priv->bec.rxerr = rxerr;
+
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+ netif_rx(skb);
+ }
+ }
+diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c
+index 0e6faf962ebbc..34d374d301e50 100644
+--- a/drivers/net/can/usb/etas_es58x/es58x_core.c
++++ b/drivers/net/can/usb/etas_es58x/es58x_core.c
+@@ -849,13 +849,6 @@ int es58x_rx_err_msg(struct net_device *netdev, enum es58x_err error,
+ break;
+ }
+
+- /* driver/net/can/dev.c:can_restart() takes in account error
+- * messages in the RX stats. Doing the same here for
+- * consistency.
+- */
+- netdev->stats.rx_packets++;
+- netdev->stats.rx_bytes += CAN_ERR_DLC;
+-
+ if (cf) {
+ if (cf->data[1])
+ cf->can_id |= CAN_ERR_CRTL;
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+index 95ed200553929..f6cb5ba61ac93 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+@@ -315,8 +315,6 @@ int kvaser_usb_can_rx_over_error(struct net_device *netdev)
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+ netif_rx(skb);
+
+ return 0;
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+index 562105b8a6327..684c9685ba613 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+@@ -922,7 +922,6 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv,
+ struct net_device *netdev = priv->netdev;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+- struct net_device_stats *stats;
+ enum can_state new_state, old_state;
+
+ old_state = priv->can.state;
+@@ -974,9 +973,6 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv,
+ cf->data[7] = bec->rxerr;
+ }
+
+- stats = &netdev->stats;
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+ netif_rx(skb);
+ }
+
+@@ -1131,8 +1127,6 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv,
+ cf->data[7] = bec.rxerr;
+ }
+
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+ netif_rx(skb);
+
+ priv->bec.txerr = bec.txerr;
+@@ -1166,8 +1160,6 @@ static void kvaser_usb_hydra_one_shot_fail(struct kvaser_usb_net_priv *priv,
+ }
+
+ stats->tx_errors++;
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+ netif_rx(skb);
+ }
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index ad3103391c793..43ec056646661 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -907,8 +907,6 @@ static void kvaser_usb_leaf_tx_acknowledge(const struct kvaser_usb *dev,
+ if (skb) {
+ cf->can_id |= CAN_ERR_RESTARTED;
+
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+ netif_rx(skb);
+ } else {
+ netdev_err(priv->netdev,
+@@ -1131,8 +1129,6 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
+ cf->data[7] = es->rxerr;
+ }
+
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+ netif_rx(skb);
+ }
+
+diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
+index af8d3dadbbb8b..d7adc313a6eda 100644
+--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
++++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
+@@ -520,8 +520,6 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n,
+ &hwts->hwtstamp);
+ }
+
+- mc->netdev->stats.rx_packets++;
+- mc->netdev->stats.rx_bytes += cf->len;
+ netif_rx(skb);
+
+ return 0;
+diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+index 6bd12549f1014..185f5a98d2177 100644
+--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
++++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+@@ -577,9 +577,6 @@ static int pcan_usb_fd_decode_status(struct pcan_usb_fd_if *usb_if,
+ if (!skb)
+ return -ENOMEM;
+
+- netdev->stats.rx_packets++;
+- netdev->stats.rx_bytes += cf->len;
+-
+ peak_usb_netif_rx_64(skb, le32_to_cpu(sm->ts_low),
+ le32_to_cpu(sm->ts_high));
+
+diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+index 858ab22708fcd..f6d19879bf404 100644
+--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
++++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+@@ -660,8 +660,6 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if,
+
+ hwts = skb_hwtstamps(skb);
+ peak_usb_get_ts_time(&usb_if->time_ref, le32_to_cpu(er->ts32), &hwts->hwtstamp);
+- netdev->stats.rx_packets++;
+- netdev->stats.rx_bytes += can_frame->len;
+ netif_rx(skb);
+
+ return 0;
+diff --git a/drivers/net/can/usb/ucan.c b/drivers/net/can/usb/ucan.c
+index 1679cbe45ded2..d582c39fc8d0e 100644
+--- a/drivers/net/can/usb/ucan.c
++++ b/drivers/net/can/usb/ucan.c
+@@ -621,8 +621,10 @@ static void ucan_rx_can_msg(struct ucan_priv *up, struct ucan_message_in *m)
+ memcpy(cf->data, m->msg.can_msg.data, cf->len);
+
+ /* don't count error frames as real packets */
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
++ if (!(cf->can_id & CAN_ERR_FLAG)) {
++ stats->rx_packets++;
++ stats->rx_bytes += cf->len;
++ }
+
+ /* pass it to Linux */
+ netif_rx(skb);
+diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c
+index a5dee2ee24656..3dbb689535d1e 100644
+--- a/drivers/net/can/usb/usb_8dev.c
++++ b/drivers/net/can/usb/usb_8dev.c
+@@ -450,8 +450,6 @@ static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv,
+ priv->bec.txerr = txerr;
+ priv->bec.rxerr = rxerr;
+
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
+ netif_rx(skb);
+ }
+
+diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
+index a2e751f0ae0b1..cb48598e32ad8 100644
+--- a/drivers/net/can/xilinx_can.c
++++ b/drivers/net/can/xilinx_can.c
+@@ -966,13 +966,8 @@ static void xcan_update_error_state_after_rxtx(struct net_device *ndev)
+
+ xcan_set_error_state(ndev, new_state, skb ? cf : NULL);
+
+- if (skb) {
+- struct net_device_stats *stats = &ndev->stats;
+-
+- stats->rx_packets++;
+- stats->rx_bytes += cf->len;
++ if (skb)
+ netif_rx(skb);
+- }
+ }
+ }
+
+@@ -1096,8 +1091,6 @@ static void xcan_err_interrupt(struct net_device *ndev, u32 isr)
+ if (skb) {
+ skb_cf->can_id |= cf.can_id;
+ memcpy(skb_cf->data, cf.data, CAN_ERR_DLC);
+- stats->rx_packets++;
+- stats->rx_bytes += CAN_ERR_DLC;
+ netif_rx(skb);
+ }
+ }
+--
+2.43.0
+
--- /dev/null
+From 072fc358c93d4fdc6b9f4a57ac0b33f3fd10d1de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Nov 2024 23:15:52 +0100
+Subject: can: ems_usb: ems_usb_rx_err(): fix {rx,tx}_errors statistics
+
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+[ Upstream commit 72a7e2e74b3075959f05e622bae09b115957dffe ]
+
+The ems_usb_rx_err() function only incremented the receive error counter
+and never the transmit error counter, even if the ECC_DIR flag reported
+that an error had occurred during transmission.
+
+Increment the receive/transmit error counter based on the value of the
+ECC_DIR flag.
+
+Fixes: 702171adeed3 ("ems_usb: Added support for EMS CPC-USB/ARM7 CAN/USB interface")
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Link: https://patch.msgid.link/20241122221650.633981-12-dario.binacchi@amarulasolutions.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/ems_usb.c | 58 ++++++++++++++++++++---------------
+ 1 file changed, 33 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
+index 0581e70ab903e..af81ccc9572bc 100644
+--- a/drivers/net/can/usb/ems_usb.c
++++ b/drivers/net/can/usb/ems_usb.c
+@@ -334,15 +334,14 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg)
+ struct net_device_stats *stats = &dev->netdev->stats;
+
+ skb = alloc_can_err_skb(dev->netdev, &cf);
+- if (skb == NULL)
+- return;
+
+ if (msg->type == CPC_MSG_TYPE_CAN_STATE) {
+ u8 state = msg->msg.can_state;
+
+ if (state & SJA1000_SR_BS) {
+ dev->can.state = CAN_STATE_BUS_OFF;
+- cf->can_id |= CAN_ERR_BUSOFF;
++ if (skb)
++ cf->can_id |= CAN_ERR_BUSOFF;
+
+ dev->can.can_stats.bus_off++;
+ can_bus_off(dev->netdev);
+@@ -360,44 +359,53 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg)
+
+ /* bus error interrupt */
+ dev->can.can_stats.bus_error++;
+- stats->rx_errors++;
+
+- cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
++ if (skb) {
++ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+
+- switch (ecc & SJA1000_ECC_MASK) {
+- case SJA1000_ECC_BIT:
+- cf->data[2] |= CAN_ERR_PROT_BIT;
+- break;
+- case SJA1000_ECC_FORM:
+- cf->data[2] |= CAN_ERR_PROT_FORM;
+- break;
+- case SJA1000_ECC_STUFF:
+- cf->data[2] |= CAN_ERR_PROT_STUFF;
+- break;
+- default:
+- cf->data[3] = ecc & SJA1000_ECC_SEG;
+- break;
++ switch (ecc & SJA1000_ECC_MASK) {
++ case SJA1000_ECC_BIT:
++ cf->data[2] |= CAN_ERR_PROT_BIT;
++ break;
++ case SJA1000_ECC_FORM:
++ cf->data[2] |= CAN_ERR_PROT_FORM;
++ break;
++ case SJA1000_ECC_STUFF:
++ cf->data[2] |= CAN_ERR_PROT_STUFF;
++ break;
++ default:
++ cf->data[3] = ecc & SJA1000_ECC_SEG;
++ break;
++ }
+ }
+
+ /* Error occurred during transmission? */
+- if ((ecc & SJA1000_ECC_DIR) == 0)
+- cf->data[2] |= CAN_ERR_PROT_TX;
++ if ((ecc & SJA1000_ECC_DIR) == 0) {
++ stats->tx_errors++;
++ if (skb)
++ cf->data[2] |= CAN_ERR_PROT_TX;
++ } else {
++ stats->rx_errors++;
++ }
+
+- if (dev->can.state == CAN_STATE_ERROR_WARNING ||
+- dev->can.state == CAN_STATE_ERROR_PASSIVE) {
++ if (skb && (dev->can.state == CAN_STATE_ERROR_WARNING ||
++ dev->can.state == CAN_STATE_ERROR_PASSIVE)) {
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = (txerr > rxerr) ?
+ CAN_ERR_CRTL_TX_PASSIVE : CAN_ERR_CRTL_RX_PASSIVE;
+ }
+ } else if (msg->type == CPC_MSG_TYPE_OVERRUN) {
+- cf->can_id |= CAN_ERR_CRTL;
+- cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
++ if (skb) {
++ cf->can_id |= CAN_ERR_CRTL;
++ cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
++ }
+
+ stats->rx_over_errors++;
+ stats->rx_errors++;
+ }
+
+- netif_rx(skb);
++ if (skb)
++ netif_rx(skb);
+ }
+
+ /*
+--
+2.43.0
+
--- /dev/null
+From 50313bd214585aedf4dc1482aecbbb82568bc03c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Nov 2024 23:15:48 +0100
+Subject: can: ifi_canfd: ifi_canfd_handle_lec_err(): fix {rx,tx}_errors
+ statistics
+
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+[ Upstream commit bb03d568bb21b4afe7935d1943bcf68ddea3ea45 ]
+
+The ifi_canfd_handle_lec_err() function was incorrectly incrementing only
+the receive error counter, even in cases of bit or acknowledgment errors
+that occur during transmission.
+
+Fix the issue by incrementing the appropriate counter based on the
+type of error.
+
+Fixes: 5bbd655a8bd0 ("can: ifi: Add more detailed error reporting")
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Reviewed-by: Marek Vasut <marex@denx.de>
+Link: https://patch.msgid.link/20241122221650.633981-8-dario.binacchi@amarulasolutions.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/ifi_canfd/ifi_canfd.c | 58 ++++++++++++++++++---------
+ 1 file changed, 40 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
+index e8318e984bf2f..6a66d63f25c1d 100644
+--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
++++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
+@@ -393,36 +393,55 @@ static int ifi_canfd_handle_lec_err(struct net_device *ndev)
+ return 0;
+
+ priv->can.can_stats.bus_error++;
+- stats->rx_errors++;
+
+ /* Propagate the error condition to the CAN stack. */
+ skb = alloc_can_err_skb(ndev, &cf);
+- if (unlikely(!skb))
+- return 0;
+
+ /* Read the error counter register and check for new errors. */
+- cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
++ if (likely(skb))
++ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+
+- if (errctr & IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST)
+- cf->data[2] |= CAN_ERR_PROT_OVERLOAD;
++ if (errctr & IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST) {
++ stats->rx_errors++;
++ if (likely(skb))
++ cf->data[2] |= CAN_ERR_PROT_OVERLOAD;
++ }
+
+- if (errctr & IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST)
+- cf->data[3] = CAN_ERR_PROT_LOC_ACK;
++ if (errctr & IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST) {
++ stats->tx_errors++;
++ if (likely(skb))
++ cf->data[3] = CAN_ERR_PROT_LOC_ACK;
++ }
+
+- if (errctr & IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST)
+- cf->data[2] |= CAN_ERR_PROT_BIT0;
++ if (errctr & IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST) {
++ stats->tx_errors++;
++ if (likely(skb))
++ cf->data[2] |= CAN_ERR_PROT_BIT0;
++ }
+
+- if (errctr & IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST)
+- cf->data[2] |= CAN_ERR_PROT_BIT1;
++ if (errctr & IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST) {
++ stats->tx_errors++;
++ if (likely(skb))
++ cf->data[2] |= CAN_ERR_PROT_BIT1;
++ }
+
+- if (errctr & IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST)
+- cf->data[2] |= CAN_ERR_PROT_STUFF;
++ if (errctr & IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST) {
++ stats->rx_errors++;
++ if (likely(skb))
++ cf->data[2] |= CAN_ERR_PROT_STUFF;
++ }
+
+- if (errctr & IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST)
+- cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
++ if (errctr & IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST) {
++ stats->rx_errors++;
++ if (likely(skb))
++ cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
++ }
+
+- if (errctr & IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST)
+- cf->data[2] |= CAN_ERR_PROT_FORM;
++ if (errctr & IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST) {
++ stats->rx_errors++;
++ if (likely(skb))
++ cf->data[2] |= CAN_ERR_PROT_FORM;
++ }
+
+ /* Reset the error counter, ack the IRQ and re-enable the counter. */
+ writel(IFI_CANFD_ERROR_CTR_ER_RESET, priv->base + IFI_CANFD_ERROR_CTR);
+@@ -430,6 +449,9 @@ static int ifi_canfd_handle_lec_err(struct net_device *ndev)
+ priv->base + IFI_CANFD_INTERRUPT);
+ writel(IFI_CANFD_ERROR_CTR_ER_ENABLE, priv->base + IFI_CANFD_ERROR_CTR);
+
++ if (unlikely(!skb))
++ return 0;
++
+ netif_receive_skb(skb);
+
+ return 1;
+--
+2.43.0
+
--- /dev/null
+From 1fb91334f60f0c64f03e2d42e37071b9bd36cee0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2024 12:48:23 +0300
+Subject: can: j1939: j1939_session_new(): fix skb reference counting
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit a8c695005bfe6569acd73d777ca298ddddd66105 ]
+
+Since j1939_session_skb_queue() does an extra skb_get() for each new
+skb, do the same for the initial one in j1939_session_new() to avoid
+refcount underflow.
+
+Reported-by: syzbot+d4e8dc385d9258220c31@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=d4e8dc385d9258220c31
+Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol")
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Tested-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://patch.msgid.link/20241105094823.2403806-1-dmantipov@yandex.ru
+[mkl: clean up commit message]
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/j1939/transport.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
+index 5d2097e5ca3a8..a58f6f5dfcf8e 100644
+--- a/net/can/j1939/transport.c
++++ b/net/can/j1939/transport.c
+@@ -1505,7 +1505,7 @@ static struct j1939_session *j1939_session_new(struct j1939_priv *priv,
+ session->state = J1939_SESSION_NEW;
+
+ skb_queue_head_init(&session->skb_queue);
+- skb_queue_tail(&session->skb_queue, skb);
++ skb_queue_tail(&session->skb_queue, skb_get(skb));
+
+ skcb = j1939_skb_to_cb(skb);
+ memcpy(&session->skcb, skcb, sizeof(session->skcb));
+--
+2.43.0
+
--- /dev/null
+From af29adb7b8dadbbacd901513c03de843bf0df353 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Nov 2024 23:15:47 +0100
+Subject: can: m_can: m_can_handle_lec_err(): fix {rx,tx}_errors statistics
+
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+[ Upstream commit 988d4222bf9039a875a3d48f2fe35c317831ff68 ]
+
+The m_can_handle_lec_err() function was incorrectly incrementing only the
+receive error counter, even in cases of bit or acknowledgment errors that
+occur during transmission.
+
+Fix the issue by incrementing the appropriate counter based on the
+type of error.
+
+Fixes: e0d1f4816f2a ("can: m_can: add Bosch M_CAN controller support")
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Link: https://patch.msgid.link/20241122221650.633981-7-dario.binacchi@amarulasolutions.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/m_can/m_can.c | 33 +++++++++++++++++++++++----------
+ 1 file changed, 23 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
+index abc3907feb739..a4edd7ab37eb2 100644
+--- a/drivers/net/can/m_can/m_can.c
++++ b/drivers/net/can/m_can/m_can.c
+@@ -612,47 +612,60 @@ static int m_can_handle_lec_err(struct net_device *dev,
+ u32 timestamp = 0;
+
+ cdev->can.can_stats.bus_error++;
+- stats->rx_errors++;
+
+ /* propagate the error condition to the CAN stack */
+ skb = alloc_can_err_skb(dev, &cf);
+- if (unlikely(!skb))
+- return 0;
+
+ /* check for 'last error code' which tells us the
+ * type of the last error to occur on the CAN bus
+ */
+- cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
++ if (likely(skb))
++ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+
+ switch (lec_type) {
+ case LEC_STUFF_ERROR:
+ netdev_dbg(dev, "stuff error\n");
+- cf->data[2] |= CAN_ERR_PROT_STUFF;
++ stats->rx_errors++;
++ if (likely(skb))
++ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ break;
+ case LEC_FORM_ERROR:
+ netdev_dbg(dev, "form error\n");
+- cf->data[2] |= CAN_ERR_PROT_FORM;
++ stats->rx_errors++;
++ if (likely(skb))
++ cf->data[2] |= CAN_ERR_PROT_FORM;
+ break;
+ case LEC_ACK_ERROR:
+ netdev_dbg(dev, "ack error\n");
+- cf->data[3] = CAN_ERR_PROT_LOC_ACK;
++ stats->tx_errors++;
++ if (likely(skb))
++ cf->data[3] = CAN_ERR_PROT_LOC_ACK;
+ break;
+ case LEC_BIT1_ERROR:
+ netdev_dbg(dev, "bit1 error\n");
+- cf->data[2] |= CAN_ERR_PROT_BIT1;
++ stats->tx_errors++;
++ if (likely(skb))
++ cf->data[2] |= CAN_ERR_PROT_BIT1;
+ break;
+ case LEC_BIT0_ERROR:
+ netdev_dbg(dev, "bit0 error\n");
+- cf->data[2] |= CAN_ERR_PROT_BIT0;
++ stats->tx_errors++;
++ if (likely(skb))
++ cf->data[2] |= CAN_ERR_PROT_BIT0;
+ break;
+ case LEC_CRC_ERROR:
+ netdev_dbg(dev, "CRC error\n");
+- cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
++ stats->rx_errors++;
++ if (likely(skb))
++ cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+ break;
+ default:
+ break;
+ }
+
++ if (unlikely(!skb))
++ return 0;
++
+ if (cdev->is_peripheral)
+ timestamp = m_can_get_timestamp(cdev);
+
+--
+2.43.0
+
--- /dev/null
+From 5319ee693281fe06e32d551a282cced263cb7b0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Sep 2021 11:46:03 +0200
+Subject: can: peak_usb: CANFD: store 64-bits hw timestamps
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Stephane Grosjean <s.grosjean@peak-system.com>
+
+[ Upstream commit 28e0a70cede3fa6835e36302207776831cc41b8b ]
+
+This patch allows to use the whole 64-bit timestamps received from the
+CAN-FD device (expressed in µs) rather than only its low part, in the
+hwtstamp structure of the skb transferred to the network layer, when a
+CAN/CANFD frame has been received.
+
+Link: https://lore.kernel.org/all/20210930094603.23134-1-s.grosjean@peak-system.com
+Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Stable-dep-of: 9e66242504f4 ("can: c_can: c_can_handle_bus_err(): update statistics if skb allocation fails")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/peak_usb/pcan_usb_core.c | 13 +++++++++++++
+ drivers/net/can/usb/peak_usb/pcan_usb_core.h | 1 +
+ drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 9 ++++++---
+ 3 files changed, 20 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+index e8f43ed90b722..6107fef9f4a03 100644
+--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
++++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+@@ -205,6 +205,19 @@ int peak_usb_netif_rx(struct sk_buff *skb,
+ return netif_rx(skb);
+ }
+
++/* post received skb with native 64-bit hw timestamp */
++int peak_usb_netif_rx_64(struct sk_buff *skb, u32 ts_low, u32 ts_high)
++{
++ struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb);
++ u64 ns_ts;
++
++ ns_ts = (u64)ts_high << 32 | ts_low;
++ ns_ts *= NSEC_PER_USEC;
++ hwts->hwtstamp = ns_to_ktime(ns_ts);
++
++ return netif_rx(skb);
++}
++
+ /*
+ * callback for bulk Rx urb
+ */
+diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+index b00a4811bf61f..daa19f57e7422 100644
+--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
++++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+@@ -143,6 +143,7 @@ void peak_usb_set_ts_now(struct peak_time_ref *time_ref, u32 ts_now);
+ void peak_usb_get_ts_time(struct peak_time_ref *time_ref, u32 ts, ktime_t *tv);
+ int peak_usb_netif_rx(struct sk_buff *skb,
+ struct peak_time_ref *time_ref, u32 ts_low);
++int peak_usb_netif_rx_64(struct sk_buff *skb, u32 ts_low, u32 ts_high);
+ void peak_usb_async_complete(struct urb *urb);
+ void peak_usb_restart_complete(struct peak_usb_device *dev);
+
+diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+index 09029a3bad1ac..6bd12549f1014 100644
+--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
++++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+@@ -515,7 +515,8 @@ static int pcan_usb_fd_decode_canmsg(struct pcan_usb_fd_if *usb_if,
+ netdev->stats.rx_packets++;
+ netdev->stats.rx_bytes += cfd->len;
+
+- peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(rm->ts_low));
++ peak_usb_netif_rx_64(skb, le32_to_cpu(rm->ts_low),
++ le32_to_cpu(rm->ts_high));
+
+ return 0;
+ }
+@@ -579,7 +580,8 @@ static int pcan_usb_fd_decode_status(struct pcan_usb_fd_if *usb_if,
+ netdev->stats.rx_packets++;
+ netdev->stats.rx_bytes += cf->len;
+
+- peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(sm->ts_low));
++ peak_usb_netif_rx_64(skb, le32_to_cpu(sm->ts_low),
++ le32_to_cpu(sm->ts_high));
+
+ return 0;
+ }
+@@ -629,7 +631,8 @@ static int pcan_usb_fd_decode_overrun(struct pcan_usb_fd_if *usb_if,
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
+
+- peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(ov->ts_low));
++ peak_usb_netif_rx_64(skb, le32_to_cpu(ov->ts_low),
++ le32_to_cpu(ov->ts_high));
+
+ netdev->stats.rx_over_errors++;
+ netdev->stats.rx_errors++;
+--
+2.43.0
+
--- /dev/null
+From ae52d5247de6204c18d6001dfb1fa2cfa768a2b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Nov 2024 23:15:43 +0100
+Subject: can: sun4i_can: sun4i_can_err(): call can_change_state() even if cf
+ is NULL
+
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+[ Upstream commit ee6bf3677ae03569d833795064e17f605c2163c7 ]
+
+Call the function can_change_state() if the allocation of the skb
+fails, as it handles the cf parameter when it is null.
+
+Additionally, this ensures that the statistics related to state error
+counters (i. e. warning, passive, and bus-off) are updated.
+
+Fixes: 0738eff14d81 ("can: Allwinner A10/A20 CAN Controller support - Kernel module")
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Link: https://patch.msgid.link/20241122221650.633981-3-dario.binacchi@amarulasolutions.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/sun4i_can.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
+index ab9adfe92a94b..aad1882a9be11 100644
+--- a/drivers/net/can/sun4i_can.c
++++ b/drivers/net/can/sun4i_can.c
+@@ -613,10 +613,10 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
+ tx_state = txerr >= rxerr ? state : 0;
+ rx_state = txerr <= rxerr ? state : 0;
+
+- if (likely(skb))
+- can_change_state(dev, cf, tx_state, rx_state);
+- else
+- priv->can.state = state;
++ /* The skb allocation might fail, but can_change_state()
++ * handles cf == NULL.
++ */
++ can_change_state(dev, cf, tx_state, rx_state);
+ if (state == CAN_STATE_BUS_OFF)
+ can_bus_off(dev);
+ }
+--
+2.43.0
+
--- /dev/null
+From 7251cb2179542e863d4fc4cc2b3d252a52693a33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Nov 2024 23:15:51 +0100
+Subject: can: sun4i_can: sun4i_can_err(): fix {rx,tx}_errors statistics
+
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+[ Upstream commit 595a81988a6fe06eb5849e972c8b9cb21c4e0d54 ]
+
+The sun4i_can_err() function only incremented the receive error counter
+and never the transmit error counter, even if the STA_ERR_DIR flag
+reported that an error had occurred during transmission.
+
+Increment the receive/transmit error counter based on the value of the
+STA_ERR_DIR flag.
+
+Fixes: 0738eff14d81 ("can: Allwinner A10/A20 CAN Controller support - Kernel module")
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Link: https://patch.msgid.link/20241122221650.633981-11-dario.binacchi@amarulasolutions.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/sun4i_can.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
+index aad1882a9be11..3e5aa2e0ea66e 100644
+--- a/drivers/net/can/sun4i_can.c
++++ b/drivers/net/can/sun4i_can.c
+@@ -563,11 +563,9 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
+ /* bus error interrupt */
+ netdev_dbg(dev, "bus error interrupt\n");
+ priv->can.can_stats.bus_error++;
+- stats->rx_errors++;
++ ecc = readl(priv->base + SUN4I_REG_STA_ADDR);
+
+ if (likely(skb)) {
+- ecc = readl(priv->base + SUN4I_REG_STA_ADDR);
+-
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+
+ switch (ecc & SUN4I_STA_MASK_ERR) {
+@@ -585,9 +583,15 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
+ >> 16;
+ break;
+ }
+- /* error occurred during transmission? */
+- if ((ecc & SUN4I_STA_ERR_DIR) == 0)
++ }
++
++ /* error occurred during transmission? */
++ if ((ecc & SUN4I_STA_ERR_DIR) == 0) {
++ if (likely(skb))
+ cf->data[2] |= CAN_ERR_PROT_TX;
++ stats->tx_errors++;
++ } else {
++ stats->rx_errors++;
+ }
+ }
+ if (isrc & SUN4I_INT_ERR_PASSIVE) {
+--
+2.43.0
+
--- /dev/null
+From 8e11e1f62bd5d75fd66fc3544f42f04e104e2d48 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Nov 2024 17:39:02 +0300
+Subject: dccp: Fix memory leak in dccp_feat_change_recv
+
+From: Ivan Solodovnikov <solodovnikov.ia@phystech.edu>
+
+[ Upstream commit 22be4727a8f898442066bcac34f8a1ad0bc72e14 ]
+
+If dccp_feat_push_confirm() fails after new value for SP feature was accepted
+without reconciliation ('entry == NULL' branch), memory allocated for that value
+with dccp_feat_clone_sp_val() is never freed.
+
+Here is the kmemleak stack for this:
+
+unreferenced object 0xffff88801d4ab488 (size 8):
+ comm "syz-executor310", pid 1127, jiffies 4295085598 (age 41.666s)
+ hex dump (first 8 bytes):
+ 01 b4 4a 1d 80 88 ff ff ..J.....
+ backtrace:
+ [<00000000db7cabfe>] kmemdup+0x23/0x50 mm/util.c:128
+ [<0000000019b38405>] kmemdup include/linux/string.h:465 [inline]
+ [<0000000019b38405>] dccp_feat_clone_sp_val net/dccp/feat.c:371 [inline]
+ [<0000000019b38405>] dccp_feat_clone_sp_val net/dccp/feat.c:367 [inline]
+ [<0000000019b38405>] dccp_feat_change_recv net/dccp/feat.c:1145 [inline]
+ [<0000000019b38405>] dccp_feat_parse_options+0x1196/0x2180 net/dccp/feat.c:1416
+ [<00000000b1f6d94a>] dccp_parse_options+0xa2a/0x1260 net/dccp/options.c:125
+ [<0000000030d7b621>] dccp_rcv_state_process+0x197/0x13d0 net/dccp/input.c:650
+ [<000000001f74c72e>] dccp_v4_do_rcv+0xf9/0x1a0 net/dccp/ipv4.c:688
+ [<00000000a6c24128>] sk_backlog_rcv include/net/sock.h:1041 [inline]
+ [<00000000a6c24128>] __release_sock+0x139/0x3b0 net/core/sock.c:2570
+ [<00000000cf1f3a53>] release_sock+0x54/0x1b0 net/core/sock.c:3111
+ [<000000008422fa23>] inet_wait_for_connect net/ipv4/af_inet.c:603 [inline]
+ [<000000008422fa23>] __inet_stream_connect+0x5d0/0xf70 net/ipv4/af_inet.c:696
+ [<0000000015b6f64d>] inet_stream_connect+0x53/0xa0 net/ipv4/af_inet.c:735
+ [<0000000010122488>] __sys_connect_file+0x15c/0x1a0 net/socket.c:1865
+ [<00000000b4b70023>] __sys_connect+0x165/0x1a0 net/socket.c:1882
+ [<00000000f4cb3815>] __do_sys_connect net/socket.c:1892 [inline]
+ [<00000000f4cb3815>] __se_sys_connect net/socket.c:1889 [inline]
+ [<00000000f4cb3815>] __x64_sys_connect+0x6e/0xb0 net/socket.c:1889
+ [<00000000e7b1e839>] do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46
+ [<0000000055e91434>] entry_SYSCALL_64_after_hwframe+0x67/0xd1
+
+Clean up the allocated memory in case of dccp_feat_push_confirm() failure
+and bail out with an error reset code.
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Fixes: e77b8363b2ea ("dccp: Process incoming Change feature-negotiation options")
+Signed-off-by: Ivan Solodovnikov <solodovnikov.ia@phystech.edu>
+Link: https://patch.msgid.link/20241126143902.190853-1-solodovnikov.ia@phystech.edu
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/dccp/feat.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/dccp/feat.c b/net/dccp/feat.c
+index 54086bb05c42c..f7554dcdaaba9 100644
+--- a/net/dccp/feat.c
++++ b/net/dccp/feat.c
+@@ -1166,8 +1166,12 @@ static u8 dccp_feat_change_recv(struct list_head *fn, u8 is_mandatory, u8 opt,
+ goto not_valid_or_not_known;
+ }
+
+- return dccp_feat_push_confirm(fn, feat, local, &fval);
++ if (dccp_feat_push_confirm(fn, feat, local, &fval)) {
++ kfree(fval.sp.vec);
++ return DCCP_RESET_CODE_TOO_BUSY;
++ }
+
++ return 0;
+ } else if (entry->state == FEAT_UNSTABLE) { /* 6.6.2 */
+ return 0;
+ }
+--
+2.43.0
+
--- /dev/null
+From ed4c0422993073e9c8e26b1fd0039a69316dcc8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Sep 2024 11:53:06 +0200
+Subject: dt-bindings: serial: rs485: Fix rs485-rts-delay property
+
+From: Michal Simek <michal.simek@amd.com>
+
+[ Upstream commit 12b3642b6c242061d3ba84e6e3050c3141ded14c ]
+
+Code expects array only with 2 items which should be checked.
+But also item checking is not working as it should likely because of
+incorrect items description.
+
+Fixes: d50f974c4f7f ("dt-bindings: serial: Convert rs485 bindings to json-schema")
+Signed-off-by: Michal Simek <michal.simek@amd.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
+Link: https://lore.kernel.org/r/820c639b9e22fe037730ed44d1b044cdb6d28b75.1726480384.git.michal.simek@amd.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../devicetree/bindings/serial/rs485.yaml | 19 +++++++++----------
+ 1 file changed, 9 insertions(+), 10 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/serial/rs485.yaml b/Documentation/devicetree/bindings/serial/rs485.yaml
+index 518949737c86e..bc43670c69fa9 100644
+--- a/Documentation/devicetree/bindings/serial/rs485.yaml
++++ b/Documentation/devicetree/bindings/serial/rs485.yaml
+@@ -18,16 +18,15 @@ properties:
+ description: prop-encoded-array <a b>
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ items:
+- items:
+- - description: Delay between rts signal and beginning of data sent in
+- milliseconds. It corresponds to the delay before sending data.
+- default: 0
+- maximum: 100
+- - description: Delay between end of data sent and rts signal in milliseconds.
+- It corresponds to the delay after sending data and actual release
+- of the line.
+- default: 0
+- maximum: 100
++ - description: Delay between rts signal and beginning of data sent in
++ milliseconds. It corresponds to the delay before sending data.
++ default: 0
++ maximum: 100
++ - description: Delay between end of data sent and rts signal in milliseconds.
++ It corresponds to the delay after sending data and actual release
++ of the line.
++ default: 0
++ maximum: 100
+
+ rs485-rts-active-low:
+ description: drive RTS low when sending (default is high).
+--
+2.43.0
+
--- /dev/null
+From 4c0be6994b06ee57b549e60666bdd01949cccc3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 Jul 2022 18:44:40 +0200
+Subject: dt_bindings: rs485: Correct delay values
+
+From: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+
+[ Upstream commit 885dcb08c93d75b784468e65fd4f1f82d5313061 ]
+
+Currently the documentation claims that a maximum of 1000 msecs is allowed
+for RTS delays. However nothing actually checks the values read from device
+tree/ACPI and so it is possible to set much higher values.
+
+There is already a maximum of 100 ms enforced for RTS delays that are set
+via the UART TIOCSRS485 ioctl. To be consistent with that use the same
+limit for DT/ACPI values.
+
+Although this change is visible to userspace the risk of breaking anything
+when reducing the max delays from 1000 to 100 ms should be very low, since
+100 ms is already a very high maximum for delays that are usually rather in
+the usecs range.
+
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+Link: https://lore.kernel.org/r/20220710164442.2958979-7-LinoSanfilippo@gmx.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 12b3642b6c24 ("dt-bindings: serial: rs485: Fix rs485-rts-delay property")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/serial/rs485.yaml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/serial/rs485.yaml b/Documentation/devicetree/bindings/serial/rs485.yaml
+index 0c9fa694f85c8..518949737c86e 100644
+--- a/Documentation/devicetree/bindings/serial/rs485.yaml
++++ b/Documentation/devicetree/bindings/serial/rs485.yaml
+@@ -22,12 +22,12 @@ properties:
+ - description: Delay between rts signal and beginning of data sent in
+ milliseconds. It corresponds to the delay before sending data.
+ default: 0
+- maximum: 1000
++ maximum: 100
+ - description: Delay between end of data sent and rts signal in milliseconds.
+ It corresponds to the delay after sending data and actual release
+ of the line.
+ default: 0
+- maximum: 1000
++ maximum: 100
+
+ rs485-rts-active-low:
+ description: drive RTS low when sending (default is high).
+--
+2.43.0
+
--- /dev/null
+From 5eb8c9aca16fc84f93478568f9531bb2c3438cf1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Dec 2024 16:33:57 +0100
+Subject: ethtool: Fix wrong mod state in case of verbose and no_mask bitset
+
+From: Kory Maincent <kory.maincent@bootlin.com>
+
+[ Upstream commit 910c4788d6155b2202ec88273376cd7ecdc24f0a ]
+
+A bitset without mask in a _SET request means we want exactly the bits in
+the bitset to be set. This works correctly for compact format but when
+verbose format is parsed, ethnl_update_bitset32_verbose() only sets the
+bits present in the request bitset but does not clear the rest. The commit
+6699170376ab ("ethtool: fix application of verbose no_mask bitset") fixes
+this issue by clearing the whole target bitmap before we start iterating.
+The solution proposed brought an issue with the behavior of the mod
+variable. As the bitset is always cleared the old value will always
+differ to the new value.
+
+Fix it by adding a new function to compare bitmaps and a temporary variable
+which save the state of the old bitmap.
+
+Fixes: 6699170376ab ("ethtool: fix application of verbose no_mask bitset")
+Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
+Link: https://patch.msgid.link/20241202153358.1142095-1-kory.maincent@bootlin.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/bitset.c | 48 ++++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 44 insertions(+), 4 deletions(-)
+
+diff --git a/net/ethtool/bitset.c b/net/ethtool/bitset.c
+index 0515d6604b3b9..f0883357d12e5 100644
+--- a/net/ethtool/bitset.c
++++ b/net/ethtool/bitset.c
+@@ -425,12 +425,32 @@ static int ethnl_parse_bit(unsigned int *index, bool *val, unsigned int nbits,
+ return 0;
+ }
+
++/**
++ * ethnl_bitmap32_equal() - Compare two bitmaps
++ * @map1: first bitmap
++ * @map2: second bitmap
++ * @nbits: bit size to compare
++ *
++ * Return: true if first @nbits are equal, false if not
++ */
++static bool ethnl_bitmap32_equal(const u32 *map1, const u32 *map2,
++ unsigned int nbits)
++{
++ if (memcmp(map1, map2, nbits / 32 * sizeof(u32)))
++ return false;
++ if (nbits % 32 == 0)
++ return true;
++ return !((map1[nbits / 32] ^ map2[nbits / 32]) &
++ ethnl_lower_bits(nbits % 32));
++}
++
+ static int
+ ethnl_update_bitset32_verbose(u32 *bitmap, unsigned int nbits,
+ const struct nlattr *attr, struct nlattr **tb,
+ ethnl_string_array_t names,
+ struct netlink_ext_ack *extack, bool *mod)
+ {
++ u32 *saved_bitmap = NULL;
+ struct nlattr *bit_attr;
+ bool no_mask;
+ int rem;
+@@ -448,8 +468,20 @@ ethnl_update_bitset32_verbose(u32 *bitmap, unsigned int nbits,
+ }
+
+ no_mask = tb[ETHTOOL_A_BITSET_NOMASK];
+- if (no_mask)
+- ethnl_bitmap32_clear(bitmap, 0, nbits, mod);
++ if (no_mask) {
++ unsigned int nwords = DIV_ROUND_UP(nbits, 32);
++ unsigned int nbytes = nwords * sizeof(u32);
++ bool dummy;
++
++ /* The bitmap size is only the size of the map part without
++ * its mask part.
++ */
++ saved_bitmap = kcalloc(nwords, sizeof(u32), GFP_KERNEL);
++ if (!saved_bitmap)
++ return -ENOMEM;
++ memcpy(saved_bitmap, bitmap, nbytes);
++ ethnl_bitmap32_clear(bitmap, 0, nbits, &dummy);
++ }
+
+ nla_for_each_nested(bit_attr, tb[ETHTOOL_A_BITSET_BITS], rem) {
+ bool old_val, new_val;
+@@ -458,22 +490,30 @@ ethnl_update_bitset32_verbose(u32 *bitmap, unsigned int nbits,
+ if (nla_type(bit_attr) != ETHTOOL_A_BITSET_BITS_BIT) {
+ NL_SET_ERR_MSG_ATTR(extack, bit_attr,
+ "only ETHTOOL_A_BITSET_BITS_BIT allowed in ETHTOOL_A_BITSET_BITS");
++ kfree(saved_bitmap);
+ return -EINVAL;
+ }
+ ret = ethnl_parse_bit(&idx, &new_val, nbits, bit_attr, no_mask,
+ names, extack);
+- if (ret < 0)
++ if (ret < 0) {
++ kfree(saved_bitmap);
+ return ret;
++ }
+ old_val = bitmap[idx / 32] & ((u32)1 << (idx % 32));
+ if (new_val != old_val) {
+ if (new_val)
+ bitmap[idx / 32] |= ((u32)1 << (idx % 32));
+ else
+ bitmap[idx / 32] &= ~((u32)1 << (idx % 32));
+- *mod = true;
++ if (!no_mask)
++ *mod = true;
+ }
+ }
+
++ if (no_mask && !ethnl_bitmap32_equal(saved_bitmap, bitmap, nbits))
++ *mod = true;
++
++ kfree(saved_bitmap);
+ return 0;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From ce3650d63463ee160dd469cde19387969fe8fb4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Dec 2024 18:21:21 +0000
+Subject: geneve: do not assume mac header is set in geneve_xmit_skb()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 8588c99c7d47448fcae39e3227d6e2bb97aad86d ]
+
+We should not assume mac header is set in output path.
+
+Use skb_eth_hdr() instead of eth_hdr() to fix the issue.
+
+sysbot reported the following :
+
+ WARNING: CPU: 0 PID: 11635 at include/linux/skbuff.h:3052 skb_mac_header include/linux/skbuff.h:3052 [inline]
+ WARNING: CPU: 0 PID: 11635 at include/linux/skbuff.h:3052 eth_hdr include/linux/if_ether.h:24 [inline]
+ WARNING: CPU: 0 PID: 11635 at include/linux/skbuff.h:3052 geneve_xmit_skb drivers/net/geneve.c:898 [inline]
+ WARNING: CPU: 0 PID: 11635 at include/linux/skbuff.h:3052 geneve_xmit+0x4c38/0x5730 drivers/net/geneve.c:1039
+Modules linked in:
+CPU: 0 UID: 0 PID: 11635 Comm: syz.4.1423 Not tainted 6.12.0-syzkaller-10296-gaaf20f870da0 #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024
+ RIP: 0010:skb_mac_header include/linux/skbuff.h:3052 [inline]
+ RIP: 0010:eth_hdr include/linux/if_ether.h:24 [inline]
+ RIP: 0010:geneve_xmit_skb drivers/net/geneve.c:898 [inline]
+ RIP: 0010:geneve_xmit+0x4c38/0x5730 drivers/net/geneve.c:1039
+Code: 21 c6 02 e9 35 d4 ff ff e8 a5 48 4c fb 90 0f 0b 90 e9 fd f5 ff ff e8 97 48 4c fb 90 0f 0b 90 e9 d8 f5 ff ff e8 89 48 4c fb 90 <0f> 0b 90 e9 41 e4 ff ff e8 7b 48 4c fb 90 0f 0b 90 e9 cd e7 ff ff
+RSP: 0018:ffffc90003b2f870 EFLAGS: 00010283
+RAX: 000000000000037a RBX: 000000000000ffff RCX: ffffc9000dc3d000
+RDX: 0000000000080000 RSI: ffffffff86428417 RDI: 0000000000000003
+RBP: ffffc90003b2f9f0 R08: 0000000000000003 R09: 000000000000ffff
+R10: 000000000000ffff R11: 0000000000000002 R12: ffff88806603c000
+R13: 0000000000000000 R14: ffff8880685b2780 R15: 0000000000000e23
+FS: 00007fdc2deed6c0(0000) GS:ffff8880b8600000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 0000001b30a1dff8 CR3: 0000000056b8c000 CR4: 00000000003526f0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ <TASK>
+ __netdev_start_xmit include/linux/netdevice.h:5002 [inline]
+ netdev_start_xmit include/linux/netdevice.h:5011 [inline]
+ __dev_direct_xmit+0x58a/0x720 net/core/dev.c:4490
+ dev_direct_xmit include/linux/netdevice.h:3181 [inline]
+ packet_xmit+0x1e4/0x360 net/packet/af_packet.c:285
+ packet_snd net/packet/af_packet.c:3146 [inline]
+ packet_sendmsg+0x2700/0x5660 net/packet/af_packet.c:3178
+ sock_sendmsg_nosec net/socket.c:711 [inline]
+ __sock_sendmsg net/socket.c:726 [inline]
+ __sys_sendto+0x488/0x4f0 net/socket.c:2197
+ __do_sys_sendto net/socket.c:2204 [inline]
+ __se_sys_sendto net/socket.c:2200 [inline]
+ __x64_sys_sendto+0xe0/0x1c0 net/socket.c:2200
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xcd/0x250 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fixes: a025fb5f49ad ("geneve: Allow configuration of DF behaviour")
+Reported-by: syzbot+3ec5271486d7cb2d242a@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/674f4b72.050a0220.17bd51.004a.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Link: https://patch.msgid.link/20241203182122.2725517-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/geneve.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
+index d7440cc4be80b..10e3d69205a4f 100644
+--- a/drivers/net/geneve.c
++++ b/drivers/net/geneve.c
+@@ -985,7 +985,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+ if (geneve->cfg.df == GENEVE_DF_SET) {
+ df = htons(IP_DF);
+ } else if (geneve->cfg.df == GENEVE_DF_INHERIT) {
+- struct ethhdr *eth = eth_hdr(skb);
++ struct ethhdr *eth = skb_eth_hdr(skb);
+
+ if (ntohs(eth->h_proto) == ETH_P_IPV6) {
+ df = htons(IP_DF);
+--
+2.43.0
+
--- /dev/null
+From 1d125a4130e74e280caf63f46d2992bd60308925 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Nov 2024 17:18:22 +0800
+Subject: gpio: grgpio: Add NULL check in grgpio_probe
+
+From: Charles Han <hanchunchao@inspur.com>
+
+[ Upstream commit 050b23d081da0f29474de043e9538c1f7a351b3b ]
+
+devm_kasprintf() can return a NULL pointer on failure,but this
+returned value in grgpio_probe is not checked.
+Add NULL check in grgpio_probe, to handle kernel NULL
+pointer dereference error.
+
+Cc: stable@vger.kernel.org
+Fixes: 7eb6ce2f2723 ("gpio: Convert to using %pOF instead of full_name")
+Signed-off-by: Charles Han <hanchunchao@inspur.com>
+Link: https://lore.kernel.org/r/20241114091822.78199-1-hanchunchao@inspur.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-grgpio.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c
+index bf5ecf23cbceb..0d2441b7c6d02 100644
+--- a/drivers/gpio/gpio-grgpio.c
++++ b/drivers/gpio/gpio-grgpio.c
+@@ -363,6 +363,9 @@ static int grgpio_probe(struct platform_device *ofdev)
+ gc->owner = THIS_MODULE;
+ gc->to_irq = grgpio_to_irq;
+ gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", np);
++ if (!gc->label)
++ return -ENOMEM;
++
+ gc->base = -1;
+
+ err = of_property_read_u32(np, "nbits", &prop);
+--
+2.43.0
+
--- /dev/null
+From cf43ad3f0f2d4c07e76d9a946eb572ba29cfe0fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Oct 2024 15:18:31 +0200
+Subject: gpio: grgpio: use a helper variable to store the address of
+ ofdev->dev
+
+From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+
+[ Upstream commit d036ae41cebdfae92666024163c109b8fef516fa ]
+
+Instead of dereferencing the platform device pointer repeatedly, just
+store its address in a helper variable.
+
+Link: https://lore.kernel.org/r/20241015131832.44678-3-brgl@bgdev.pl
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Stable-dep-of: 050b23d081da ("gpio: grgpio: Add NULL check in grgpio_probe")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-grgpio.c | 23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c
+index 21204a5dca3d4..bf5ecf23cbceb 100644
+--- a/drivers/gpio/gpio-grgpio.c
++++ b/drivers/gpio/gpio-grgpio.c
+@@ -328,6 +328,7 @@ static const struct irq_domain_ops grgpio_irq_domain_ops = {
+ static int grgpio_probe(struct platform_device *ofdev)
+ {
+ struct device_node *np = ofdev->dev.of_node;
++ struct device *dev = &ofdev->dev;
+ void __iomem *regs;
+ struct gpio_chip *gc;
+ struct grgpio_priv *priv;
+@@ -337,7 +338,7 @@ static int grgpio_probe(struct platform_device *ofdev)
+ int size;
+ int i;
+
+- priv = devm_kzalloc(&ofdev->dev, sizeof(*priv), GFP_KERNEL);
++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+@@ -346,29 +347,29 @@ static int grgpio_probe(struct platform_device *ofdev)
+ return PTR_ERR(regs);
+
+ gc = &priv->gc;
+- err = bgpio_init(gc, &ofdev->dev, 4, regs + GRGPIO_DATA,
++ err = bgpio_init(gc, dev, 4, regs + GRGPIO_DATA,
+ regs + GRGPIO_OUTPUT, NULL, regs + GRGPIO_DIR, NULL,
+ BGPIOF_BIG_ENDIAN_BYTE_ORDER);
+ if (err) {
+- dev_err(&ofdev->dev, "bgpio_init() failed\n");
++ dev_err(dev, "bgpio_init() failed\n");
+ return err;
+ }
+
+ priv->regs = regs;
+ priv->imask = gc->read_reg(regs + GRGPIO_IMASK);
+- priv->dev = &ofdev->dev;
++ priv->dev = dev;
+
+ gc->of_node = np;
+ gc->owner = THIS_MODULE;
+ gc->to_irq = grgpio_to_irq;
+- gc->label = devm_kasprintf(&ofdev->dev, GFP_KERNEL, "%pOF", np);
++ gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", np);
+ gc->base = -1;
+
+ err = of_property_read_u32(np, "nbits", &prop);
+ if (err || prop <= 0 || prop > GRGPIO_MAX_NGPIO) {
+ gc->ngpio = GRGPIO_MAX_NGPIO;
+- dev_dbg(&ofdev->dev,
+- "No or invalid nbits property: assume %d\n", gc->ngpio);
++ dev_dbg(dev, "No or invalid nbits property: assume %d\n",
++ gc->ngpio);
+ } else {
+ gc->ngpio = prop;
+ }
+@@ -380,7 +381,7 @@ static int grgpio_probe(struct platform_device *ofdev)
+ irqmap = (s32 *)of_get_property(np, "irqmap", &size);
+ if (irqmap) {
+ if (size < gc->ngpio) {
+- dev_err(&ofdev->dev,
++ dev_err(dev,
+ "irqmap shorter than ngpio (%d < %d)\n",
+ size, gc->ngpio);
+ return -EINVAL;
+@@ -390,7 +391,7 @@ static int grgpio_probe(struct platform_device *ofdev)
+ &grgpio_irq_domain_ops,
+ priv);
+ if (!priv->domain) {
+- dev_err(&ofdev->dev, "Could not add irq domain\n");
++ dev_err(dev, "Could not add irq domain\n");
+ return -EINVAL;
+ }
+
+@@ -420,13 +421,13 @@ static int grgpio_probe(struct platform_device *ofdev)
+
+ err = gpiochip_add_data(gc, priv);
+ if (err) {
+- dev_err(&ofdev->dev, "Could not add gpiochip\n");
++ dev_err(dev, "Could not add gpiochip\n");
+ if (priv->domain)
+ irq_domain_remove(priv->domain);
+ return err;
+ }
+
+- dev_info(&ofdev->dev, "regs=0x%p, base=%d, ngpio=%d, irqs=%s\n",
++ dev_info(dev, "regs=0x%p, base=%d, ngpio=%d, irqs=%s\n",
+ priv->regs, gc->base, gc->ngpio, priv->domain ? "on" : "off");
+
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From fdf81ea3fd1f68ce8dedaccfbb018e05f3fa64f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Oct 2024 20:10:48 +0800
+Subject: igb: Fix potential invalid memory access in igb_init_module()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 0566f83d206c7a864abcd741fe39d6e0ae5eef29 ]
+
+The pci_register_driver() can fail and when this happened, the dca_notifier
+needs to be unregistered, otherwise the dca_notifier can be called when
+igb fails to install, resulting to invalid memory access.
+
+Fixes: bbd98fe48a43 ("igb: Fix DCA errors and do not use context index for 82576")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igb/igb_main.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
+index f3a433b4c7cdb..7712df5b93147 100644
+--- a/drivers/net/ethernet/intel/igb/igb_main.c
++++ b/drivers/net/ethernet/intel/igb/igb_main.c
+@@ -667,6 +667,10 @@ static int __init igb_init_module(void)
+ dca_register_notify(&dca_notifier);
+ #endif
+ ret = pci_register_driver(&igb_driver);
++#ifdef CONFIG_IGB_DCA
++ if (ret)
++ dca_unregister_notify(&dca_notifier);
++#endif
+ return ret;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From dd4d91b9fbaae7a9fc29c0e400beaed538653f47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Nov 2024 03:42:56 -0600
+Subject: ipvs: fix UB due to uninitialized stack access in
+ ip_vs_protocol_init()
+
+From: Jinghao Jia <jinghao7@illinois.edu>
+
+[ Upstream commit 146b6f1112eb30a19776d6c323c994e9d67790db ]
+
+Under certain kernel configurations when building with Clang/LLVM, the
+compiler does not generate a return or jump as the terminator
+instruction for ip_vs_protocol_init(), triggering the following objtool
+warning during build time:
+
+ vmlinux.o: warning: objtool: ip_vs_protocol_init() falls through to next function __initstub__kmod_ip_vs_rr__935_123_ip_vs_rr_init6()
+
+At runtime, this either causes an oops when trying to load the ipvs
+module or a boot-time panic if ipvs is built-in. This same issue has
+been reported by the Intel kernel test robot previously.
+
+Digging deeper into both LLVM and the kernel code reveals this to be a
+undefined behavior problem. ip_vs_protocol_init() uses a on-stack buffer
+of 64 chars to store the registered protocol names and leaves it
+uninitialized after definition. The function calls strnlen() when
+concatenating protocol names into the buffer. With CONFIG_FORTIFY_SOURCE
+strnlen() performs an extra step to check whether the last byte of the
+input char buffer is a null character (commit 3009f891bb9f ("fortify:
+Allow strlen() and strnlen() to pass compile-time known lengths")).
+This, together with possibly other configurations, cause the following
+IR to be generated:
+
+ define hidden i32 @ip_vs_protocol_init() local_unnamed_addr #5 section ".init.text" align 16 !kcfi_type !29 {
+ %1 = alloca [64 x i8], align 16
+ ...
+
+ 14: ; preds = %11
+ %15 = getelementptr inbounds i8, ptr %1, i64 63
+ %16 = load i8, ptr %15, align 1
+ %17 = tail call i1 @llvm.is.constant.i8(i8 %16)
+ %18 = icmp eq i8 %16, 0
+ %19 = select i1 %17, i1 %18, i1 false
+ br i1 %19, label %20, label %23
+
+ 20: ; preds = %14
+ %21 = call i64 @strlen(ptr noundef nonnull dereferenceable(1) %1) #23
+ ...
+
+ 23: ; preds = %14, %11, %20
+ %24 = call i64 @strnlen(ptr noundef nonnull dereferenceable(1) %1, i64 noundef 64) #24
+ ...
+ }
+
+The above code calculates the address of the last char in the buffer
+(value %15) and then loads from it (value %16). Because the buffer is
+never initialized, the LLVM GVN pass marks value %16 as undefined:
+
+ %13 = getelementptr inbounds i8, ptr %1, i64 63
+ br i1 undef, label %14, label %17
+
+This gives later passes (SCCP, in particular) more DCE opportunities by
+propagating the undef value further, and eventually removes everything
+after the load on the uninitialized stack location:
+
+ define hidden i32 @ip_vs_protocol_init() local_unnamed_addr #0 section ".init.text" align 16 !kcfi_type !11 {
+ %1 = alloca [64 x i8], align 16
+ ...
+
+ 12: ; preds = %11
+ %13 = getelementptr inbounds i8, ptr %1, i64 63
+ unreachable
+ }
+
+In this way, the generated native code will just fall through to the
+next function, as LLVM does not generate any code for the unreachable IR
+instruction and leaves the function without a terminator.
+
+Zero the on-stack buffer to avoid this possible UB.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202402100205.PWXIz1ZK-lkp@intel.com/
+Co-developed-by: Ruowen Qin <ruqin@redhat.com>
+Signed-off-by: Ruowen Qin <ruqin@redhat.com>
+Signed-off-by: Jinghao Jia <jinghao7@illinois.edu>
+Acked-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipvs/ip_vs_proto.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c
+index f100da4ba3bc3..a9fd1d3fc2cbf 100644
+--- a/net/netfilter/ipvs/ip_vs_proto.c
++++ b/net/netfilter/ipvs/ip_vs_proto.c
+@@ -340,7 +340,7 @@ void __net_exit ip_vs_protocol_net_cleanup(struct netns_ipvs *ipvs)
+
+ int __init ip_vs_protocol_init(void)
+ {
+- char protocols[64];
++ char protocols[64] = { 0 };
+ #define REGISTER_PROTOCOL(p) \
+ do { \
+ register_ip_vs_protocol(p); \
+@@ -348,8 +348,6 @@ int __init ip_vs_protocol_init(void)
+ strcat(protocols, (p)->name); \
+ } while (0)
+
+- protocols[0] = '\0';
+- protocols[2] = '\0';
+ #ifdef CONFIG_IP_VS_PROTO_TCP
+ REGISTER_PROTOCOL(&ip_vs_protocol_tcp);
+ #endif
+--
+2.43.0
+
--- /dev/null
+From 635b605b4d7740b1e7d322b7959f9acbbae3ab0a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Sep 2024 12:14:03 -0700
+Subject: iTCO_wdt: mask NMI_NOW bit for update_no_reboot_bit() call
+
+From: Oleksandr Ocheretnyi <oocheret@cisco.com>
+
+[ Upstream commit daa814d784ac034c62ab3fb0ef83daeafef527e2 ]
+
+Commit da23b6faa8bf ("watchdog: iTCO: Add support for Cannon Lake
+PCH iTCO") does not mask NMI_NOW bit during TCO1_CNT register's
+value comparison for update_no_reboot_bit() call causing following
+failure:
+
+ ...
+ iTCO_vendor_support: vendor-support=0
+ iTCO_wdt iTCO_wdt: unable to reset NO_REBOOT flag, device
+ disabled by hardware/BIOS
+ ...
+
+and this can lead to unexpected NMIs later during regular
+crashkernel's workflow because of watchdog probe call failures.
+
+This change masks NMI_NOW bit for TCO1_CNT register values to
+avoid unexpected NMI_NOW bit inversions.
+
+Fixes: da23b6faa8bf ("watchdog: iTCO: Add support for Cannon Lake PCH iTCO")
+Signed-off-by: Oleksandr Ocheretnyi <oocheret@cisco.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Link: https://lore.kernel.org/r/20240913191403.2560805-1-oocheret@cisco.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/iTCO_wdt.c | 21 +++++++++++++++++++--
+ 1 file changed, 19 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
+index a8052a3faaabb..3cebb83b3e679 100644
+--- a/drivers/watchdog/iTCO_wdt.c
++++ b/drivers/watchdog/iTCO_wdt.c
+@@ -82,6 +82,13 @@
+ #define TCO2_CNT(p) (TCOBASE(p) + 0x0a) /* TCO2 Control Register */
+ #define TCOv2_TMR(p) (TCOBASE(p) + 0x12) /* TCOv2 Timer Initial Value*/
+
++/*
++ * NMI_NOW is bit 8 of TCO1_CNT register
++ * Read/Write
++ * This bit is implemented as RW but has no effect on HW.
++ */
++#define NMI_NOW BIT(8)
++
+ /* internal variables */
+ struct iTCO_wdt_private {
+ struct watchdog_device wddev;
+@@ -220,13 +227,23 @@ static int update_no_reboot_bit_cnt(void *priv, bool set)
+ struct iTCO_wdt_private *p = priv;
+ u16 val, newval;
+
+- val = inw(TCO1_CNT(p));
++ /*
++ * writing back 1b1 to NMI_NOW of TCO1_CNT register
++ * causes NMI_NOW bit inversion what consequently does
++ * not allow to perform the register's value comparison
++ * properly.
++ *
++ * NMI_NOW bit masking for TCO1_CNT register values
++ * helps to avoid possible NMI_NOW bit inversions on
++ * following write operation.
++ */
++ val = inw(TCO1_CNT(p)) & ~NMI_NOW;
+ if (set)
+ val |= BIT(0);
+ else
+ val &= ~BIT(0);
+ outw(val, TCO1_CNT(p));
+- newval = inw(TCO1_CNT(p));
++ newval = inw(TCO1_CNT(p)) & ~NMI_NOW;
+
+ /* make sure the update is successful */
+ return val != newval ? -EIO : 0;
+--
+2.43.0
+
--- /dev/null
+From 016f2084acb741b7d5cbb424641da63d80b16f0b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Nov 2024 14:43:44 +0000
+Subject: net: hsr: avoid potential out-of-bound access in fill_frame_info()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit b9653d19e556c6afd035602927a93d100a0d7644 ]
+
+syzbot is able to feed a packet with 14 bytes, pretending
+it is a vlan one.
+
+Since fill_frame_info() is relying on skb->mac_len already,
+extend the check to cover this case.
+
+BUG: KMSAN: uninit-value in fill_frame_info net/hsr/hsr_forward.c:709 [inline]
+ BUG: KMSAN: uninit-value in hsr_forward_skb+0x9ee/0x3b10 net/hsr/hsr_forward.c:724
+ fill_frame_info net/hsr/hsr_forward.c:709 [inline]
+ hsr_forward_skb+0x9ee/0x3b10 net/hsr/hsr_forward.c:724
+ hsr_dev_xmit+0x2f0/0x350 net/hsr/hsr_device.c:235
+ __netdev_start_xmit include/linux/netdevice.h:5002 [inline]
+ netdev_start_xmit include/linux/netdevice.h:5011 [inline]
+ xmit_one net/core/dev.c:3590 [inline]
+ dev_hard_start_xmit+0x247/0xa20 net/core/dev.c:3606
+ __dev_queue_xmit+0x366a/0x57d0 net/core/dev.c:4434
+ dev_queue_xmit include/linux/netdevice.h:3168 [inline]
+ packet_xmit+0x9c/0x6c0 net/packet/af_packet.c:276
+ packet_snd net/packet/af_packet.c:3146 [inline]
+ packet_sendmsg+0x91ae/0xa6f0 net/packet/af_packet.c:3178
+ sock_sendmsg_nosec net/socket.c:711 [inline]
+ __sock_sendmsg+0x30f/0x380 net/socket.c:726
+ __sys_sendto+0x594/0x750 net/socket.c:2197
+ __do_sys_sendto net/socket.c:2204 [inline]
+ __se_sys_sendto net/socket.c:2200 [inline]
+ __x64_sys_sendto+0x125/0x1d0 net/socket.c:2200
+ x64_sys_call+0x346a/0x3c30 arch/x86/include/generated/asm/syscalls_64.h:45
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Uninit was created at:
+ slab_post_alloc_hook mm/slub.c:4091 [inline]
+ slab_alloc_node mm/slub.c:4134 [inline]
+ kmem_cache_alloc_node_noprof+0x6bf/0xb80 mm/slub.c:4186
+ kmalloc_reserve+0x13d/0x4a0 net/core/skbuff.c:587
+ __alloc_skb+0x363/0x7b0 net/core/skbuff.c:678
+ alloc_skb include/linux/skbuff.h:1323 [inline]
+ alloc_skb_with_frags+0xc8/0xd00 net/core/skbuff.c:6612
+ sock_alloc_send_pskb+0xa81/0xbf0 net/core/sock.c:2881
+ packet_alloc_skb net/packet/af_packet.c:2995 [inline]
+ packet_snd net/packet/af_packet.c:3089 [inline]
+ packet_sendmsg+0x74c6/0xa6f0 net/packet/af_packet.c:3178
+ sock_sendmsg_nosec net/socket.c:711 [inline]
+ __sock_sendmsg+0x30f/0x380 net/socket.c:726
+ __sys_sendto+0x594/0x750 net/socket.c:2197
+ __do_sys_sendto net/socket.c:2204 [inline]
+ __se_sys_sendto net/socket.c:2200 [inline]
+ __x64_sys_sendto+0x125/0x1d0 net/socket.c:2200
+ x64_sys_call+0x346a/0x3c30 arch/x86/include/generated/asm/syscalls_64.h:45
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fixes: 48b491a5cc74 ("net: hsr: fix mac_len checks")
+Reported-by: syzbot+671e2853f9851d039551@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/6745dc7f.050a0220.21d33d.0018.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: WingMan Kwok <w-kwok2@ti.com>
+Cc: Murali Karicheri <m-karicheri2@ti.com>
+Cc: MD Danish Anwar <danishanwar@ti.com>
+Cc: Jiri Pirko <jiri@nvidia.com>
+Cc: George McCollister <george.mccollister@gmail.com>
+Link: https://patch.msgid.link/20241126144344.4177332-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_forward.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
+index e31747d328e70..20d4c3f8d8750 100644
+--- a/net/hsr/hsr_forward.c
++++ b/net/hsr/hsr_forward.c
+@@ -546,6 +546,8 @@ static int fill_frame_info(struct hsr_frame_info *frame,
+ frame->is_vlan = true;
+
+ if (frame->is_vlan) {
++ if (skb->mac_len < offsetofend(struct hsr_vlan_ethhdr, vlanhdr))
++ return -EINVAL;
+ vlan_hdr = (struct hsr_vlan_ethhdr *)ethhdr;
+ proto = vlan_hdr->vlanhdr.h_vlan_encapsulated_proto;
+ /* FIXME: */
+--
+2.43.0
+
--- /dev/null
+From 4cb9e76a35556cb99d4956f365ada92126e78ef4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Nov 2024 09:59:50 +0100
+Subject: net/ipv6: release expired exception dst cached in socket
+
+From: Jiri Wiesner <jwiesner@suse.de>
+
+[ Upstream commit 3301ab7d5aeb0fe270f73a3d4810c9d1b6a9f045 ]
+
+Dst objects get leaked in ip6_negative_advice() when this function is
+executed for an expired IPv6 route located in the exception table. There
+are several conditions that must be fulfilled for the leak to occur:
+* an ICMPv6 packet indicating a change of the MTU for the path is received,
+ resulting in an exception dst being created
+* a TCP connection that uses the exception dst for routing packets must
+ start timing out so that TCP begins retransmissions
+* after the exception dst expires, the FIB6 garbage collector must not run
+ before TCP executes ip6_negative_advice() for the expired exception dst
+
+When TCP executes ip6_negative_advice() for an exception dst that has
+expired and if no other socket holds a reference to the exception dst, the
+refcount of the exception dst is 2, which corresponds to the increment
+made by dst_init() and the increment made by the TCP socket for which the
+connection is timing out. The refcount made by the socket is never
+released. The refcount of the dst is decremented in sk_dst_reset() but
+that decrement is counteracted by a dst_hold() intentionally placed just
+before the sk_dst_reset() in ip6_negative_advice(). After
+ip6_negative_advice() has finished, there is no other object tied to the
+dst. The socket lost its reference stored in sk_dst_cache and the dst is
+no longer in the exception table. The exception dst becomes a leaked
+object.
+
+As a result of this dst leak, an unbalanced refcount is reported for the
+loopback device of a net namespace being destroyed under kernels that do
+not contain e5f80fcf869a ("ipv6: give an IPv6 dev to blackhole_netdev"):
+unregister_netdevice: waiting for lo to become free. Usage count = 2
+
+Fix the dst leak by removing the dst_hold() in ip6_negative_advice(). The
+patch that introduced the dst_hold() in ip6_negative_advice() was
+92f1655aa2b22 ("net: fix __dst_negative_advice() race"). But 92f1655aa2b22
+merely refactored the code with regards to the dst refcount so the issue
+was present even before 92f1655aa2b22. The bug was introduced in
+54c1a859efd9f ("ipv6: Don't drop cache route entry unless timer actually
+expired.") where the expired cached route is deleted and the sk_dst_cache
+member of the socket is set to NULL by calling dst_negative_advice() but
+the refcount belonging to the socket is left unbalanced.
+
+The IPv4 version - ipv4_negative_advice() - is not affected by this bug.
+When the TCP connection times out ipv4_negative_advice() merely resets the
+sk_dst_cache of the socket while decrementing the refcount of the
+exception dst.
+
+Fixes: 92f1655aa2b22 ("net: fix __dst_negative_advice() race")
+Fixes: 54c1a859efd9f ("ipv6: Don't drop cache route entry unless timer actually expired.")
+Link: https://lore.kernel.org/netdev/20241113105611.GA6723@incl/T/#u
+Signed-off-by: Jiri Wiesner <jwiesner@suse.de>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20241128085950.GA4505@incl
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/route.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 35d3f02ddf163..407dba4327f53 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -2769,10 +2769,10 @@ static void ip6_negative_advice(struct sock *sk,
+ if (rt->rt6i_flags & RTF_CACHE) {
+ rcu_read_lock();
+ if (rt6_check_expired(rt)) {
+- /* counteract the dst_release() in sk_dst_reset() */
+- dst_hold(dst);
++ /* rt/dst can not be destroyed yet,
++ * because of rcu_read_lock()
++ */
+ sk_dst_reset(sk);
+-
+ rt6_remove_exception_rt(rt);
+ }
+ rcu_read_unlock();
+--
+2.43.0
+
--- /dev/null
+From 3426d4f2de2d47fdd8264b8b539339e1419fe429 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Nov 2024 09:33:58 +0100
+Subject: net/qed: allow old cards not supporting "num_images" to work
+
+From: Louis Leseur <louis.leseur@gmail.com>
+
+[ Upstream commit 7a0ea70da56ee8c2716d0b79e9959d3c47efab62 ]
+
+Commit 43645ce03e00 ("qed: Populate nvm image attribute shadow.")
+added support for populating flash image attributes, notably
+"num_images". However, some cards were not able to return this
+information. In such cases, the driver would return EINVAL, causing the
+driver to exit.
+
+Add check to return EOPNOTSUPP instead of EINVAL when the card is not
+able to return these information. The caller function already handles
+EOPNOTSUPP without error.
+
+Fixes: 43645ce03e00 ("qed: Populate nvm image attribute shadow.")
+Co-developed-by: Florian Forestier <florian@forestier.re>
+Signed-off-by: Florian Forestier <florian@forestier.re>
+Signed-off-by: Louis Leseur <louis.leseur@gmail.com>
+Link: https://patch.msgid.link/20241128083633.26431-1-louis.leseur@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/qlogic/qed/qed_mcp.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+index b734c120d508f..1f3834c6c5878 100644
+--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+@@ -3253,7 +3253,9 @@ int qed_mcp_bist_nvm_get_num_images(struct qed_hwfn *p_hwfn,
+ if (rc)
+ return rc;
+
+- if (((rsp & FW_MSG_CODE_MASK) != FW_MSG_CODE_OK))
++ if (((rsp & FW_MSG_CODE_MASK) == FW_MSG_CODE_UNSUPPORTED))
++ rc = -EOPNOTSUPP;
++ else if (((rsp & FW_MSG_CODE_MASK) != FW_MSG_CODE_OK))
+ rc = -EINVAL;
+
+ return rc;
+--
+2.43.0
+
--- /dev/null
+From a63291b5c03d302a554289bcbb74712f71de85fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Dec 2024 10:21:38 -0500
+Subject: net: sched: fix erspan_opt settings in cls_flower
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit 292207809486d99c78068d3f459cbbbffde88415 ]
+
+When matching erspan_opt in cls_flower, only the (version, dir, hwid)
+fields are relevant. However, in fl_set_erspan_opt() it initializes
+all bits of erspan_opt and its mask to 1. This inadvertently requires
+packets to match not only the (version, dir, hwid) fields but also the
+other fields that are unexpectedly set to 1.
+
+This patch resolves the issue by ensuring that only the (version, dir,
+hwid) fields are configured in fl_set_erspan_opt(), leaving the other
+fields to 0 in erspan_opt.
+
+Fixes: 79b1011cb33d ("net: sched: allow flower to match erspan options")
+Reported-by: Shuang Li <shuali@redhat.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Reviewed-by: Cong Wang <cong.wang@bytedance.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/cls_flower.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
+index bff0a5f24aca8..057612c97a372 100644
+--- a/net/sched/cls_flower.c
++++ b/net/sched/cls_flower.c
+@@ -1224,7 +1224,6 @@ static int fl_set_erspan_opt(const struct nlattr *nla, struct fl_flow_key *key,
+ int err;
+
+ md = (struct erspan_metadata *)&key->enc_opts.data[key->enc_opts.len];
+- memset(md, 0xff, sizeof(*md));
+ md->version = 1;
+
+ if (!depth)
+@@ -1253,9 +1252,9 @@ static int fl_set_erspan_opt(const struct nlattr *nla, struct fl_flow_key *key,
+ NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option index");
+ return -EINVAL;
+ }
++ memset(&md->u.index, 0xff, sizeof(md->u.index));
+ if (tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX]) {
+ nla = tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX];
+- memset(&md->u, 0x00, sizeof(md->u));
+ md->u.index = nla_get_be32(nla);
+ }
+ } else if (md->version == 2) {
+@@ -1264,10 +1263,12 @@ static int fl_set_erspan_opt(const struct nlattr *nla, struct fl_flow_key *key,
+ NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option dir or hwid");
+ return -EINVAL;
+ }
++ md->u.md2.dir = 1;
+ if (tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR]) {
+ nla = tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR];
+ md->u.md2.dir = nla_get_u8(nla);
+ }
++ set_hwid(&md->u.md2, 0xff);
+ if (tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID]) {
+ nla = tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID];
+ set_hwid(&md->u.md2, nla_get_u8(nla));
+--
+2.43.0
+
--- /dev/null
+From c017e9f8507e77817e179b082ec7f66cfecaaf9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Nov 2024 18:46:07 +0100
+Subject: net/sched: tbf: correct backlog statistic for GSO packets
+
+From: Martin Ottens <martin.ottens@fau.de>
+
+[ Upstream commit 1596a135e3180c92e42dd1fbcad321f4fb3e3b17 ]
+
+When the length of a GSO packet in the tbf qdisc is larger than the burst
+size configured the packet will be segmented by the tbf_segment function.
+Whenever this function is used to enqueue SKBs, the backlog statistic of
+the tbf is not increased correctly. This can lead to underflows of the
+'backlog' byte-statistic value when these packets are dequeued from tbf.
+
+Reproduce the bug:
+Ensure that the sender machine has GSO enabled. Configured the tbf on
+the outgoing interface of the machine as follows (burstsize = 1 MTU):
+$ tc qdisc add dev <oif> root handle 1: tbf rate 50Mbit burst 1514 latency 50ms
+
+Send bulk TCP traffic out via this interface, e.g., by running an iPerf3
+client on this machine. Check the qdisc statistics:
+$ tc -s qdisc show dev <oif>
+
+The 'backlog' byte-statistic has incorrect values while traffic is
+transferred, e.g., high values due to u32 underflows. When the transfer
+is stopped, the value is != 0, which should never happen.
+
+This patch fixes this bug by updating the statistics correctly, even if
+single SKBs of a GSO SKB cannot be enqueued.
+
+Fixes: e43ac79a4bc6 ("sch_tbf: segment too big GSO packets")
+Signed-off-by: Martin Ottens <martin.ottens@fau.de>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20241125174608.1484356-1-martin.ottens@fau.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_tbf.c | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
+index 7461e5c67d50a..5f50fdeaafa8d 100644
+--- a/net/sched/sch_tbf.c
++++ b/net/sched/sch_tbf.c
+@@ -193,7 +193,7 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch,
+ struct tbf_sched_data *q = qdisc_priv(sch);
+ struct sk_buff *segs, *nskb;
+ netdev_features_t features = netif_skb_features(skb);
+- unsigned int len = 0, prev_len = qdisc_pkt_len(skb);
++ unsigned int len = 0, prev_len = qdisc_pkt_len(skb), seg_len;
+ int ret, nb;
+
+ segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK);
+@@ -204,21 +204,27 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch,
+ nb = 0;
+ skb_list_walk_safe(segs, segs, nskb) {
+ skb_mark_not_on_list(segs);
+- qdisc_skb_cb(segs)->pkt_len = segs->len;
+- len += segs->len;
++ seg_len = segs->len;
++ qdisc_skb_cb(segs)->pkt_len = seg_len;
+ ret = qdisc_enqueue(segs, q->qdisc, to_free);
+ if (ret != NET_XMIT_SUCCESS) {
+ if (net_xmit_drop_count(ret))
+ qdisc_qstats_drop(sch);
+ } else {
+ nb++;
++ len += seg_len;
+ }
+ }
+ sch->q.qlen += nb;
+- if (nb > 1)
++ sch->qstats.backlog += len;
++ if (nb > 0) {
+ qdisc_tree_reduce_backlog(sch, 1 - nb, prev_len - len);
+- consume_skb(skb);
+- return nb > 0 ? NET_XMIT_SUCCESS : NET_XMIT_DROP;
++ consume_skb(skb);
++ return NET_XMIT_SUCCESS;
++ }
++
++ kfree_skb(skb);
++ return NET_XMIT_DROP;
+ }
+
+ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+--
+2.43.0
+
--- /dev/null
+From c2f5d6d5fa9488a1bc15c7715ca87d0751f693ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Nov 2024 21:30:14 +0800
+Subject: net/smc: fix LGR and link use-after-free issue
+
+From: Wen Gu <guwen@linux.alibaba.com>
+
+[ Upstream commit 2c7f14ed9c19ec0f149479d1c2842ec1f9bf76d7 ]
+
+We encountered a LGR/link use-after-free issue, which manifested as
+the LGR/link refcnt reaching 0 early and entering the clear process,
+making resource access unsafe.
+
+ refcount_t: addition on 0; use-after-free.
+ WARNING: CPU: 14 PID: 107447 at lib/refcount.c:25 refcount_warn_saturate+0x9c/0x140
+ Workqueue: events smc_lgr_terminate_work [smc]
+ Call trace:
+ refcount_warn_saturate+0x9c/0x140
+ __smc_lgr_terminate.part.45+0x2a8/0x370 [smc]
+ smc_lgr_terminate_work+0x28/0x30 [smc]
+ process_one_work+0x1b8/0x420
+ worker_thread+0x158/0x510
+ kthread+0x114/0x118
+
+or
+
+ refcount_t: underflow; use-after-free.
+ WARNING: CPU: 6 PID: 93140 at lib/refcount.c:28 refcount_warn_saturate+0xf0/0x140
+ Workqueue: smc_hs_wq smc_listen_work [smc]
+ Call trace:
+ refcount_warn_saturate+0xf0/0x140
+ smcr_link_put+0x1cc/0x1d8 [smc]
+ smc_conn_free+0x110/0x1b0 [smc]
+ smc_conn_abort+0x50/0x60 [smc]
+ smc_listen_find_device+0x75c/0x790 [smc]
+ smc_listen_work+0x368/0x8a0 [smc]
+ process_one_work+0x1b8/0x420
+ worker_thread+0x158/0x510
+ kthread+0x114/0x118
+
+It is caused by repeated release of LGR/link refcnt. One suspect is that
+smc_conn_free() is called repeatedly because some smc_conn_free() from
+server listening path are not protected by sock lock.
+
+e.g.
+
+Calls under socklock | smc_listen_work
+-------------------------------------------------------
+lock_sock(sk) | smc_conn_abort
+smc_conn_free | \- smc_conn_free
+\- smcr_link_put | \- smcr_link_put (duplicated)
+release_sock(sk)
+
+So here add sock lock protection in smc_listen_work() path, making it
+exclusive with other connection operations.
+
+Fixes: 3b2dec2603d5 ("net/smc: restructure client and server code in af_smc")
+Co-developed-by: Guangguan Wang <guangguan.wang@linux.alibaba.com>
+Signed-off-by: Guangguan Wang <guangguan.wang@linux.alibaba.com>
+Co-developed-by: Kai <KaiShen@linux.alibaba.com>
+Signed-off-by: Kai <KaiShen@linux.alibaba.com>
+Signed-off-by: Wen Gu <guwen@linux.alibaba.com>
+Reviewed-by: Wenjia Zhang <wenjia@linux.ibm.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/af_smc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
+index d433b88e6a277..1072b32a1d75d 100644
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -1509,6 +1509,7 @@ static void smc_listen_out(struct smc_sock *new_smc)
+ if (tcp_sk(new_smc->clcsock->sk)->syn_smc)
+ atomic_dec(&lsmc->queued_smc_hs);
+
++ release_sock(newsmcsk); /* lock in smc_listen_work() */
+ if (lsmc->sk.sk_state == SMC_LISTEN) {
+ lock_sock_nested(&lsmc->sk, SINGLE_DEPTH_NESTING);
+ smc_accept_enqueue(&lsmc->sk, newsmcsk);
+@@ -1921,6 +1922,7 @@ static void smc_listen_work(struct work_struct *work)
+ struct smc_init_info *ini = NULL;
+ int rc = 0;
+
++ lock_sock(&new_smc->sk); /* release in smc_listen_out() */
+ if (new_smc->listen_smc->sk.sk_state != SMC_LISTEN)
+ return smc_listen_out_err(new_smc);
+
+--
+2.43.0
+
--- /dev/null
+From baed6108d25c33ddbc43ad7b36b7a743d5bb61fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Feb 2022 17:11:35 +0800
+Subject: net/smc: Limit backlog connections
+
+From: D. Wythe <alibuda@linux.alibaba.com>
+
+[ Upstream commit 8270d9c21041470f58348248b9d9dcf3bf79592e ]
+
+Current implementation does not handling backlog semantics, one
+potential risk is that server will be flooded by infinite amount
+connections, even if client was SMC-incapable.
+
+This patch works to put a limit on backlog connections, referring to the
+TCP implementation, we divides SMC connections into two categories:
+
+1. Half SMC connection, which includes all TCP established while SMC not
+connections.
+
+2. Full SMC connection, which includes all SMC established connections.
+
+For half SMC connection, since all half SMC connections starts with TCP
+established, we can achieve our goal by put a limit before TCP
+established. Refer to the implementation of TCP, this limits will based
+on not only the half SMC connections but also the full connections,
+which is also a constraint on full SMC connections.
+
+For full SMC connections, although we know exactly where it starts, it's
+quite hard to put a limit before it. The easiest way is to block wait
+before receive SMC confirm CLC message, while it's under protection by
+smc_server_lgr_pending, a global lock, which leads this limit to the
+entire host instead of a single listen socket. Another way is to drop
+the full connections, but considering the cast of SMC connections, we
+prefer to keep full SMC connections.
+
+Even so, the limits of full SMC connections still exists, see commits
+about half SMC connection below.
+
+After this patch, the limits of backend connection shows like:
+
+For SMC:
+
+1. Client with SMC-capability can makes 2 * backlog full SMC connections
+ or 1 * backlog half SMC connections and 1 * backlog full SMC
+ connections at most.
+
+2. Client without SMC-capability can only makes 1 * backlog half TCP
+ connections and 1 * backlog full TCP connections.
+
+Signed-off-by: D. Wythe <alibuda@linux.alibaba.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 2c7f14ed9c19 ("net/smc: fix LGR and link use-after-free issue")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/af_smc.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
+ net/smc/smc.h | 6 +++++-
+ 2 files changed, 50 insertions(+), 1 deletion(-)
+
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
+index bd0b3a8b95d50..d433b88e6a277 100644
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -71,6 +71,36 @@ static void smc_set_keepalive(struct sock *sk, int val)
+ smc->clcsock->sk->sk_prot->keepalive(smc->clcsock->sk, val);
+ }
+
++static struct sock *smc_tcp_syn_recv_sock(const struct sock *sk,
++ struct sk_buff *skb,
++ struct request_sock *req,
++ struct dst_entry *dst,
++ struct request_sock *req_unhash,
++ bool *own_req)
++{
++ struct smc_sock *smc;
++
++ smc = smc_clcsock_user_data(sk);
++
++ if (READ_ONCE(sk->sk_ack_backlog) + atomic_read(&smc->queued_smc_hs) >
++ sk->sk_max_ack_backlog)
++ goto drop;
++
++ if (sk_acceptq_is_full(&smc->sk)) {
++ NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
++ goto drop;
++ }
++
++ /* passthrough to original syn recv sock fct */
++ return smc->ori_af_ops->syn_recv_sock(sk, skb, req, dst, req_unhash,
++ own_req);
++
++drop:
++ dst_release(dst);
++ tcp_listendrop(sk);
++ return NULL;
++}
++
+ static struct smc_hashinfo smc_v4_hashinfo = {
+ .lock = __RW_LOCK_UNLOCKED(smc_v4_hashinfo.lock),
+ };
+@@ -1476,6 +1506,9 @@ static void smc_listen_out(struct smc_sock *new_smc)
+ struct smc_sock *lsmc = new_smc->listen_smc;
+ struct sock *newsmcsk = &new_smc->sk;
+
++ if (tcp_sk(new_smc->clcsock->sk)->syn_smc)
++ atomic_dec(&lsmc->queued_smc_hs);
++
+ if (lsmc->sk.sk_state == SMC_LISTEN) {
+ lock_sock_nested(&lsmc->sk, SINGLE_DEPTH_NESTING);
+ smc_accept_enqueue(&lsmc->sk, newsmcsk);
+@@ -2008,6 +2041,9 @@ static void smc_tcp_listen_work(struct work_struct *work)
+ if (!new_smc)
+ continue;
+
++ if (tcp_sk(new_smc->clcsock->sk)->syn_smc)
++ atomic_inc(&lsmc->queued_smc_hs);
++
+ new_smc->listen_smc = lsmc;
+ new_smc->use_fallback = lsmc->use_fallback;
+ new_smc->fallback_rsn = lsmc->fallback_rsn;
+@@ -2074,6 +2110,15 @@ static int smc_listen(struct socket *sock, int backlog)
+ smc->clcsock->sk->sk_data_ready = smc_clcsock_data_ready;
+ smc->clcsock->sk->sk_user_data =
+ (void *)((uintptr_t)smc | SK_USER_DATA_NOCOPY);
++
++ /* save original ops */
++ smc->ori_af_ops = inet_csk(smc->clcsock->sk)->icsk_af_ops;
++
++ smc->af_ops = *smc->ori_af_ops;
++ smc->af_ops.syn_recv_sock = smc_tcp_syn_recv_sock;
++
++ inet_csk(smc->clcsock->sk)->icsk_af_ops = &smc->af_ops;
++
+ rc = kernel_listen(smc->clcsock, backlog);
+ if (rc) {
+ smc->clcsock->sk->sk_data_ready = smc->clcsk_data_ready;
+diff --git a/net/smc/smc.h b/net/smc/smc.h
+index 57e376756b913..1c00f1bba2cdb 100644
+--- a/net/smc/smc.h
++++ b/net/smc/smc.h
+@@ -241,6 +241,10 @@ struct smc_sock { /* smc sock container */
+ bool use_fallback; /* fallback to tcp */
+ int fallback_rsn; /* reason for fallback */
+ u32 peer_diagnosis; /* decline reason from peer */
++ atomic_t queued_smc_hs; /* queued smc handshakes */
++ struct inet_connection_sock_af_ops af_ops;
++ const struct inet_connection_sock_af_ops *ori_af_ops;
++ /* original af ops */
+ int sockopt_defer_accept;
+ /* sockopt TCP_DEFER_ACCEPT
+ * value
+@@ -265,7 +269,7 @@ static inline struct smc_sock *smc_sk(const struct sock *sk)
+ return (struct smc_sock *)sk;
+ }
+
+-static inline struct smc_sock *smc_clcsock_user_data(struct sock *clcsk)
++static inline struct smc_sock *smc_clcsock_user_data(const struct sock *clcsk)
+ {
+ return (struct smc_sock *)
+ ((uintptr_t)clcsk->sk_user_data & ~SK_USER_DATA_NOCOPY);
+--
+2.43.0
+
--- /dev/null
+From f38cbbc568896cd7ba7fd3e438e0b678b91e46f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Nov 2024 16:30:38 +0100
+Subject: netfilter: ipset: Hold module reference while requesting a module
+
+From: Phil Sutter <phil@nwl.cc>
+
+[ Upstream commit 456f010bfaefde84d3390c755eedb1b0a5857c3c ]
+
+User space may unload ip_set.ko while it is itself requesting a set type
+backend module, leading to a kernel crash. The race condition may be
+provoked by inserting an mdelay() right after the nfnl_unlock() call.
+
+Fixes: a7b4f989a629 ("netfilter: ipset: IP set core support")
+Signed-off-by: Phil Sutter <phil@nwl.cc>
+Acked-by: Jozsef Kadlecsik <kadlec@netfilter.org>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipset/ip_set_core.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
+index f2f6b7325c706..72e5638206c0e 100644
+--- a/net/netfilter/ipset/ip_set_core.c
++++ b/net/netfilter/ipset/ip_set_core.c
+@@ -104,14 +104,19 @@ find_set_type(const char *name, u8 family, u8 revision)
+ static bool
+ load_settype(const char *name)
+ {
++ if (!try_module_get(THIS_MODULE))
++ return false;
++
+ nfnl_unlock(NFNL_SUBSYS_IPSET);
+ pr_debug("try to load ip_set_%s\n", name);
+ if (request_module("ip_set_%s", name) < 0) {
+ pr_warn("Can't find ip_set type %s\n", name);
+ nfnl_lock(NFNL_SUBSYS_IPSET);
++ module_put(THIS_MODULE);
+ return false;
+ }
+ nfnl_lock(NFNL_SUBSYS_IPSET);
++ module_put(THIS_MODULE);
+ return true;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From bc68880146f0e721d84010bb438233d55b5aaad1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Dec 2024 00:04:49 +0100
+Subject: netfilter: nft_set_hash: skip duplicated elements pending gc run
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 7ffc7481153bbabf3332c6a19b289730c7e1edf5 ]
+
+rhashtable does not provide stable walk, duplicated elements are
+possible in case of resizing. I considered that checking for errors when
+calling rhashtable_walk_next() was sufficient to detect the resizing.
+However, rhashtable_walk_next() returns -EAGAIN only at the end of the
+iteration, which is too late, because a gc work containing duplicated
+elements could have been already scheduled for removal to the worker.
+
+Add a u32 gc worker sequence number per set, bump it on every workqueue
+run. Annotate gc worker sequence number on the expired element. Use it
+to skip those already seen in this gc workqueue run.
+
+Note that this new field is never reset in case gc transaction fails, so
+next gc worker run on the expired element overrides it. Wraparound of gc
+worker sequence number should not be an issue with stale gc worker
+sequence number in the element, that would just postpone the element
+removal in one gc run.
+
+Note that it is not possible to use flags to annotate that element is
+pending gc run to detect duplicates, given that gc transaction can be
+invalidated in case of update from the control plane, therefore, not
+allowing to clear such flag.
+
+On x86_64, pahole reports no changes in the size of nft_rhash_elem.
+
+Fixes: f6c383b8c31a ("netfilter: nf_tables: adapt set backend to use GC transaction API")
+Reported-by: Laurent Fasnacht <laurent.fasnacht@proton.ch>
+Tested-by: Laurent Fasnacht <laurent.fasnacht@proton.ch>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_set_hash.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c
+index 1fd3b413350dc..5c4209b49bda7 100644
+--- a/net/netfilter/nft_set_hash.c
++++ b/net/netfilter/nft_set_hash.c
+@@ -24,10 +24,12 @@
+ struct nft_rhash {
+ struct rhashtable ht;
+ struct delayed_work gc_work;
++ u32 wq_gc_seq;
+ };
+
+ struct nft_rhash_elem {
+ struct rhash_head node;
++ u32 wq_gc_seq;
+ struct nft_set_ext ext;
+ };
+
+@@ -339,6 +341,10 @@ static void nft_rhash_gc(struct work_struct *work)
+ if (!gc)
+ goto done;
+
++ /* Elements never collected use a zero gc worker sequence number. */
++ if (unlikely(++priv->wq_gc_seq == 0))
++ priv->wq_gc_seq++;
++
+ rhashtable_walk_enter(&priv->ht, &hti);
+ rhashtable_walk_start(&hti);
+
+@@ -356,6 +362,14 @@ static void nft_rhash_gc(struct work_struct *work)
+ goto try_later;
+ }
+
++ /* rhashtable walk is unstable, already seen in this gc run?
++ * Then, skip this element. In case of (unlikely) sequence
++ * wraparound and stale element wq_gc_seq, next gc run will
++ * just find this expired element.
++ */
++ if (he->wq_gc_seq == priv->wq_gc_seq)
++ continue;
++
+ if (nft_set_elem_is_dead(&he->ext))
+ goto dead_elem;
+
+@@ -372,6 +386,8 @@ static void nft_rhash_gc(struct work_struct *work)
+ if (!gc)
+ goto try_later;
+
++ /* annotate gc sequence for this attempt. */
++ he->wq_gc_seq = priv->wq_gc_seq;
+ nft_trans_gc_elem_add(gc, he);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 3584065cf9b9c5aa9e7bc8f0109d5bbfbbf2f667 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Nov 2024 09:55:42 +0300
+Subject: netfilter: x_tables: fix LED ID check in led_tg_check()
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit 04317f4eb2aad312ad85c1a17ad81fe75f1f9bc7 ]
+
+Syzbot has reported the following BUG detected by KASAN:
+
+BUG: KASAN: slab-out-of-bounds in strlen+0x58/0x70
+Read of size 1 at addr ffff8881022da0c8 by task repro/5879
+...
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x241/0x360
+ ? __pfx_dump_stack_lvl+0x10/0x10
+ ? __pfx__printk+0x10/0x10
+ ? _printk+0xd5/0x120
+ ? __virt_addr_valid+0x183/0x530
+ ? __virt_addr_valid+0x183/0x530
+ print_report+0x169/0x550
+ ? __virt_addr_valid+0x183/0x530
+ ? __virt_addr_valid+0x183/0x530
+ ? __virt_addr_valid+0x45f/0x530
+ ? __phys_addr+0xba/0x170
+ ? strlen+0x58/0x70
+ kasan_report+0x143/0x180
+ ? strlen+0x58/0x70
+ strlen+0x58/0x70
+ kstrdup+0x20/0x80
+ led_tg_check+0x18b/0x3c0
+ xt_check_target+0x3bb/0xa40
+ ? __pfx_xt_check_target+0x10/0x10
+ ? stack_depot_save_flags+0x6e4/0x830
+ ? nft_target_init+0x174/0xc30
+ nft_target_init+0x82d/0xc30
+ ? __pfx_nft_target_init+0x10/0x10
+ ? nf_tables_newrule+0x1609/0x2980
+ ? nf_tables_newrule+0x1609/0x2980
+ ? rcu_is_watching+0x15/0xb0
+ ? nf_tables_newrule+0x1609/0x2980
+ ? nf_tables_newrule+0x1609/0x2980
+ ? __kmalloc_noprof+0x21a/0x400
+ nf_tables_newrule+0x1860/0x2980
+ ? __pfx_nf_tables_newrule+0x10/0x10
+ ? __nla_parse+0x40/0x60
+ nfnetlink_rcv+0x14e5/0x2ab0
+ ? __pfx_validate_chain+0x10/0x10
+ ? __pfx_nfnetlink_rcv+0x10/0x10
+ ? __lock_acquire+0x1384/0x2050
+ ? netlink_deliver_tap+0x2e/0x1b0
+ ? __pfx_lock_release+0x10/0x10
+ ? netlink_deliver_tap+0x2e/0x1b0
+ netlink_unicast+0x7f8/0x990
+ ? __pfx_netlink_unicast+0x10/0x10
+ ? __virt_addr_valid+0x183/0x530
+ ? __check_object_size+0x48e/0x900
+ netlink_sendmsg+0x8e4/0xcb0
+ ? __pfx_netlink_sendmsg+0x10/0x10
+ ? aa_sock_msg_perm+0x91/0x160
+ ? __pfx_netlink_sendmsg+0x10/0x10
+ __sock_sendmsg+0x223/0x270
+ ____sys_sendmsg+0x52a/0x7e0
+ ? __pfx_____sys_sendmsg+0x10/0x10
+ __sys_sendmsg+0x292/0x380
+ ? __pfx___sys_sendmsg+0x10/0x10
+ ? lockdep_hardirqs_on_prepare+0x43d/0x780
+ ? __pfx_lockdep_hardirqs_on_prepare+0x10/0x10
+ ? exc_page_fault+0x590/0x8c0
+ ? do_syscall_64+0xb6/0x230
+ do_syscall_64+0xf3/0x230
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+...
+ </TASK>
+
+Since an invalid (without '\0' byte at all) byte sequence may be passed
+from userspace, add an extra check to ensure that such a sequence is
+rejected as possible ID and so never passed to 'kstrdup()' and further.
+
+Reported-by: syzbot+6c8215822f35fdb35667@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=6c8215822f35fdb35667
+Fixes: 268cb38e1802 ("netfilter: x_tables: add LED trigger target")
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/xt_LED.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/netfilter/xt_LED.c b/net/netfilter/xt_LED.c
+index 211bfa2a2ac04..c2c10a536cc68 100644
+--- a/net/netfilter/xt_LED.c
++++ b/net/netfilter/xt_LED.c
+@@ -97,7 +97,9 @@ static int led_tg_check(const struct xt_tgchk_param *par)
+ struct xt_led_info_internal *ledinternal;
+ int err;
+
+- if (ledinfo->id[0] == '\0')
++ /* Bail out if empty string or not a string at all. */
++ if (ledinfo->id[0] == '\0' ||
++ !memchr(ledinfo->id, '\0', sizeof(ledinfo->id)))
+ return -EINVAL;
+
+ mutex_lock(&xt_led_mutex);
+--
+2.43.0
+
--- /dev/null
+From 980a99dd285b52ce1faabc17596a850fe829e011 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Nov 2024 10:59:54 +0000
+Subject: ptp: Add error handling for adjfine callback in ptp_clock_adjtime
+
+From: Ajay Kaher <ajay.kaher@broadcom.com>
+
+[ Upstream commit 98337d7c87577ded71114f6976edb70a163e27bc ]
+
+ptp_clock_adjtime sets ptp->dialed_frequency even when adjfine
+callback returns an error. This causes subsequent reads to return
+an incorrect value.
+
+Fix this by adding error check before ptp->dialed_frequency is set.
+
+Fixes: 39a8cbd9ca05 ("ptp: remember the adjusted frequency")
+Signed-off-by: Ajay Kaher <ajay.kaher@broadcom.com>
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Link: https://patch.msgid.link/20241125105954.1509971-1-ajay.kaher@broadcom.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ptp/ptp_clock.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
+index e70c6dec3a3a3..92dd1c6f54f4a 100644
+--- a/drivers/ptp/ptp_clock.c
++++ b/drivers/ptp/ptp_clock.c
+@@ -136,7 +136,8 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx)
+ err = ops->adjfine(ops, tx->freq);
+ else
+ err = ops->adjfreq(ops, ppb);
+- ptp->dialed_frequency = tx->freq;
++ if (!err)
++ ptp->dialed_frequency = tx->freq;
+ } else if (tx->modes & ADJ_OFFSET) {
+ if (ops->adjphase) {
+ s32 offset = tx->offset;
+--
+2.43.0
+
--- /dev/null
+From c080688daab7ea65b1f7914ee83648305a130cd9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Nov 2024 14:56:29 +0530
+Subject: serial: amba-pl011: Fix RX stall when DMA is used
+
+From: Kartik Rajput <kkartik@nvidia.com>
+
+[ Upstream commit 2bcacc1c87acf9a8ebc17de18cb2b3cfeca547cf ]
+
+Function pl011_throttle_rx() calls pl011_stop_rx() to disable RX, which
+also disables the RX DMA by clearing the RXDMAE bit of the DMACR
+register. However, to properly unthrottle RX when DMA is used, the
+function pl011_unthrottle_rx() is expected to set the RXDMAE bit of
+the DMACR register, which it currently lacks. This causes RX to stall
+after the throttle API is called.
+
+Set RXDMAE bit in the DMACR register while unthrottling RX if RX DMA is
+used.
+
+Fixes: 211565b10099 ("serial: pl011: UPSTAT_AUTORTS requires .throttle/unthrottle")
+Cc: stable@vger.kernel.org
+Signed-off-by: Kartik Rajput <kkartik@nvidia.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/20241113092629.60226-1-kkartik@nvidia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/amba-pl011.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
+index 16fc159bdf3b9..8ae8fb8132d5b 100644
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -1842,6 +1842,11 @@ static void pl011_unthrottle_rx(struct uart_port *port)
+
+ pl011_write(uap->im, uap, REG_IMSC);
+
++ if (uap->using_rx_dma) {
++ uap->dmacr |= UART011_RXDMAE;
++ pl011_write(uap->dmacr, uap, REG_DMACR);
++ }
++
+ uart_port_unlock_irqrestore(&uap->port, flags);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From de8b11d5e089eca946f187e136df1b4a6019c8ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Sep 2023 20:43:34 +0206
+Subject: serial: amba-pl011: Use port lock wrappers
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit 68ca3e72d7463d79d29b6e4961d6028df2a88e25 ]
+
+When a serial port is used for kernel console output, then all
+modifications to the UART registers which are done from other contexts,
+e.g. getty, termios, are interference points for the kernel console.
+
+So far this has been ignored and the printk output is based on the
+principle of hope. The rework of the console infrastructure which aims to
+support threaded and atomic consoles, requires to mark sections which
+modify the UART registers as unsafe. This allows the atomic write function
+to make informed decisions and eventually to restore operational state. It
+also allows to prevent the regular UART code from modifying UART registers
+while printk output is in progress.
+
+All modifications of UART registers are guarded by the UART port lock,
+which provides an obvious synchronization point with the console
+infrastructure.
+
+To avoid adding this functionality to all UART drivers, wrap the
+spin_[un]lock*() invocations for uart_port::lock into helper functions
+which just contain the spin_[un]lock*() invocations for now. In a
+subsequent step these helpers will gain the console synchronization
+mechanisms.
+
+Converted with coccinelle. No functional change.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: John Ogness <john.ogness@linutronix.de>
+Link: https://lore.kernel.org/r/20230914183831.587273-18-john.ogness@linutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 2bcacc1c87ac ("serial: amba-pl011: Fix RX stall when DMA is used")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/amba-pl011.c | 72 ++++++++++++++++-----------------
+ 1 file changed, 36 insertions(+), 36 deletions(-)
+
+diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
+index a5eb5dc275ccd..16fc159bdf3b9 100644
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -351,9 +351,9 @@ static int pl011_fifo_to_tty(struct uart_amba_port *uap)
+ flag = TTY_FRAME;
+ }
+
+- spin_unlock(&uap->port.lock);
++ uart_port_unlock(&uap->port);
+ sysrq = uart_handle_sysrq_char(&uap->port, ch & 255);
+- spin_lock(&uap->port.lock);
++ uart_port_lock(&uap->port);
+
+ if (!sysrq)
+ uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag);
+@@ -548,7 +548,7 @@ static void pl011_dma_tx_callback(void *data)
+ unsigned long flags;
+ u16 dmacr;
+
+- spin_lock_irqsave(&uap->port.lock, flags);
++ uart_port_lock_irqsave(&uap->port, &flags);
+ if (uap->dmatx.queued)
+ dma_unmap_single(dmatx->chan->device->dev, dmatx->dma,
+ dmatx->len, DMA_TO_DEVICE);
+@@ -569,7 +569,7 @@ static void pl011_dma_tx_callback(void *data)
+ if (!(dmacr & UART011_TXDMAE) || uart_tx_stopped(&uap->port) ||
+ uart_circ_empty(&uap->port.state->xmit)) {
+ uap->dmatx.queued = false;
+- spin_unlock_irqrestore(&uap->port.lock, flags);
++ uart_port_unlock_irqrestore(&uap->port, flags);
+ return;
+ }
+
+@@ -580,7 +580,7 @@ static void pl011_dma_tx_callback(void *data)
+ */
+ pl011_start_tx_pio(uap);
+
+- spin_unlock_irqrestore(&uap->port.lock, flags);
++ uart_port_unlock_irqrestore(&uap->port, flags);
+ }
+
+ /*
+@@ -1009,7 +1009,7 @@ static void pl011_dma_rx_callback(void *data)
+ * routine to flush out the secondary DMA buffer while
+ * we immediately trigger the next DMA job.
+ */
+- spin_lock_irq(&uap->port.lock);
++ uart_port_lock_irq(&uap->port);
+ /*
+ * Rx data can be taken by the UART interrupts during
+ * the DMA irq handler. So we check the residue here.
+@@ -1025,7 +1025,7 @@ static void pl011_dma_rx_callback(void *data)
+ ret = pl011_dma_rx_trigger_dma(uap);
+
+ pl011_dma_rx_chars(uap, pending, lastbuf, false);
+- spin_unlock_irq(&uap->port.lock);
++ uart_port_unlock_irq(&uap->port);
+ /*
+ * Do this check after we picked the DMA chars so we don't
+ * get some IRQ immediately from RX.
+@@ -1091,11 +1091,11 @@ static void pl011_dma_rx_poll(struct timer_list *t)
+ if (jiffies_to_msecs(jiffies - dmarx->last_jiffies)
+ > uap->dmarx.poll_timeout) {
+
+- spin_lock_irqsave(&uap->port.lock, flags);
++ uart_port_lock_irqsave(&uap->port, &flags);
+ pl011_dma_rx_stop(uap);
+ uap->im |= UART011_RXIM;
+ pl011_write(uap->im, uap, REG_IMSC);
+- spin_unlock_irqrestore(&uap->port.lock, flags);
++ uart_port_unlock_irqrestore(&uap->port, flags);
+
+ uap->dmarx.running = false;
+ dmaengine_terminate_all(rxchan);
+@@ -1191,10 +1191,10 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap)
+ while (pl011_read(uap, REG_FR) & uap->vendor->fr_busy)
+ cpu_relax();
+
+- spin_lock_irq(&uap->port.lock);
++ uart_port_lock_irq(&uap->port);
+ uap->dmacr &= ~(UART011_DMAONERR | UART011_RXDMAE | UART011_TXDMAE);
+ pl011_write(uap->dmacr, uap, REG_DMACR);
+- spin_unlock_irq(&uap->port.lock);
++ uart_port_unlock_irq(&uap->port);
+
+ if (uap->using_tx_dma) {
+ /* In theory, this should already be done by pl011_dma_flush_buffer */
+@@ -1405,9 +1405,9 @@ static void pl011_throttle_rx(struct uart_port *port)
+ {
+ unsigned long flags;
+
+- spin_lock_irqsave(&port->lock, flags);
++ uart_port_lock_irqsave(port, &flags);
+ pl011_stop_rx(port);
+- spin_unlock_irqrestore(&port->lock, flags);
++ uart_port_unlock_irqrestore(port, flags);
+ }
+
+ static void pl011_enable_ms(struct uart_port *port)
+@@ -1425,7 +1425,7 @@ __acquires(&uap->port.lock)
+ {
+ pl011_fifo_to_tty(uap);
+
+- spin_unlock(&uap->port.lock);
++ uart_port_unlock(&uap->port);
+ tty_flip_buffer_push(&uap->port.state->port);
+ /*
+ * If we were temporarily out of DMA mode for a while,
+@@ -1450,7 +1450,7 @@ __acquires(&uap->port.lock)
+ #endif
+ }
+ }
+- spin_lock(&uap->port.lock);
++ uart_port_lock(&uap->port);
+ }
+
+ static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c,
+@@ -1556,7 +1556,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
+ unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
+ int handled = 0;
+
+- spin_lock_irqsave(&uap->port.lock, flags);
++ uart_port_lock_irqsave(&uap->port, &flags);
+ status = pl011_read(uap, REG_RIS) & uap->im;
+ if (status) {
+ do {
+@@ -1586,7 +1586,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
+ handled = 1;
+ }
+
+- spin_unlock_irqrestore(&uap->port.lock, flags);
++ uart_port_unlock_irqrestore(&uap->port, flags);
+
+ return IRQ_RETVAL(handled);
+ }
+@@ -1658,14 +1658,14 @@ static void pl011_break_ctl(struct uart_port *port, int break_state)
+ unsigned long flags;
+ unsigned int lcr_h;
+
+- spin_lock_irqsave(&uap->port.lock, flags);
++ uart_port_lock_irqsave(&uap->port, &flags);
+ lcr_h = pl011_read(uap, REG_LCRH_TX);
+ if (break_state == -1)
+ lcr_h |= UART01x_LCRH_BRK;
+ else
+ lcr_h &= ~UART01x_LCRH_BRK;
+ pl011_write(lcr_h, uap, REG_LCRH_TX);
+- spin_unlock_irqrestore(&uap->port.lock, flags);
++ uart_port_unlock_irqrestore(&uap->port, flags);
+ }
+
+ #ifdef CONFIG_CONSOLE_POLL
+@@ -1804,7 +1804,7 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap)
+ unsigned long flags;
+ unsigned int i;
+
+- spin_lock_irqsave(&uap->port.lock, flags);
++ uart_port_lock_irqsave(&uap->port, &flags);
+
+ /* Clear out any spuriously appearing RX interrupts */
+ pl011_write(UART011_RTIS | UART011_RXIS, uap, REG_ICR);
+@@ -1826,7 +1826,7 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap)
+ if (!pl011_dma_rx_running(uap))
+ uap->im |= UART011_RXIM;
+ pl011_write(uap->im, uap, REG_IMSC);
+- spin_unlock_irqrestore(&uap->port.lock, flags);
++ uart_port_unlock_irqrestore(&uap->port, flags);
+ }
+
+ static void pl011_unthrottle_rx(struct uart_port *port)
+@@ -1834,7 +1834,7 @@ static void pl011_unthrottle_rx(struct uart_port *port)
+ struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port);
+ unsigned long flags;
+
+- spin_lock_irqsave(&uap->port.lock, flags);
++ uart_port_lock_irqsave(&uap->port, &flags);
+
+ uap->im = UART011_RTIM;
+ if (!pl011_dma_rx_running(uap))
+@@ -1842,7 +1842,7 @@ static void pl011_unthrottle_rx(struct uart_port *port)
+
+ pl011_write(uap->im, uap, REG_IMSC);
+
+- spin_unlock_irqrestore(&uap->port.lock, flags);
++ uart_port_unlock_irqrestore(&uap->port, flags);
+ }
+
+ static int pl011_startup(struct uart_port *port)
+@@ -1862,7 +1862,7 @@ static int pl011_startup(struct uart_port *port)
+
+ pl011_write(uap->vendor->ifls, uap, REG_IFLS);
+
+- spin_lock_irq(&uap->port.lock);
++ uart_port_lock_irq(&uap->port);
+
+ /* restore RTS and DTR */
+ cr = uap->old_cr & (UART011_CR_RTS | UART011_CR_DTR);
+@@ -1873,7 +1873,7 @@ static int pl011_startup(struct uart_port *port)
+
+ pl011_write(cr, uap, REG_CR);
+
+- spin_unlock_irq(&uap->port.lock);
++ uart_port_unlock_irq(&uap->port);
+
+ /*
+ * initialise the old status of the modem signals
+@@ -1934,13 +1934,13 @@ static void pl011_disable_uart(struct uart_amba_port *uap)
+ unsigned int cr;
+
+ uap->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS);
+- spin_lock_irq(&uap->port.lock);
++ uart_port_lock_irq(&uap->port);
+ cr = pl011_read(uap, REG_CR);
+ uap->old_cr = cr;
+ cr &= UART011_CR_RTS | UART011_CR_DTR;
+ cr |= UART01x_CR_UARTEN | UART011_CR_TXE;
+ pl011_write(cr, uap, REG_CR);
+- spin_unlock_irq(&uap->port.lock);
++ uart_port_unlock_irq(&uap->port);
+
+ /*
+ * disable break condition and fifos
+@@ -1952,14 +1952,14 @@ static void pl011_disable_uart(struct uart_amba_port *uap)
+
+ static void pl011_disable_interrupts(struct uart_amba_port *uap)
+ {
+- spin_lock_irq(&uap->port.lock);
++ uart_port_lock_irq(&uap->port);
+
+ /* mask all interrupts and clear all pending ones */
+ uap->im = 0;
+ pl011_write(uap->im, uap, REG_IMSC);
+ pl011_write(0xffff, uap, REG_ICR);
+
+- spin_unlock_irq(&uap->port.lock);
++ uart_port_unlock_irq(&uap->port);
+ }
+
+ static void pl011_shutdown(struct uart_port *port)
+@@ -2104,7 +2104,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
+
+ bits = tty_get_frame_size(termios->c_cflag);
+
+- spin_lock_irqsave(&port->lock, flags);
++ uart_port_lock_irqsave(port, &flags);
+
+ /*
+ * Update the per-port timeout.
+@@ -2171,7 +2171,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
+ pl011_write_lcr_h(uap, lcr_h);
+ pl011_write(old_cr, uap, REG_CR);
+
+- spin_unlock_irqrestore(&port->lock, flags);
++ uart_port_unlock_irqrestore(port, flags);
+ }
+
+ static void
+@@ -2189,10 +2189,10 @@ sbsa_uart_set_termios(struct uart_port *port, struct ktermios *termios,
+ termios->c_cflag &= ~(CMSPAR | CRTSCTS);
+ termios->c_cflag |= CS8 | CLOCAL;
+
+- spin_lock_irqsave(&port->lock, flags);
++ uart_port_lock_irqsave(port, &flags);
+ uart_update_timeout(port, CS8, uap->fixed_baud);
+ pl011_setup_status_masks(port, termios);
+- spin_unlock_irqrestore(&port->lock, flags);
++ uart_port_unlock_irqrestore(port, flags);
+ }
+
+ static const char *pl011_type(struct uart_port *port)
+@@ -2345,9 +2345,9 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
+ if (uap->port.sysrq)
+ locked = 0;
+ else if (oops_in_progress)
+- locked = spin_trylock(&uap->port.lock);
++ locked = uart_port_trylock(&uap->port);
+ else
+- spin_lock(&uap->port.lock);
++ uart_port_lock(&uap->port);
+
+ /*
+ * First save the CR then disable the interrupts
+@@ -2373,7 +2373,7 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
+ pl011_write(old_cr, uap, REG_CR);
+
+ if (locked)
+- spin_unlock(&uap->port.lock);
++ uart_port_unlock(&uap->port);
+ local_irq_restore(flags);
+
+ clk_disable(uap->clk);
+--
+2.43.0
+
drm-sti-avoid-potential-dereference-of-error-pointers-in-sti_gdp_atomic_check.patch
drm-sti-avoid-potential-dereference-of-error-pointers.patch
drm-etnaviv-flush-shader-l1-cache-after-user-commandstream.patch
+itco_wdt-mask-nmi_now-bit-for-update_no_reboot_bit-c.patch
+watchdog-mediatek-make-sure-system-reset-gets-assert.patch
+can-peak_usb-canfd-store-64-bits-hw-timestamps.patch
+can-do-not-increase-rx-statistics-when-generating-a-.patch
+can-c_can-c_can_handle_bus_err-update-statistics-if-.patch
+can-sun4i_can-sun4i_can_err-call-can_change_state-ev.patch
+can-m_can-m_can_handle_lec_err-fix-rx-tx-_errors-sta.patch
+can-ifi_canfd-ifi_canfd_handle_lec_err-fix-rx-tx-_er.patch
+can-sun4i_can-sun4i_can_err-fix-rx-tx-_errors-statis.patch
+can-ems_usb-ems_usb_rx_err-fix-rx-tx-_errors-statist.patch
+ipvs-fix-ub-due-to-uninitialized-stack-access-in-ip_.patch
+netfilter-x_tables-fix-led-id-check-in-led_tg_check.patch
+ptp-add-error-handling-for-adjfine-callback-in-ptp_c.patch
+net-sched-tbf-correct-backlog-statistic-for-gso-pack.patch
+net-hsr-avoid-potential-out-of-bound-access-in-fill_.patch
+can-j1939-j1939_session_new-fix-skb-reference-counti.patch
+net-ipv6-release-expired-exception-dst-cached-in-soc.patch
+dccp-fix-memory-leak-in-dccp_feat_change_recv.patch
+tipc-fix-use-after-free-of-kernel-socket-in-cleanup_.patch
+net-smc-limit-backlog-connections.patch
+net-smc-fix-lgr-and-link-use-after-free-issue.patch
+net-qed-allow-old-cards-not-supporting-num_images-to.patch
+igb-fix-potential-invalid-memory-access-in-igb_init_.patch
+net-sched-fix-erspan_opt-settings-in-cls_flower.patch
+netfilter-ipset-hold-module-reference-while-requesti.patch
+netfilter-nft_set_hash-skip-duplicated-elements-pend.patch
+ethtool-fix-wrong-mod-state-in-case-of-verbose-and-n.patch
+geneve-do-not-assume-mac-header-is-set-in-geneve_xmi.patch
+gpio-grgpio-use-a-helper-variable-to-store-the-addre.patch
+gpio-grgpio-add-null-check-in-grgpio_probe.patch
+dt_bindings-rs485-correct-delay-values.patch
+dt-bindings-serial-rs485-fix-rs485-rts-delay-propert.patch
+serial-amba-pl011-use-port-lock-wrappers.patch
+serial-amba-pl011-fix-rx-stall-when-dma-is-used.patch
--- /dev/null
+From 0efd40a3082aea84de4e529fb63ccfacc65c3b86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Nov 2024 14:05:12 +0900
+Subject: tipc: Fix use-after-free of kernel socket in cleanup_bearer().
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 6a2fa13312e51a621f652d522d7e2df7066330b6 ]
+
+syzkaller reported a use-after-free of UDP kernel socket
+in cleanup_bearer() without repro. [0][1]
+
+When bearer_disable() calls tipc_udp_disable(), cleanup
+of the UDP kernel socket is deferred by work calling
+cleanup_bearer().
+
+tipc_net_stop() waits for such works to finish by checking
+tipc_net(net)->wq_count. However, the work decrements the
+count too early before releasing the kernel socket,
+unblocking cleanup_net() and resulting in use-after-free.
+
+Let's move the decrement after releasing the socket in
+cleanup_bearer().
+
+[0]:
+ref_tracker: net notrefcnt@000000009b3d1faf has 1/1 users at
+ sk_alloc+0x438/0x608
+ inet_create+0x4c8/0xcb0
+ __sock_create+0x350/0x6b8
+ sock_create_kern+0x58/0x78
+ udp_sock_create4+0x68/0x398
+ udp_sock_create+0x88/0xc8
+ tipc_udp_enable+0x5e8/0x848
+ __tipc_nl_bearer_enable+0x84c/0xed8
+ tipc_nl_bearer_enable+0x38/0x60
+ genl_family_rcv_msg_doit+0x170/0x248
+ genl_rcv_msg+0x400/0x5b0
+ netlink_rcv_skb+0x1dc/0x398
+ genl_rcv+0x44/0x68
+ netlink_unicast+0x678/0x8b0
+ netlink_sendmsg+0x5e4/0x898
+ ____sys_sendmsg+0x500/0x830
+
+[1]:
+BUG: KMSAN: use-after-free in udp_hashslot include/net/udp.h:85 [inline]
+BUG: KMSAN: use-after-free in udp_lib_unhash+0x3b8/0x930 net/ipv4/udp.c:1979
+ udp_hashslot include/net/udp.h:85 [inline]
+ udp_lib_unhash+0x3b8/0x930 net/ipv4/udp.c:1979
+ sk_common_release+0xaf/0x3f0 net/core/sock.c:3820
+ inet_release+0x1e0/0x260 net/ipv4/af_inet.c:437
+ inet6_release+0x6f/0xd0 net/ipv6/af_inet6.c:489
+ __sock_release net/socket.c:658 [inline]
+ sock_release+0xa0/0x210 net/socket.c:686
+ cleanup_bearer+0x42d/0x4c0 net/tipc/udp_media.c:819
+ process_one_work kernel/workqueue.c:3229 [inline]
+ process_scheduled_works+0xcaf/0x1c90 kernel/workqueue.c:3310
+ worker_thread+0xf6c/0x1510 kernel/workqueue.c:3391
+ kthread+0x531/0x6b0 kernel/kthread.c:389
+ ret_from_fork+0x60/0x80 arch/x86/kernel/process.c:147
+ ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:244
+
+Uninit was created at:
+ slab_free_hook mm/slub.c:2269 [inline]
+ slab_free mm/slub.c:4580 [inline]
+ kmem_cache_free+0x207/0xc40 mm/slub.c:4682
+ net_free net/core/net_namespace.c:454 [inline]
+ cleanup_net+0x16f2/0x19d0 net/core/net_namespace.c:647
+ process_one_work kernel/workqueue.c:3229 [inline]
+ process_scheduled_works+0xcaf/0x1c90 kernel/workqueue.c:3310
+ worker_thread+0xf6c/0x1510 kernel/workqueue.c:3391
+ kthread+0x531/0x6b0 kernel/kthread.c:389
+ ret_from_fork+0x60/0x80 arch/x86/kernel/process.c:147
+ ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:244
+
+CPU: 0 UID: 0 PID: 54 Comm: kworker/0:2 Not tainted 6.12.0-rc1-00131-gf66ebf37d69c #7 91723d6f74857f70725e1583cba3cf4adc716cfa
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
+Workqueue: events cleanup_bearer
+
+Fixes: 26abe14379f8 ("net: Modify sk_alloc to not reference count the netns of kernel sockets.")
+Reported-by: syzkaller <syzkaller@googlegroups.com>
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20241127050512.28438-1-kuniyu@amazon.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/udp_media.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
+index 73e461dc12d7b..3f5a12b85b2d3 100644
+--- a/net/tipc/udp_media.c
++++ b/net/tipc/udp_media.c
+@@ -818,10 +818,10 @@ static void cleanup_bearer(struct work_struct *work)
+ kfree_rcu(rcast, rcu);
+ }
+
+- atomic_dec(&tipc_net(sock_net(ub->ubsock->sk))->wq_count);
+ dst_cache_destroy(&ub->rcast.dst_cache);
+ udp_tunnel_sock_release(ub->ubsock);
+ synchronize_net();
++ atomic_dec(&tipc_net(sock_net(ub->ubsock->sk))->wq_count);
+ kfree(ub);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 15b6923bcd2e79fc5049059d699807d172ac03f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Nov 2024 10:47:51 +0000
+Subject: watchdog: mediatek: Make sure system reset gets asserted in
+ mtk_wdt_restart()
+
+From: Yassine Oudjana <y.oudjana@protonmail.com>
+
+[ Upstream commit a1495a21e0b8aad92132dfcf9c6fffc1bde9d5b2 ]
+
+Clear the IRQ enable bit of WDT_MODE before asserting software reset
+in order to make TOPRGU issue a system reset signal instead of an IRQ.
+
+Fixes: a44a45536f7b ("watchdog: Add driver for Mediatek watchdog")
+Signed-off-by: Yassine Oudjana <y.oudjana@protonmail.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20241106104738.195968-2-y.oudjana@protonmail.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/mtk_wdt.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
+index 796fbb048cbea..a9d67ead94838 100644
+--- a/drivers/watchdog/mtk_wdt.c
++++ b/drivers/watchdog/mtk_wdt.c
+@@ -164,9 +164,15 @@ static int mtk_wdt_restart(struct watchdog_device *wdt_dev,
+ {
+ struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
+ void __iomem *wdt_base;
++ u32 reg;
+
+ wdt_base = mtk_wdt->wdt_base;
+
++ /* Enable reset in order to issue a system reset instead of an IRQ */
++ reg = readl(wdt_base + WDT_MODE);
++ reg &= ~WDT_MODE_IRQ_EN;
++ writel(reg | WDT_MODE_KEY, wdt_base + WDT_MODE);
++
+ while (1) {
+ writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST);
+ mdelay(5);
+--
+2.43.0
+