From: Sasha Levin Date: Mon, 9 Dec 2024 11:18:31 +0000 (-0500) Subject: Fixes for 5.15 X-Git-Tag: v6.6.65~47 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7a51c7051fe9b34ec6379b60e0cdc7699c501422;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.15 Signed-off-by: Sasha Levin --- diff --git a/queue-5.15/can-c_can-c_can_handle_bus_err-update-statistics-if-.patch b/queue-5.15/can-c_can-c_can_handle_bus_err-update-statistics-if-.patch new file mode 100644 index 00000000000..af4cca8c593 --- /dev/null +++ b/queue-5.15/can-c_can-c_can_handle_bus_err-update-statistics-if-.patch @@ -0,0 +1,96 @@ +From b326aa76d1d11c1df4365de1f1174262c5f655c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://patch.msgid.link/20241122221650.633981-2-dario.binacchi@amarulasolutions.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/can-do-not-increase-rx-statistics-when-generating-a-.patch b/queue-5.15/can-do-not-increase-rx-statistics-when-generating-a-.patch new file mode 100644 index 00000000000..24b0de75516 --- /dev/null +++ b/queue-5.15/can-do-not-increase-rx-statistics-when-generating-a-.patch @@ -0,0 +1,640 @@ +From d70d4ed68726d5f383bb35554b3c3e1fe919c7e0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +CC: Nicolas Ferre +CC: Alexandre Belloni +CC: Ludovic Desroches +CC: Chandrasekar Ramakrishnan +CC: Maxime Ripard +CC: Chen-Yu Tsai +CC: Jernej Skrabec +CC: Appana Durga Kedareswara rao +CC: Naga Sureshkumar Relli +CC: Michal Simek +CC: Stephane Grosjean +Tested-by: Jimmy Assarsson # kvaser +Signed-off-by: Vincent Mailhol +Acked-by: Stefan Mätje # esd_usb2 +Tested-by: Stefan Mätje # esd_usb2 +Signed-off-by: Marc Kleine-Budde +Stable-dep-of: 9e66242504f4 ("can: c_can: c_can_handle_bus_err(): update statistics if skb allocation fails") +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/can-ems_usb-ems_usb_rx_err-fix-rx-tx-_errors-statist.patch b/queue-5.15/can-ems_usb-ems_usb_rx_err-fix-rx-tx-_errors-statist.patch new file mode 100644 index 00000000000..1cfa2ba0fcc --- /dev/null +++ b/queue-5.15/can-ems_usb-ems_usb_rx_err-fix-rx-tx-_errors-statist.patch @@ -0,0 +1,126 @@ +From 072fc358c93d4fdc6b9f4a57ac0b33f3fd10d1de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://patch.msgid.link/20241122221650.633981-12-dario.binacchi@amarulasolutions.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/can-ifi_canfd-ifi_canfd_handle_lec_err-fix-rx-tx-_er.patch b/queue-5.15/can-ifi_canfd-ifi_canfd_handle_lec_err-fix-rx-tx-_er.patch new file mode 100644 index 00000000000..61cf9402577 --- /dev/null +++ b/queue-5.15/can-ifi_canfd-ifi_canfd_handle_lec_err-fix-rx-tx-_er.patch @@ -0,0 +1,118 @@ +From 50313bd214585aedf4dc1482aecbbb82568bc03c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Marek Vasut +Link: https://patch.msgid.link/20241122221650.633981-8-dario.binacchi@amarulasolutions.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/can-j1939-j1939_session_new-fix-skb-reference-counti.patch b/queue-5.15/can-j1939-j1939_session_new-fix-skb-reference-counti.patch new file mode 100644 index 00000000000..a169ba312e7 --- /dev/null +++ b/queue-5.15/can-j1939-j1939_session_new-fix-skb-reference-counti.patch @@ -0,0 +1,43 @@ +From 1fb91334f60f0c64f03e2d42e37071b9bd36cee0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Nov 2024 12:48:23 +0300 +Subject: can: j1939: j1939_session_new(): fix skb reference counting + +From: Dmitry Antipov + +[ 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 +Tested-by: Oleksij Rempel +Acked-by: Oleksij Rempel +Link: https://patch.msgid.link/20241105094823.2403806-1-dmantipov@yandex.ru +[mkl: clean up commit message] +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/can-m_can-m_can_handle_lec_err-fix-rx-tx-_errors-sta.patch b/queue-5.15/can-m_can-m_can_handle_lec_err-fix-rx-tx-_errors-sta.patch new file mode 100644 index 00000000000..187b460b442 --- /dev/null +++ b/queue-5.15/can-m_can-m_can_handle_lec_err-fix-rx-tx-_errors-sta.patch @@ -0,0 +1,103 @@ +From af29adb7b8dadbbacd901513c03de843bf0df353 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://patch.msgid.link/20241122221650.633981-7-dario.binacchi@amarulasolutions.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/can-peak_usb-canfd-store-64-bits-hw-timestamps.patch b/queue-5.15/can-peak_usb-canfd-store-64-bits-hw-timestamps.patch new file mode 100644 index 00000000000..eea777bf09e --- /dev/null +++ b/queue-5.15/can-peak_usb-canfd-store-64-bits-hw-timestamps.patch @@ -0,0 +1,101 @@ +From 5319ee693281fe06e32d551a282cced263cb7b0c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Marc Kleine-Budde +Stable-dep-of: 9e66242504f4 ("can: c_can: c_can_handle_bus_err(): update statistics if skb allocation fails") +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/can-sun4i_can-sun4i_can_err-call-can_change_state-ev.patch b/queue-5.15/can-sun4i_can-sun4i_can_err-call-can_change_state-ev.patch new file mode 100644 index 00000000000..46960a5338d --- /dev/null +++ b/queue-5.15/can-sun4i_can-sun4i_can_err-call-can_change_state-ev.patch @@ -0,0 +1,47 @@ +From ae52d5247de6204c18d6001dfb1fa2cfa768a2b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://patch.msgid.link/20241122221650.633981-3-dario.binacchi@amarulasolutions.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/can-sun4i_can-sun4i_can_err-fix-rx-tx-_errors-statis.patch b/queue-5.15/can-sun4i_can-sun4i_can_err-fix-rx-tx-_errors-statis.patch new file mode 100644 index 00000000000..86b8e04e1cf --- /dev/null +++ b/queue-5.15/can-sun4i_can-sun4i_can_err-fix-rx-tx-_errors-statis.patch @@ -0,0 +1,63 @@ +From 7251cb2179542e863d4fc4cc2b3d252a52693a33 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Nov 2024 23:15:51 +0100 +Subject: can: sun4i_can: sun4i_can_err(): fix {rx,tx}_errors statistics + +From: Dario Binacchi + +[ 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 +Link: https://patch.msgid.link/20241122221650.633981-11-dario.binacchi@amarulasolutions.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/dccp-fix-memory-leak-in-dccp_feat_change_recv.patch b/queue-5.15/dccp-fix-memory-leak-in-dccp_feat_change_recv.patch new file mode 100644 index 00000000000..b700c114c46 --- /dev/null +++ b/queue-5.15/dccp-fix-memory-leak-in-dccp_feat_change_recv.patch @@ -0,0 +1,78 @@ +From 8e11e1f62bd5d75fd66fc3544f42f04e104e2d48 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Nov 2024 17:39:02 +0300 +Subject: dccp: Fix memory leak in dccp_feat_change_recv + +From: Ivan Solodovnikov + +[ 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 +Link: https://patch.msgid.link/20241126143902.190853-1-solodovnikov.ia@phystech.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/dt-bindings-serial-rs485-fix-rs485-rts-delay-propert.patch b/queue-5.15/dt-bindings-serial-rs485-fix-rs485-rts-delay-propert.patch new file mode 100644 index 00000000000..46a9cc52d32 --- /dev/null +++ b/queue-5.15/dt-bindings-serial-rs485-fix-rs485-rts-delay-propert.patch @@ -0,0 +1,57 @@ +From ed4c0422993073e9c8e26b1fd0039a69316dcc8f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Sep 2024 11:53:06 +0200 +Subject: dt-bindings: serial: rs485: Fix rs485-rts-delay property + +From: Michal Simek + +[ 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 +Cc: stable@vger.kernel.org +Reviewed-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/820c639b9e22fe037730ed44d1b044cdb6d28b75.1726480384.git.michal.simek@amd.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + .../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 + $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 + diff --git a/queue-5.15/dt_bindings-rs485-correct-delay-values.patch b/queue-5.15/dt_bindings-rs485-correct-delay-values.patch new file mode 100644 index 00000000000..e4e1f2cd0f3 --- /dev/null +++ b/queue-5.15/dt_bindings-rs485-correct-delay-values.patch @@ -0,0 +1,54 @@ +From 4c0be6994b06ee57b549e60666bdd01949cccc3b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 10 Jul 2022 18:44:40 +0200 +Subject: dt_bindings: rs485: Correct delay values + +From: Lino Sanfilippo + +[ 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 +Signed-off-by: Lino Sanfilippo +Link: https://lore.kernel.org/r/20220710164442.2958979-7-LinoSanfilippo@gmx.de +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 12b3642b6c24 ("dt-bindings: serial: rs485: Fix rs485-rts-delay property") +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/ethtool-fix-wrong-mod-state-in-case-of-verbose-and-n.patch b/queue-5.15/ethtool-fix-wrong-mod-state-in-case-of-verbose-and-n.patch new file mode 100644 index 00000000000..a955b0446b1 --- /dev/null +++ b/queue-5.15/ethtool-fix-wrong-mod-state-in-case-of-verbose-and-n.patch @@ -0,0 +1,127 @@ +From 5eb8c9aca16fc84f93478568f9531bb2c3438cf1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://patch.msgid.link/20241202153358.1142095-1-kory.maincent@bootlin.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/geneve-do-not-assume-mac-header-is-set-in-geneve_xmi.patch b/queue-5.15/geneve-do-not-assume-mac-header-is-set-in-geneve_xmi.patch new file mode 100644 index 00000000000..465d08ae3bd --- /dev/null +++ b/queue-5.15/geneve-do-not-assume-mac-header-is-set-in-geneve_xmi.patch @@ -0,0 +1,85 @@ +From ce3650d63463ee160dd469cde19387969fe8fb4c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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: + + __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 +Reviewed-by: Stefano Brivio +Link: https://patch.msgid.link/20241203182122.2725517-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/gpio-grgpio-add-null-check-in-grgpio_probe.patch b/queue-5.15/gpio-grgpio-add-null-check-in-grgpio_probe.patch new file mode 100644 index 00000000000..badc9463c91 --- /dev/null +++ b/queue-5.15/gpio-grgpio-add-null-check-in-grgpio_probe.patch @@ -0,0 +1,41 @@ +From 1d125a4130e74e280caf63f46d2992bd60308925 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Nov 2024 17:18:22 +0800 +Subject: gpio: grgpio: Add NULL check in grgpio_probe + +From: Charles Han + +[ 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 +Link: https://lore.kernel.org/r/20241114091822.78199-1-hanchunchao@inspur.com +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/gpio-grgpio-use-a-helper-variable-to-store-the-addre.patch b/queue-5.15/gpio-grgpio-use-a-helper-variable-to-store-the-addre.patch new file mode 100644 index 00000000000..04d070795aa --- /dev/null +++ b/queue-5.15/gpio-grgpio-use-a-helper-variable-to-store-the-addre.patch @@ -0,0 +1,115 @@ +From cf43ad3f0f2d4c07e76d9a946eb572ba29cfe0fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Stable-dep-of: 050b23d081da ("gpio: grgpio: Add NULL check in grgpio_probe") +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/igb-fix-potential-invalid-memory-access-in-igb_init_.patch b/queue-5.15/igb-fix-potential-invalid-memory-access-in-igb_init_.patch new file mode 100644 index 00000000000..adeb1c33e0b --- /dev/null +++ b/queue-5.15/igb-fix-potential-invalid-memory-access-in-igb_init_.patch @@ -0,0 +1,40 @@ +From fdf81ea3fd1f68ce8dedaccfbb018e05f3fa64f3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Oct 2024 20:10:48 +0800 +Subject: igb: Fix potential invalid memory access in igb_init_module() + +From: Yuan Can + +[ 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 +Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/ipvs-fix-ub-due-to-uninitialized-stack-access-in-ip_.patch b/queue-5.15/ipvs-fix-ub-due-to-uninitialized-stack-access-in-ip_.patch new file mode 100644 index 00000000000..85a2aaefead --- /dev/null +++ b/queue-5.15/ipvs-fix-ub-due-to-uninitialized-stack-access-in-ip_.patch @@ -0,0 +1,117 @@ +From dd4d91b9fbaae7a9fc29c0e400beaed538653f47 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Closes: https://lore.kernel.org/oe-kbuild-all/202402100205.PWXIz1ZK-lkp@intel.com/ +Co-developed-by: Ruowen Qin +Signed-off-by: Ruowen Qin +Signed-off-by: Jinghao Jia +Acked-by: Julian Anastasov +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/itco_wdt-mask-nmi_now-bit-for-update_no_reboot_bit-c.patch b/queue-5.15/itco_wdt-mask-nmi_now-bit-for-update_no_reboot_bit-c.patch new file mode 100644 index 00000000000..f6cdaa7eb6b --- /dev/null +++ b/queue-5.15/itco_wdt-mask-nmi_now-bit-for-update_no_reboot_bit-c.patch @@ -0,0 +1,85 @@ +From 635b605b4d7740b1e7d322b7959f9acbbae3ab0a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Guenter Roeck +Reviewed-by: Mika Westerberg +Link: https://lore.kernel.org/r/20240913191403.2560805-1-oocheret@cisco.com +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/net-hsr-avoid-potential-out-of-bound-access-in-fill_.patch b/queue-5.15/net-hsr-avoid-potential-out-of-bound-access-in-fill_.patch new file mode 100644 index 00000000000..5b45329d1f5 --- /dev/null +++ b/queue-5.15/net-hsr-avoid-potential-out-of-bound-access-in-fill_.patch @@ -0,0 +1,95 @@ +From 016f2084acb741b7d5cbb424641da63d80b16f0b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Cc: WingMan Kwok +Cc: Murali Karicheri +Cc: MD Danish Anwar +Cc: Jiri Pirko +Cc: George McCollister +Link: https://patch.msgid.link/20241126144344.4177332-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/net-ipv6-release-expired-exception-dst-cached-in-soc.patch b/queue-5.15/net-ipv6-release-expired-exception-dst-cached-in-soc.patch new file mode 100644 index 00000000000..1cb927866cc --- /dev/null +++ b/queue-5.15/net-ipv6-release-expired-exception-dst-cached-in-soc.patch @@ -0,0 +1,85 @@ +From 4cb9e76a35556cb99d4956f365ada92126e78ef4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Nov 2024 09:59:50 +0100 +Subject: net/ipv6: release expired exception dst cached in socket + +From: Jiri Wiesner + +[ 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 +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20241128085950.GA4505@incl +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/net-qed-allow-old-cards-not-supporting-num_images-to.patch b/queue-5.15/net-qed-allow-old-cards-not-supporting-num_images-to.patch new file mode 100644 index 00000000000..9ee0fe82a0f --- /dev/null +++ b/queue-5.15/net-qed-allow-old-cards-not-supporting-num_images-to.patch @@ -0,0 +1,48 @@ +From 3426d4f2de2d47fdd8264b8b539339e1419fe429 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Nov 2024 09:33:58 +0100 +Subject: net/qed: allow old cards not supporting "num_images" to work + +From: Louis Leseur + +[ 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 +Signed-off-by: Florian Forestier +Signed-off-by: Louis Leseur +Link: https://patch.msgid.link/20241128083633.26431-1-louis.leseur@gmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/net-sched-fix-erspan_opt-settings-in-cls_flower.patch b/queue-5.15/net-sched-fix-erspan_opt-settings-in-cls_flower.patch new file mode 100644 index 00000000000..992f3564718 --- /dev/null +++ b/queue-5.15/net-sched-fix-erspan_opt-settings-in-cls_flower.patch @@ -0,0 +1,68 @@ +From a63291b5c03d302a554289bcbb74712f71de85fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Dec 2024 10:21:38 -0500 +Subject: net: sched: fix erspan_opt settings in cls_flower + +From: Xin Long + +[ 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 +Signed-off-by: Xin Long +Reviewed-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/net-sched-tbf-correct-backlog-statistic-for-gso-pack.patch b/queue-5.15/net-sched-tbf-correct-backlog-statistic-for-gso-pack.patch new file mode 100644 index 00000000000..5d0986b83f2 --- /dev/null +++ b/queue-5.15/net-sched-tbf-correct-backlog-statistic-for-gso-pack.patch @@ -0,0 +1,90 @@ +From c017e9f8507e77817e179b082ec7f66cfecaaf9f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Nov 2024 18:46:07 +0100 +Subject: net/sched: tbf: correct backlog statistic for GSO packets + +From: Martin Ottens + +[ 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 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 + +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 +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20241125174608.1484356-1-martin.ottens@fau.de +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/net-smc-fix-lgr-and-link-use-after-free-issue.patch b/queue-5.15/net-smc-fix-lgr-and-link-use-after-free-issue.patch new file mode 100644 index 00000000000..0fecbf85c53 --- /dev/null +++ b/queue-5.15/net-smc-fix-lgr-and-link-use-after-free-issue.patch @@ -0,0 +1,92 @@ +From c2f5d6d5fa9488a1bc15c7715ca87d0751f693ab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Nov 2024 21:30:14 +0800 +Subject: net/smc: fix LGR and link use-after-free issue + +From: Wen Gu + +[ 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 +Signed-off-by: Guangguan Wang +Co-developed-by: Kai +Signed-off-by: Kai +Signed-off-by: Wen Gu +Reviewed-by: Wenjia Zhang +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/net-smc-limit-backlog-connections.patch b/queue-5.15/net-smc-limit-backlog-connections.patch new file mode 100644 index 00000000000..85b86294622 --- /dev/null +++ b/queue-5.15/net-smc-limit-backlog-connections.patch @@ -0,0 +1,162 @@ +From baed6108d25c33ddbc43ad7b36b7a743d5bb61fb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 10 Feb 2022 17:11:35 +0800 +Subject: net/smc: Limit backlog connections + +From: D. Wythe + +[ 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 +Signed-off-by: David S. Miller +Stable-dep-of: 2c7f14ed9c19 ("net/smc: fix LGR and link use-after-free issue") +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/netfilter-ipset-hold-module-reference-while-requesti.patch b/queue-5.15/netfilter-ipset-hold-module-reference-while-requesti.patch new file mode 100644 index 00000000000..88361c53c06 --- /dev/null +++ b/queue-5.15/netfilter-ipset-hold-module-reference-while-requesti.patch @@ -0,0 +1,49 @@ +From f38cbbc568896cd7ba7fd3e438e0b678b91e46f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Nov 2024 16:30:38 +0100 +Subject: netfilter: ipset: Hold module reference while requesting a module + +From: Phil Sutter + +[ 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 +Acked-by: Jozsef Kadlecsik +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/netfilter-nft_set_hash-skip-duplicated-elements-pend.patch b/queue-5.15/netfilter-nft_set_hash-skip-duplicated-elements-pend.patch new file mode 100644 index 00000000000..80ddffc590f --- /dev/null +++ b/queue-5.15/netfilter-nft_set_hash-skip-duplicated-elements-pend.patch @@ -0,0 +1,97 @@ +From bc68880146f0e721d84010bb438233d55b5aaad1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Dec 2024 00:04:49 +0100 +Subject: netfilter: nft_set_hash: skip duplicated elements pending gc run + +From: Pablo Neira Ayuso + +[ 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 +Tested-by: Laurent Fasnacht +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/netfilter-x_tables-fix-led-id-check-in-led_tg_check.patch b/queue-5.15/netfilter-x_tables-fix-led-id-check-in-led_tg_check.patch new file mode 100644 index 00000000000..15a1b9bf7ae --- /dev/null +++ b/queue-5.15/netfilter-x_tables-fix-led-id-check-in-led_tg_check.patch @@ -0,0 +1,109 @@ +From 3584065cf9b9c5aa9e7bc8f0109d5bbfbbf2f667 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Nov 2024 09:55:42 +0300 +Subject: netfilter: x_tables: fix LED ID check in led_tg_check() + +From: Dmitry Antipov + +[ 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: + + 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 +... + + +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 +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/ptp-add-error-handling-for-adjfine-callback-in-ptp_c.patch b/queue-5.15/ptp-add-error-handling-for-adjfine-callback-in-ptp_c.patch new file mode 100644 index 00000000000..220174b1668 --- /dev/null +++ b/queue-5.15/ptp-add-error-handling-for-adjfine-callback-in-ptp_c.patch @@ -0,0 +1,42 @@ +From 980a99dd285b52ce1faabc17596a850fe829e011 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Nov 2024 10:59:54 +0000 +Subject: ptp: Add error handling for adjfine callback in ptp_clock_adjtime + +From: Ajay Kaher + +[ 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 +Acked-by: Richard Cochran +Link: https://patch.msgid.link/20241125105954.1509971-1-ajay.kaher@broadcom.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/serial-amba-pl011-fix-rx-stall-when-dma-is-used.patch b/queue-5.15/serial-amba-pl011-fix-rx-stall-when-dma-is-used.patch new file mode 100644 index 00000000000..59cd7824d3f --- /dev/null +++ b/queue-5.15/serial-amba-pl011-fix-rx-stall-when-dma-is-used.patch @@ -0,0 +1,49 @@ +From c080688daab7ea65b1f7914ee83648305a130cd9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Nov 2024 14:56:29 +0530 +Subject: serial: amba-pl011: Fix RX stall when DMA is used + +From: Kartik Rajput + +[ 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 +Reviewed-by: Linus Walleij +Link: https://lore.kernel.org/r/20241113092629.60226-1-kkartik@nvidia.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/serial-amba-pl011-use-port-lock-wrappers.patch b/queue-5.15/serial-amba-pl011-use-port-lock-wrappers.patch new file mode 100644 index 00000000000..304ebb2cfce --- /dev/null +++ b/queue-5.15/serial-amba-pl011-use-port-lock-wrappers.patch @@ -0,0 +1,338 @@ +From de8b11d5e089eca946f187e136df1b4a6019c8ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 20:43:34 +0206 +Subject: serial: amba-pl011: Use port lock wrappers + +From: Thomas Gleixner + +[ 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 +Signed-off-by: John Ogness +Link: https://lore.kernel.org/r/20230914183831.587273-18-john.ogness@linutronix.de +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 2bcacc1c87ac ("serial: amba-pl011: Fix RX stall when DMA is used") +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/series b/queue-5.15/series index 82aa7623b25..b28d5ddec0b 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -397,3 +397,37 @@ drm-sti-avoid-potential-dereference-of-error-pointers-in-sti_hqvdp_atomic_check. 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 diff --git a/queue-5.15/tipc-fix-use-after-free-of-kernel-socket-in-cleanup_.patch b/queue-5.15/tipc-fix-use-after-free-of-kernel-socket-in-cleanup_.patch new file mode 100644 index 00000000000..d44de7f198e --- /dev/null +++ b/queue-5.15/tipc-fix-use-after-free-of-kernel-socket-in-cleanup_.patch @@ -0,0 +1,107 @@ +From 0efd40a3082aea84de4e529fb63ccfacc65c3b86 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Nov 2024 14:05:12 +0900 +Subject: tipc: Fix use-after-free of kernel socket in cleanup_bearer(). + +From: Kuniyuki Iwashima + +[ 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 +Signed-off-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20241127050512.28438-1-kuniyu@amazon.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/watchdog-mediatek-make-sure-system-reset-gets-assert.patch b/queue-5.15/watchdog-mediatek-make-sure-system-reset-gets-assert.patch new file mode 100644 index 00000000000..d63c995c038 --- /dev/null +++ b/queue-5.15/watchdog-mediatek-make-sure-system-reset-gets-assert.patch @@ -0,0 +1,48 @@ +From 15b6923bcd2e79fc5049059d699807d172ac03f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/20241106104738.195968-2-y.oudjana@protonmail.com +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + 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 +