* [PATCH v3] net: phy: air_en8811h: add AN8811HB MCU assert/deassert support
From: Lucien.Jheng @ 2026-04-20 13:45 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
linux-kernel, bjorn
Cc: ericwouds, frank-w, daniel, lucien.jheng, albert-al.lee,
Lucien.Jheng
AN8811HB needs a MCU soft-reset cycle before firmware loading begins.
Assert the MCU (hold it in reset) and immediately deassert (release)
via a dedicated PBUS register pair (0x5cf9f8 / 0x5cf9fc), accessed
through a registered mdio_device at PHY-addr+8.
Add __air_pbus_reg_write() as a low-level helper taking a struct
mdio_device *, create and register the PBUS mdio_device in
an8811hb_probe() and store it in priv->pbusdev, then implement
an8811hb_mcu_assert() / _deassert() on top of it. Add
an8811hb_remove() to unregister the PBUS device on teardown. Wire
both calls into an8811hb_load_firmware() and en8811h_restart_mcu()
so every firmware load or MCU restart on AN8811HB correctly sequences
the reset control registers.
Fixes: 0a55766b7711 ("net: phy: air_en8811h: add Airoha AN8811HB support")
Signed-off-by: Lucien Jheng <lucienzx159@gmail.com>
---
Changes in v3:
- Register a dedicated mdio_device for the PBUS node (addr+8) in
an8811hb_probe() and store it in priv->pbusdev, replacing the
inline addr+8 computation in v2.
- Change __air_pbus_reg_write() to take struct mdio_device * instead
of struct phy_device *.
- Add an8811hb_remove() to unregister and free the PBUS device.
- Fix error handling in an8811hb_probe() with goto error paths to
ensure the PBUS device is always cleaned up on failure.
drivers/net/phy/air_en8811h.c | 142 +++++++++++++++++++++++++++++++++-
1 file changed, 138 insertions(+), 4 deletions(-)
diff --git a/drivers/net/phy/air_en8811h.c b/drivers/net/phy/air_en8811h.c
index 29ae73e65..1fe2d8bec 100644
--- a/drivers/net/phy/air_en8811h.c
+++ b/drivers/net/phy/air_en8811h.c
@@ -170,9 +170,21 @@
#define AN8811HB_CLK_DRV_CKO_LDPWD BIT(13)
#define AN8811HB_CLK_DRV_CKO_LPPWD BIT(14)
+#define AN8811HB_MCU_SW_RST 0x5cf9f8
+#define AN8811HB_MCU_SW_RST_HOLD BIT(16)
+#define AN8811HB_MCU_SW_RST_RUN (BIT(16) | BIT(0))
+#define AN8811HB_MCU_SW_START 0x5cf9fc
+#define AN8811HB_MCU_SW_START_EN BIT(16)
+
+/* MII register constants for PBUS access (PHY addr + 8) */
+#define AIR_PBUS_ADDR_HIGH 0x1c
+#define AIR_PBUS_DATA_HIGH 0x10
+
/* Led definitions */
#define EN8811H_LED_COUNT 3
+#define EN8811H_PBUS_ADDR_OFFS 8
+
/* Default LED setup:
* GPIO5 <-> LED0 On: Link detected, blink Rx/Tx
* GPIO4 <-> LED1 On: Link detected at 2500 or 1000 Mbps
@@ -201,6 +213,7 @@ struct en8811h_priv {
struct clk_hw hw;
struct phy_device *phydev;
unsigned int cko_is_enabled;
+ struct mdio_device *pbusdev;
};
enum {
@@ -254,6 +267,31 @@ static int air_phy_write_page(struct phy_device *phydev, int page)
return __phy_write(phydev, AIR_EXT_PAGE_ACCESS, page);
}
+static int __air_pbus_reg_write(struct mdio_device *mdiodev,
+ u32 pbus_reg, u32 pbus_data)
+{
+ int ret;
+
+ ret = __mdiobus_write(mdiodev->bus, mdiodev->addr, AIR_EXT_PAGE_ACCESS,
+ upper_16_bits(pbus_reg));
+ if (ret < 0)
+ return ret;
+
+ ret = __mdiobus_write(mdiodev->bus, mdiodev->addr, AIR_PBUS_ADDR_HIGH,
+ (pbus_reg & GENMASK(15, 6)) >> 6);
+ if (ret < 0)
+ return ret;
+
+ ret = __mdiobus_write(mdiodev->bus, mdiodev->addr,
+ (pbus_reg & GENMASK(5, 2)) >> 2,
+ lower_16_bits(pbus_data));
+ if (ret < 0)
+ return ret;
+
+ return __mdiobus_write(mdiodev->bus, mdiodev->addr, AIR_PBUS_DATA_HIGH,
+ upper_16_bits(pbus_data));
+}
+
static int __air_buckpbus_reg_write(struct phy_device *phydev,
u32 pbus_address, u32 pbus_data)
{
@@ -570,10 +608,67 @@ static int an8811hb_load_file(struct phy_device *phydev, const char *name,
return ret;
}
+static int an8811hb_mcu_assert(struct phy_device *phydev)
+{
+ struct en8811h_priv *priv = phydev->priv;
+ int ret;
+
+ phy_lock_mdio_bus(phydev);
+
+ ret = __air_pbus_reg_write(priv->pbusdev, AN8811HB_MCU_SW_RST,
+ AN8811HB_MCU_SW_RST_HOLD);
+ if (ret < 0)
+ goto unlock;
+
+ ret = __air_pbus_reg_write(priv->pbusdev, AN8811HB_MCU_SW_START, 0);
+ if (ret < 0)
+ goto unlock;
+
+ msleep(50);
+ phydev_dbg(phydev, "MCU asserted\n");
+
+unlock:
+ phy_unlock_mdio_bus(phydev);
+ return ret;
+}
+
+static int an8811hb_mcu_deassert(struct phy_device *phydev)
+{
+ struct en8811h_priv *priv = phydev->priv;
+ int ret;
+
+ phy_lock_mdio_bus(phydev);
+
+ ret = __air_pbus_reg_write(priv->pbusdev, AN8811HB_MCU_SW_START,
+ AN8811HB_MCU_SW_START_EN);
+ if (ret < 0)
+ goto unlock;
+
+ ret = __air_pbus_reg_write(priv->pbusdev, AN8811HB_MCU_SW_RST,
+ AN8811HB_MCU_SW_RST_RUN);
+ if (ret < 0)
+ goto unlock;
+
+ msleep(50);
+ phydev_dbg(phydev, "MCU deasserted\n");
+
+unlock:
+ phy_unlock_mdio_bus(phydev);
+ return ret;
+}
+
static int an8811hb_load_firmware(struct phy_device *phydev)
{
int ret;
+ ret = an8811hb_mcu_assert(phydev);
+ if (ret < 0)
+ return ret;
+
+ ret = an8811hb_mcu_deassert(phydev);
+ if (ret < 0)
+ return ret;
+
ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
EN8811H_FW_CTRL_1_START);
if (ret < 0)
@@ -662,6 +757,16 @@ static int en8811h_restart_mcu(struct phy_device *phydev)
{
int ret;
+ if (phy_id_compare_model(phydev->phy_id, AN8811HB_PHY_ID)) {
+ ret = an8811hb_mcu_assert(phydev);
+ if (ret < 0)
+ return ret;
+
+ ret = an8811hb_mcu_deassert(phydev);
+ if (ret < 0)
+ return ret;
+ }
+
ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
EN8811H_FW_CTRL_1_START);
if (ret < 0)
@@ -1166,6 +1271,7 @@ static int en8811h_leds_setup(struct phy_device *phydev)
static int an8811hb_probe(struct phy_device *phydev)
{
+ struct mdio_device *mdiodev;
struct en8811h_priv *priv;
int ret;
@@ -1175,10 +1281,22 @@ static int an8811hb_probe(struct phy_device *phydev)
return -ENOMEM;
phydev->priv = priv;
+ mdiodev = mdio_device_create(phydev->mdio.bus,
+ phydev->mdio.addr + EN8811H_PBUS_ADDR_OFFS);
+ if (IS_ERR(mdiodev))
+ return PTR_ERR(mdiodev);
+
+ ret = mdio_device_register(mdiodev);
+ if (ret) {
+ mdio_device_free(mdiodev);
+ return ret;
+ }
+ priv->pbusdev = mdiodev;
+
ret = an8811hb_load_firmware(phydev);
if (ret < 0) {
phydev_err(phydev, "Load firmware failed: %d\n", ret);
- return ret;
+ goto error;
}
en8811h_print_fw_version(phydev);
@@ -1191,22 +1309,27 @@ static int an8811hb_probe(struct phy_device *phydev)
ret = en8811h_leds_setup(phydev);
if (ret < 0)
- return ret;
+ goto error;
priv->phydev = phydev;
/* Co-Clock Output */
ret = an8811hb_clk_provider_setup(&phydev->mdio.dev, &priv->hw);
if (ret)
- return ret;
+ goto error;
/* Configure led gpio pins as output */
ret = air_buckpbus_reg_modify(phydev, AN8811HB_GPIO_OUTPUT,
AN8811HB_GPIO_OUTPUT_345,
AN8811HB_GPIO_OUTPUT_345);
if (ret < 0)
- return ret;
+ goto error;
return 0;
+
+error:
+ mdio_device_remove(priv->pbusdev);
+ mdio_device_free(priv->pbusdev);
+ return ret;
}
static int en8811h_probe(struct phy_device *phydev)
@@ -1561,6 +1684,16 @@ static int en8811h_suspend(struct phy_device *phydev)
return genphy_suspend(phydev);
}
+static void an8811hb_remove(struct phy_device *phydev)
+{
+ struct en8811h_priv *priv = phydev->priv;
+
+ if (priv->pbusdev) {
+ mdio_device_remove(priv->pbusdev);
+ mdio_device_free(priv->pbusdev);
+ }
+}
+
static struct phy_driver en8811h_driver[] = {
{
PHY_ID_MATCH_MODEL(EN8811H_PHY_ID),
@@ -1587,6 +1720,7 @@ static struct phy_driver en8811h_driver[] = {
PHY_ID_MATCH_MODEL(AN8811HB_PHY_ID),
.name = "Airoha AN8811HB",
.probe = an8811hb_probe,
+ .remove = an8811hb_remove,
.get_features = en8811h_get_features,
.config_init = an8811hb_config_init,
.get_rate_matching = en8811h_get_rate_matching,
--
2.34.1
^ permalink raw reply related
* Re: Question/proposal for DPLL NCO (DCO) mode
From: Jiri Pirko @ 2026-04-20 13:43 UTC (permalink / raw)
To: Ivan Vecera
Cc: netdev@vger.kernel.org, Arkadiusz Kubalewski, Vadim Fedorenko,
Jakub Kicinski
In-Reply-To: <21cce17b-9a79-41b5-8363-faee2378aa37@redhat.com>
Mon, Apr 20, 2026 at 01:42:29PM +0200, ivecera@redhat.com wrote:
>Hi all,
>
>I am currently working on adding PTP clock support (PHC) to the ZL3073x
>driver, and I would like to discuss an architectural addition to the
>DPLL subsystem enum dpll_mode before sending the formal patch series.
>
>To support IEEE 1588 PTP, the hardware DPLL must be decoupled from
>tracking physical reference pins. Instead, its output frequency needs to
>be continuously steered by a software PTP stack (e.g., linuxptp) using
>the .adjfine() callback. In the industry, this specific hardware state
>is widely known as NCO (Numerically Controlled Oscillator) or DCO
>(Digitally Controlled Oscillator) mode.
>
>Currently, the DPLL subsystem defines two modes in enum dpll_mode:
>
>MANUAL: The user explicitly selects a physical input pin to track.
>
>AUTOMATIC: The hardware automatically selects the best physical input pin
>based on priorities.
>
>Neither of these accurately represents the NCO/DCO state, where physical
>pins are ignored, and the loop is fully software-steered.
The manual/automatic mode is defining strategy/behaviour about how the
input pins are selected.
<header_quote>
* enum dpll_mode - working modes a dpll can support, differentiates if and how
* dpll selects one of its inputs to syntonize with it
</header_quote>
You don't want to change the strategy. You just
don't want that/don't care. Why it make sense to add a mode then?
I was thinking exposing this over STATUS. We have:
UNLOCKED (free running)
LOCKED
LOCKED_HO_ACQ
HOLDOVER
So something maybe like SW_STEERED? But:
The problem is you need to do selection. Perhaps we can have a
"magic pin" to select for this :S ? We have pin of type
DPLL_PIN_TYPE_INT_OSCILLATOR already. Perhaps we can have
DPLL_PIN_TYPE_INT_NCO/NDO? It's a source.
Makes sense?
>
>Without a dedicated mode, drivers are forced into "automagic"
>workarounds. A driver might implicitly switch the hardware to NCO mode
>in the background as soon as .adjfine() is called, while misreporting
>its mode as MANUAL to the DPLL subsystem.
>
>I strongly believe this hidden "automagic" behavior is a bad design. The
>user-space should have full visibility and explicit control over what
>the DPLL state machine is actually doing.
>
>The Proposal:
>I would like to propose adding a new mode: DPLL_MODE_NCO (or
>DPLL_MODE_DCO, I am open to suggestions regarding the terminology).
>
>The expected workflow would be explicit:
>If a user wants to actively steer the DPLL frequency via software (for
>PTP or other Time-over-Packet applications), they must explicitly set
>the DPLL device to this mode via Netlink first. Only then will the
>hardware accept frequency adjustments via .adjfine().
>
>I would appreciate any feedback from the DPLL subsystem maintainers and
>the community on this approach.
>
>Thanks,
>Ivan
>
^ permalink raw reply
* [PATCH RFC nf-next] netfilter: flowtable_offload: propagate CT mark to hardware offload path
From: Lorenzo Bianconi @ 2026-04-20 13:39 UTC (permalink / raw)
To: Pablo Neira Ayuso, Florian Westphal, Phil Sutter, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman
Cc: netfilter-devel, coreteam, netdev, Lorenzo Bianconi
When a user-space process sets the Connection Tracking (CT) mark on a
flow via nft_ct or xt_CONNMARK, that mark should be visible to the
hardware offload path when the flow is accelerated through the flowtable
infrastructure.
Extend the flowtable offload attribute set to include the ct mark field
when it has been explicitly set on the conntrack entry.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
net/netfilter/nf_flow_table_offload.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
index 002ec15d988b..d5fe35b1a647 100644
--- a/net/netfilter/nf_flow_table_offload.c
+++ b/net/netfilter/nf_flow_table_offload.c
@@ -679,6 +679,22 @@ static int flow_offload_decap_tunnel(const struct flow_offload *flow,
return 0;
}
+static void nf_flow_rule_ct_meta_mark(const struct flow_offload *flow,
+ struct nf_flow_rule *flow_rule)
+{
+#if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
+ u32 mark = flow->ct ? READ_ONCE(flow->ct->mark) : 0;
+
+ if (mark) {
+ struct flow_action_entry *entry;
+
+ entry = flow_action_entry_next(flow_rule);
+ entry->id = FLOW_ACTION_CT_METADATA;
+ entry->ct_metadata.mark = mark;
+ }
+#endif /* IS_ENABLED(CONFIG_NF_CONNTRACK_MARK) */
+}
+
static int
nf_flow_rule_route_common(struct net *net, const struct flow_offload *flow,
enum flow_offload_tuple_dir dir,
@@ -747,6 +763,8 @@ int nf_flow_rule_route_ipv4(struct net *net, struct flow_offload *flow,
if (nf_flow_rule_route_common(net, flow, dir, flow_rule) < 0)
return -1;
+ nf_flow_rule_ct_meta_mark(flow, flow_rule);
+
if (test_bit(NF_FLOW_SNAT, &flow->flags)) {
if (flow_offload_ipv4_snat(net, flow, dir, flow_rule) < 0 ||
flow_offload_port_snat(net, flow, dir, flow_rule) < 0)
@@ -776,6 +794,8 @@ int nf_flow_rule_route_ipv6(struct net *net, struct flow_offload *flow,
if (nf_flow_rule_route_common(net, flow, dir, flow_rule) < 0)
return -1;
+ nf_flow_rule_ct_meta_mark(flow, flow_rule);
+
if (test_bit(NF_FLOW_SNAT, &flow->flags)) {
if (flow_offload_ipv6_snat(net, flow, dir, flow_rule) < 0 ||
flow_offload_port_snat(net, flow, dir, flow_rule) < 0)
---
base-commit: 3f3a2aefbc661b837c8e344f944982d61c2ae037
change-id: 20260420-nft-flowtable-priority-6eef902d255a
Best regards,
--
Lorenzo Bianconi <lorenzo@kernel.org>
^ permalink raw reply related
* Re: [net-next v2 3/5] dt-bindings: net: starfive,jh7110-dwmac: Add JHB100 sgmii rx clk
From: Rob Herring @ 2026-04-20 13:39 UTC (permalink / raw)
To: Minda Chen
Cc: Alexandre Torgue, Andrew Lunn, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Maxime Coquelin,
Emil Renner Berthing, Krzysztof Kozlowski, Conor Dooley, netdev,
linux-kernel, linux-stm32, devicetree
In-Reply-To: <20260417024523.107786-4-minda.chen@starfivetech.com>
On Fri, Apr 17, 2026 at 10:45:21AM +0800, Minda Chen wrote:
> JHB100 SGMII interface tx/rx mac clock is split and require to
> set clock rate in 10M/100M/1000M speed. So dts need to add a
> new rx clock in code, dts and dt binding doc.
>
> Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
> ---
> .../bindings/net/starfive,jh7110-dwmac.yaml | 42 ++++++++++++++++---
> 1 file changed, 36 insertions(+), 6 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml b/Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
> index edc246a71ce3..3802cdbf1848 100644
> --- a/Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
> +++ b/Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
> @@ -39,20 +39,26 @@ properties:
> maxItems: 1
>
> clocks:
> + minItems: 5
> items:
> - description: GMAC main clock
> - description: GMAC AHB clock
> - description: PTP clock
> - description: TX clock
> - description: GTX clock
> + - description: SGMII RX clock
>
> clock-names:
> - items:
> - - const: stmmaceth
> - - const: pclk
> - - const: ptp_ref
> - - const: tx
> - - const: gtx
> + minItems: 5
> + maxItems: 6
> + contains:
> + enum:
> + - stmmaceth
> + - pclk
> + - ptp_ref
> + - tx
> + - gtx
> + - sgmii_rx
No, this allows any of the above strings plus any other random strings.
Rob
^ permalink raw reply
* Re: [PATCH v5] net: caif: fix stack out-of-bounds write in cfctrl_link_setup()
From: Kangzheng Gu @ 2026-04-20 13:38 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Simon Horman, Paolo Abeni, David S . Miller, Eric Dumazet,
Jakub Kicinski, Kees Cook, Thorsten Blum, sjur.brandeland, Netdev,
linux-kernel, stable
In-Reply-To: <85ec14af-bdd5-45ea-8c06-ebd769499bd1@app.fastmail.com>
Ok, I would like to wait. I am just researching for security.
Arnd Bergmann <arnd@arndb.de> 于2026年4月20日周一 16:14写道:
>
> On Mon, Apr 20, 2026, at 10:09, Kangzheng Gu wrote:
> > Thanks for all of your advice, I am preparing a new version of patch now.
>
> If you are actively using CAIF, please chime in at
>
> https://lore.kernel.org/all/20260416182829.1440262-1-kuba@kernel.org/
>
> If you are not actually using CAIF, maybe wait a little bit before
> spending more time on it because the patches may no longer
> apply if it gets removed due to lack of users.
>
> Arnd
^ permalink raw reply
* Re: [PATCH] docs: maintainer-netdev: fix typo in "targeting"
From: Breno Leitao @ 2026-04-20 13:35 UTC (permalink / raw)
To: Ariful Islam Shoikot; +Cc: netdev, linux-doc, workflows, linux-kernel
In-Reply-To: <20260420114554.1026-1-islamarifulshoikat@gmail.com>
On Mon, Apr 20, 2026 at 05:45:53PM +0600, Ariful Islam Shoikot wrote:
> Fix spelling mistake "targgeting" -> "targeting" in
> maintainer-netdev.rst
>
> No functional change.
>
> Signed-off-by: Ariful Islam Shoikot <islamarifulshoikat@gmail.com>
Reviewed-by: Breno Leitao <leitao@debian.org>
^ permalink raw reply
* Re: [PATCH AUTOSEL 7.0] dsa: tag_mxl862xx: set dsa_default_offload_fwd_mark()
From: Daniel Golle @ 2026-04-20 13:34 UTC (permalink / raw)
To: Sasha Levin
Cc: patches, stable, Jakub Kicinski, andrew, olteanv, davem, edumazet,
pabeni, netdev, linux-kernel
In-Reply-To: <20260420132314.1023554-153-sashal@kernel.org>
On Mon, Apr 20, 2026 at 09:19:07AM -0400, Sasha Levin wrote:
> From: Daniel Golle <daniel@makrotopia.org>
>
> [ Upstream commit 4250ff1640ea1ede99bfe02ca949acbcc6c0927f ]
>
> The MxL862xx offloads bridge forwarding in hardware, so set
> dsa_default_offload_fwd_mark() to avoid duplicate forwarding of
> packets of (eg. flooded) frames arriving at the CPU port.
>
> Link-local frames are directly trapped to the CPU port only, so don't
> set dsa_default_offload_fwd_mark() on those.
>
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> Link: https://patch.msgid.link/e1161c90894ddc519c57dc0224b3a0f6bfa1d2d6.1775049897.git.daniel@makrotopia.org
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---
>
> LLM Generated explanations, may be completely bogus:
>
> Now I have all the information needed for a complete analysis.
This commit should NOT be backported, it only makes sense with bridge
offloading implemented, which only happened with commit 340bdf984613c
("net: dsa: mxl862xx: implement bridge offloading").
^ permalink raw reply
* [PATCH AUTOSEL 6.18] net: airoha: Fix memory leak in airoha_qdma_rx_process()
From: Sasha Levin @ 2026-04-20 13:22 UTC (permalink / raw)
To: patches, stable
Cc: Lorenzo Bianconi, Simon Horman, Jakub Kicinski, Sasha Levin,
andrew+netdev, davem, edumazet, pabeni, linux-arm-kernel,
linux-mediatek, netdev, linux-kernel
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>
From: Lorenzo Bianconi <lorenzo@kernel.org>
[ Upstream commit 285fa6b1e03cff78ead0383e1b259c44b95faf90 ]
If an error occurs on the subsequents buffers belonging to the
non-linear part of the skb (e.g. due to an error in the payload length
reported by the NIC or if we consumed all the available fragments for
the skb), the page_pool fragment will not be linked to the skb so it will
not return to the pool in the airoha_qdma_rx_process() error path. Fix the
memory leak partially reverting commit 'd6d2b0e1538d ("net: airoha: Fix
page recycling in airoha_qdma_rx_process()")' and always running
page_pool_put_full_page routine in the airoha_qdma_rx_process() error
path.
Fixes: d6d2b0e1538d ("net: airoha: Fix page recycling in airoha_qdma_rx_process()")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260402-airoha_qdma_rx_process-mem-leak-fix-v1-1-b5706f402d3c@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Error: Failed to generate final synthesis
drivers/net/ethernet/airoha/airoha_eth.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 4fc6bd282b465..bdf600fea9508 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -709,9 +709,8 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
if (q->skb) {
dev_kfree_skb(q->skb);
q->skb = NULL;
- } else {
- page_pool_put_full_page(q->page_pool, page, true);
}
+ page_pool_put_full_page(q->page_pool, page, true);
}
airoha_qdma_fill_rx_queue(q);
--
2.53.0
^ permalink raw reply related
* [PATCH AUTOSEL 6.18] net: lapbether: handle NETDEV_PRE_TYPE_CHANGE
From: Sasha Levin @ 2026-04-20 13:22 UTC (permalink / raw)
To: patches, stable
Cc: Eric Dumazet, syzbot+d8c285748fa7292580a9, Martin Schiller,
Simon Horman, Jakub Kicinski, Sasha Levin, andrew+netdev, davem,
pabeni, jeff, fubar, linux-x25, netdev, linux-kernel
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit b120e4432f9f56c7103133d6a11245e617695adb ]
lapbeth_data_transmit() expects the underlying device type
to be ARPHRD_ETHER.
Returning NOTIFY_BAD from lapbeth_device_event() makes sure
bonding driver can not break this expectation.
Fixes: 872254dd6b1f ("net/bonding: Enable bonding to enslave non ARPHRD_ETHER")
Reported-by: syzbot+d8c285748fa7292580a9@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/69cd22a1.050a0220.70c3a.0002.GAE@google.com/T/#u
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Martin Schiller <ms@dev.tdt.de>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260402103519.1201565-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Error: Failed to generate final synthesis
drivers/net/wan/lapbether.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
index f357a7ac70ac4..9861c99ea56c4 100644
--- a/drivers/net/wan/lapbether.c
+++ b/drivers/net/wan/lapbether.c
@@ -446,33 +446,36 @@ static void lapbeth_free_device(struct lapbethdev *lapbeth)
static int lapbeth_device_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
- struct lapbethdev *lapbeth;
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+ struct lapbethdev *lapbeth;
if (dev_net(dev) != &init_net)
return NOTIFY_DONE;
- if (!dev_is_ethdev(dev) && !lapbeth_get_x25_dev(dev))
+ lapbeth = lapbeth_get_x25_dev(dev);
+ if (!dev_is_ethdev(dev) && !lapbeth)
return NOTIFY_DONE;
switch (event) {
case NETDEV_UP:
/* New ethernet device -> new LAPB interface */
- if (!lapbeth_get_x25_dev(dev))
+ if (!lapbeth)
lapbeth_new_device(dev);
break;
case NETDEV_GOING_DOWN:
/* ethernet device closes -> close LAPB interface */
- lapbeth = lapbeth_get_x25_dev(dev);
if (lapbeth)
dev_close(lapbeth->axdev);
break;
case NETDEV_UNREGISTER:
/* ethernet device disappears -> remove LAPB interface */
- lapbeth = lapbeth_get_x25_dev(dev);
if (lapbeth)
lapbeth_free_device(lapbeth);
break;
+ case NETDEV_PRE_TYPE_CHANGE:
+ /* Our underlying device type must not change. */
+ if (lapbeth)
+ return NOTIFY_BAD;
}
return NOTIFY_DONE;
--
2.53.0
^ permalink raw reply related
* [PATCH AUTOSEL 6.18] xfrm_user: fix info leak in build_mapping()
From: Sasha Levin @ 2026-04-20 13:21 UTC (permalink / raw)
To: patches, stable
Cc: Greg Kroah-Hartman, Steffen Klassert, Herbert Xu, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
Sasha Levin, martin, netdev, linux-kernel
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ Upstream commit 1beb76b2053b68c491b78370794b8ff63c8f8c02 ]
struct xfrm_usersa_id has a one-byte padding hole after the proto
field, which ends up never getting set to zero before copying out to
userspace. Fix that up by zeroing out the whole structure before
setting individual variables.
Fixes: 3a2dfbe8acb1 ("xfrm: Notify changes in UDP encapsulation via netlink")
Cc: Steffen Klassert <steffen.klassert@secunet.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Simon Horman <horms@kernel.org>
Assisted-by: gregkh_clanker_t1000
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Error: Failed to generate final synthesis
net/xfrm/xfrm_user.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 1ddcf2a1eff7a..b3f69c0760d4c 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -4164,6 +4164,7 @@ static int build_mapping(struct sk_buff *skb, struct xfrm_state *x,
um = nlmsg_data(nlh);
+ memset(&um->id, 0, sizeof(um->id));
memcpy(&um->id.daddr, &x->id.daddr, sizeof(um->id.daddr));
um->id.spi = x->id.spi;
um->id.family = x->props.family;
--
2.53.0
^ permalink raw reply related
* [PATCH AUTOSEL 6.18] xsk: validate MTU against usable frame size on bind
From: Sasha Levin @ 2026-04-20 13:21 UTC (permalink / raw)
To: patches, stable
Cc: Maciej Fijalkowski, Björn Töpel, Jakub Kicinski,
Sasha Levin, magnus.karlsson, davem, edumazet, pabeni, ast,
netdev, bpf, linux-kernel
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>
From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
[ Upstream commit 36ee60b569ba0dfb6f961333b90d19ab5b323fa9 ]
AF_XDP bind currently accepts zero-copy pool configurations without
verifying that the device MTU fits into the usable frame space provided
by the UMEM chunk.
This becomes a problem since we started to respect tailroom which is
subtracted from chunk_size (among with headroom). 2k chunk size might
not provide enough space for standard 1500 MTU, so let us catch such
settings at bind time. Furthermore, validate whether underlying HW will
be able to satisfy configured MTU wrt XSK's frame size multiplied by
supported Rx buffer chain length (that is exposed via
net_device::xdp_zc_max_segs).
Fixes: 24ea50127ecf ("xsk: support mbuf on ZC RX")
Reviewed-by: Björn Töpel <bjorn@kernel.org>
Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
Link: https://patch.msgid.link/20260402154958.562179-5-maciej.fijalkowski@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Error: Failed to generate final synthesis
net/xdp/xsk_buff_pool.c | 28 +++++++++++++++++++++++++---
1 file changed, 25 insertions(+), 3 deletions(-)
diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c
index 677c7d00f8c32..a129ce6f1c25f 100644
--- a/net/xdp/xsk_buff_pool.c
+++ b/net/xdp/xsk_buff_pool.c
@@ -10,6 +10,8 @@
#include "xdp_umem.h"
#include "xsk.h"
+#define ETH_PAD_LEN (ETH_HLEN + 2 * VLAN_HLEN + ETH_FCS_LEN)
+
void xp_add_xsk(struct xsk_buff_pool *pool, struct xdp_sock *xs)
{
unsigned long flags;
@@ -165,8 +167,12 @@ static void xp_disable_drv_zc(struct xsk_buff_pool *pool)
int xp_assign_dev(struct xsk_buff_pool *pool,
struct net_device *netdev, u16 queue_id, u16 flags)
{
+ u32 needed = netdev->mtu + ETH_PAD_LEN;
+ u32 segs = netdev->xdp_zc_max_segs;
+ bool mbuf = flags & XDP_USE_SG;
bool force_zc, force_copy;
struct netdev_bpf bpf;
+ u32 frame_size;
int err = 0;
ASSERT_RTNL();
@@ -186,7 +192,7 @@ int xp_assign_dev(struct xsk_buff_pool *pool,
if (err)
return err;
- if (flags & XDP_USE_SG)
+ if (mbuf)
pool->umem->flags |= XDP_UMEM_SG_FLAG;
if (flags & XDP_USE_NEED_WAKEUP)
@@ -208,8 +214,24 @@ int xp_assign_dev(struct xsk_buff_pool *pool,
goto err_unreg_pool;
}
- if (netdev->xdp_zc_max_segs == 1 && (flags & XDP_USE_SG)) {
- err = -EOPNOTSUPP;
+ if (mbuf) {
+ if (segs == 1) {
+ err = -EOPNOTSUPP;
+ goto err_unreg_pool;
+ }
+ } else {
+ segs = 1;
+ }
+
+ /* open-code xsk_pool_get_rx_frame_size() as pool->dev is not
+ * set yet at this point; we are before getting down to driver
+ */
+ frame_size = __xsk_pool_get_rx_frame_size(pool) -
+ xsk_pool_get_tailroom(mbuf);
+ frame_size = ALIGN_DOWN(frame_size, 128);
+
+ if (needed > frame_size * segs) {
+ err = -EINVAL;
goto err_unreg_pool;
}
--
2.53.0
^ permalink raw reply related
* [PATCH AUTOSEL 6.18] nfc: s3fwrn5: allocate rx skb before consuming bytes
From: Sasha Levin @ 2026-04-20 13:21 UTC (permalink / raw)
To: patches, stable
Cc: Pengpeng Hou, Jakub Kicinski, Sasha Levin, krzk, bongsu.jeon,
netdev, linux-kernel
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>
From: Pengpeng Hou <pengpeng@iscas.ac.cn>
[ Upstream commit 5c14a19d5b1645cce1cb1252833d70b23635b632 ]
s3fwrn82_uart_read() reports the number of accepted bytes to the serdev
core. The current code consumes bytes into recv_skb and may already
deliver a complete frame before allocating a fresh receive buffer.
If that alloc_skb() fails, the callback returns 0 even though it has
already consumed bytes, and it leaves recv_skb as NULL for the next
receive callback. That breaks the receive_buf() accounting contract and
can also lead to a NULL dereference on the next skb_put_u8().
Allocate the receive skb lazily before consuming the next byte instead.
If allocation fails, return the number of bytes already accepted.
Fixes: 3f52c2cb7e3a ("nfc: s3fwrn5: Support a UART interface")
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260402042148.65236-1-pengpeng@iscas.ac.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Error: Failed to generate final synthesis
drivers/nfc/s3fwrn5/uart.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/nfc/s3fwrn5/uart.c b/drivers/nfc/s3fwrn5/uart.c
index 9c09c10c2a464..4ee481bd7e965 100644
--- a/drivers/nfc/s3fwrn5/uart.c
+++ b/drivers/nfc/s3fwrn5/uart.c
@@ -58,6 +58,12 @@ static size_t s3fwrn82_uart_read(struct serdev_device *serdev,
size_t i;
for (i = 0; i < count; i++) {
+ if (!phy->recv_skb) {
+ phy->recv_skb = alloc_skb(NCI_SKB_BUFF_LEN, GFP_KERNEL);
+ if (!phy->recv_skb)
+ return i;
+ }
+
skb_put_u8(phy->recv_skb, *data++);
if (phy->recv_skb->len < S3FWRN82_NCI_HEADER)
@@ -69,9 +75,7 @@ static size_t s3fwrn82_uart_read(struct serdev_device *serdev,
s3fwrn5_recv_frame(phy->common.ndev, phy->recv_skb,
phy->common.mode);
- phy->recv_skb = alloc_skb(NCI_SKB_BUFF_LEN, GFP_KERNEL);
- if (!phy->recv_skb)
- return 0;
+ phy->recv_skb = NULL;
}
return i;
--
2.53.0
^ permalink raw reply related
* [PATCH AUTOSEL 6.18] ipv4: icmp: fix null-ptr-deref in icmp_build_probe()
From: Sasha Levin @ 2026-04-20 13:21 UTC (permalink / raw)
To: patches, stable
Cc: Yiqi Sun, Jakub Kicinski, Sasha Levin, davem, dsahern, edumazet,
pabeni, andreas.a.roeseler, netdev, linux-kernel
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>
From: Yiqi Sun <sunyiqixm@gmail.com>
[ Upstream commit fde29fd9349327acc50d19a0b5f3d5a6c964dfd8 ]
ipv6_stub->ipv6_dev_find() may return ERR_PTR(-EAFNOSUPPORT) when the
IPv6 stack is not active (CONFIG_IPV6=m and not loaded), and passing
this error pointer to dev_hold() will cause a kernel crash with
null-ptr-deref.
Instead, silently discard the request. RFC 8335 does not appear to
define a specific response for the case where an IPv6 interface
identifier is syntactically valid but the implementation cannot perform
the lookup at runtime, and silently dropping the request may safer than
misreporting "No Such Interface".
Fixes: d329ea5bd884 ("icmp: add response to RFC 8335 PROBE messages")
Signed-off-by: Yiqi Sun <sunyiqixm@gmail.com>
Link: https://patch.msgid.link/20260402070419.2291578-1-sunyiqixm@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Error: Failed to generate final synthesis
net/ipv4/icmp.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index b39176b620785..980aa17f3534d 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -1145,6 +1145,13 @@ bool icmp_build_probe(struct sk_buff *skb, struct icmphdr *icmphdr)
if (iio->ident.addr.ctype3_hdr.addrlen != sizeof(struct in6_addr))
goto send_mal_query;
dev = ipv6_stub->ipv6_dev_find(net, &iio->ident.addr.ip_addr.ipv6_addr, dev);
+ /*
+ * If IPv6 identifier lookup is unavailable, silently
+ * discard the request instead of misreporting NO_IF.
+ */
+ if (IS_ERR(dev))
+ return false;
+
dev_hold(dev);
break;
#endif
--
2.53.0
^ permalink raw reply related
* [PATCH AUTOSEL 6.18] net: ioam6: fix OOB and missing lock
From: Sasha Levin @ 2026-04-20 13:21 UTC (permalink / raw)
To: patches, stable
Cc: Justin Iurman, Jakub Kicinski, Sasha Levin, davem, dsahern,
edumazet, pabeni, idosch, netdev, linux-kernel
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>
From: Justin Iurman <justin.iurman@gmail.com>
[ Upstream commit b30b1675aa2bcf0491fd3830b051df4e08a7c8ca ]
When trace->type.bit6 is set:
if (trace->type.bit6) {
...
queue = skb_get_tx_queue(dev, skb);
qdisc = rcu_dereference(queue->qdisc);
This code can lead to an out-of-bounds access of the dev->_tx[] array
when is_input is true. In such a case, the packet is on the RX path and
skb->queue_mapping contains the RX queue index of the ingress device. If
the ingress device has more RX queues than the egress device (dev) has
TX queues, skb_get_queue_mapping(skb) will exceed dev->num_tx_queues.
Add a check to avoid this situation since skb_get_tx_queue() does not
clamp the index. This issue has also revealed that per queue visibility
cannot be accurate and will be replaced later as a new feature.
While at it, add missing lock around qdisc_qstats_qlen_backlog(). The
function __ioam6_fill_trace_data() is called from both softirq and
process contexts, hence the use of spin_lock_bh() here.
Fixes: b63c5478e9cb ("ipv6: ioam: Support for Queue depth data field")
Reported-by: Jakub Kicinski <kuba@kernel.org>
Closes: https://lore.kernel.org/netdev/20260403214418.2233266-2-kuba@kernel.org/
Signed-off-by: Justin Iurman <justin.iurman@gmail.com>
Link: https://patch.msgid.link/20260404134137.24553-1-justin.iurman@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Error: Failed to generate final synthesis
net/ipv6/ioam6.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/ioam6.c b/net/ipv6/ioam6.c
index 12350e1e18bde..b91de51ffa9ea 100644
--- a/net/ipv6/ioam6.c
+++ b/net/ipv6/ioam6.c
@@ -803,12 +803,16 @@ static void __ioam6_fill_trace_data(struct sk_buff *skb,
struct Qdisc *qdisc;
__u32 qlen, backlog;
- if (dev->flags & IFF_LOOPBACK) {
+ if (dev->flags & IFF_LOOPBACK ||
+ skb_get_queue_mapping(skb) >= dev->num_tx_queues) {
*(__be32 *)data = cpu_to_be32(IOAM6_U32_UNAVAILABLE);
} else {
queue = skb_get_tx_queue(dev, skb);
qdisc = rcu_dereference(queue->qdisc);
+
+ spin_lock_bh(qdisc_lock(qdisc));
qdisc_qstats_qlen_backlog(qdisc, &qlen, &backlog);
+ spin_unlock_bh(qdisc_lock(qdisc));
*(__be32 *)data = cpu_to_be32(backlog);
}
--
2.53.0
^ permalink raw reply related
* [PATCH AUTOSEL 6.18] dt-bindings: net: Fix Tegra234 MGBE PTP clock
From: Sasha Levin @ 2026-04-20 13:21 UTC (permalink / raw)
To: patches, stable
Cc: Jon Hunter, Krzysztof Kozlowski, Jakub Kicinski, Sasha Levin,
andrew+netdev, davem, edumazet, pabeni, robh, krzk+dt, conor+dt,
thierry.reding, treding, vbhadram, netdev, devicetree,
linux-tegra, linux-kernel
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>
From: Jon Hunter <jonathanh@nvidia.com>
[ Upstream commit fb22b1fc5bca3c0aad95388933497ceb30f1fb26 ]
The PTP clock for the Tegra234 MGBE device is incorrectly named
'ptp-ref' and should be 'ptp_ref'. This is causing the following
warning to be observed on Tegra234 platforms that use this device:
ERR KERN tegra-mgbe 6800000.ethernet eth0: Invalid PTP clock rate
WARNING KERN tegra-mgbe 6800000.ethernet eth0: PTP init failed
Although this constitutes an ABI breakage in the binding for this
device, PTP support has clearly never worked and so fix this now
so we can correct the device-tree for this device. Note that the
MGBE driver still supports the legacy 'ptp-ref' clock name and so
older/existing device-trees will still work, but given that this
is not the correct name, there is no point to advertise this in the
binding.
Fixes: 189c2e5c7669 ("dt-bindings: net: Add Tegra234 MGBE")
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Link: https://patch.msgid.link/20260401102941.17466-3-jonathanh@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Error: Failed to generate final synthesis
.../devicetree/bindings/net/nvidia,tegra234-mgbe.yaml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/nvidia,tegra234-mgbe.yaml b/Documentation/devicetree/bindings/net/nvidia,tegra234-mgbe.yaml
index 2bd3efff2485e..215f14d1897d2 100644
--- a/Documentation/devicetree/bindings/net/nvidia,tegra234-mgbe.yaml
+++ b/Documentation/devicetree/bindings/net/nvidia,tegra234-mgbe.yaml
@@ -42,7 +42,7 @@ properties:
- const: mgbe
- const: mac
- const: mac-divider
- - const: ptp-ref
+ - const: ptp_ref
- const: rx-input-m
- const: rx-input
- const: tx
@@ -133,7 +133,7 @@ examples:
<&bpmp TEGRA234_CLK_MGBE0_RX_PCS_M>,
<&bpmp TEGRA234_CLK_MGBE0_RX_PCS>,
<&bpmp TEGRA234_CLK_MGBE0_TX_PCS>;
- clock-names = "mgbe", "mac", "mac-divider", "ptp-ref", "rx-input-m",
+ clock-names = "mgbe", "mac", "mac-divider", "ptp_ref", "rx-input-m",
"rx-input", "tx", "eee-pcs", "rx-pcs-input", "rx-pcs-m",
"rx-pcs", "tx-pcs";
resets = <&bpmp TEGRA234_RESET_MGBE0_MAC>,
--
2.53.0
^ permalink raw reply related
* [PATCH AUTOSEL 6.18] net: ipa: fix GENERIC_CMD register field masks for IPA v5.0+
From: Sasha Levin @ 2026-04-20 13:21 UTC (permalink / raw)
To: patches, stable
Cc: Alexander Koskovich, Luca Weiss, Simon Horman, Paolo Abeni,
Sasha Levin, andrew+netdev, davem, edumazet, kuba, netdev,
linux-kernel
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>
From: Alexander Koskovich <akoskovich@pm.me>
[ Upstream commit 9709b56d908acc120fe8b4ae250b3c9d749ea832 ]
Fix the field masks to match the hardware layout documented in
downstream GSI (GSI_V3_0_EE_n_GSI_EE_GENERIC_CMD_*).
Notably this fixes a WARN I was seeing when I tried to send "stop"
to the MPSS remoteproc while IPA was up.
Fixes: faf0678ec8a0 ("net: ipa: add IPA v5.0 GSI register definitions")
Signed-off-by: Alexander Koskovich <akoskovich@pm.me>
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260403-milos-ipa-v1-1-01e9e4e03d3e@fairphone.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Error: Failed to generate final synthesis
drivers/net/ipa/reg/gsi_reg-v5.0.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ipa/reg/gsi_reg-v5.0.c b/drivers/net/ipa/reg/gsi_reg-v5.0.c
index 36d1e65df71bb..3334d8e20ad28 100644
--- a/drivers/net/ipa/reg/gsi_reg-v5.0.c
+++ b/drivers/net/ipa/reg/gsi_reg-v5.0.c
@@ -156,9 +156,10 @@ REG_FIELDS(EV_CH_CMD, ev_ch_cmd, 0x00025010 + 0x12000 * GSI_EE_AP);
static const u32 reg_generic_cmd_fmask[] = {
[GENERIC_OPCODE] = GENMASK(4, 0),
- [GENERIC_CHID] = GENMASK(9, 5),
- [GENERIC_EE] = GENMASK(13, 10),
- /* Bits 14-31 reserved */
+ [GENERIC_CHID] = GENMASK(12, 5),
+ [GENERIC_EE] = GENMASK(16, 13),
+ /* Bits 17-23 reserved */
+ [GENERIC_PARAMS] = GENMASK(31, 24),
};
REG_FIELDS(GENERIC_CMD, generic_cmd, 0x00025018 + 0x12000 * GSI_EE_AP);
--
2.53.0
^ permalink raw reply related
* [PATCH AUTOSEL 6.18] net: sched: act_csum: validate nested VLAN headers
From: Sasha Levin @ 2026-04-20 13:21 UTC (permalink / raw)
To: patches, stable
Cc: Ruide Cao, Yifan Wu, Juefei Pu, Yuan Tan, Xin Liu, Ren Wei,
Ren Wei, Simon Horman, Jakub Kicinski, Sasha Levin, jhs, jiri,
davem, edumazet, pabeni, elibr, netdev, linux-kernel
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>
From: Ruide Cao <caoruide123@gmail.com>
[ Upstream commit c842743d073bdd683606cb414eb0ca84465dd834 ]
tcf_csum_act() walks nested VLAN headers directly from skb->data when an
skb still carries in-payload VLAN tags. The current code reads
vlan->h_vlan_encapsulated_proto and then pulls VLAN_HLEN bytes without
first ensuring that the full VLAN header is present in the linear area.
If only part of an inner VLAN header is linearized, accessing
h_vlan_encapsulated_proto reads past the linear area, and the following
skb_pull(VLAN_HLEN) may violate skb invariants.
Fix this by requiring pskb_may_pull(skb, VLAN_HLEN) before accessing and
pulling each nested VLAN header. If the header still is not fully
available, drop the packet through the existing error path.
Fixes: 2ecba2d1e45b ("net: sched: act_csum: Fix csum calc for tagged packets")
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Co-developed-by: Yuan Tan <yuantan098@gmail.com>
Signed-off-by: Yuan Tan <yuantan098@gmail.com>
Suggested-by: Xin Liu <bird@lzu.edu.cn>
Tested-by: Ren Wei <enjou1224z@gmail.com>
Signed-off-by: Ruide Cao <caoruide123@gmail.com>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/22df2fcb49f410203eafa5d97963dd36089f4ecf.1774892775.git.caoruide123@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Error: Failed to generate final synthesis
net/sched/act_csum.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c
index 0939e6b2ba4d1..3a377604ad343 100644
--- a/net/sched/act_csum.c
+++ b/net/sched/act_csum.c
@@ -604,8 +604,12 @@ TC_INDIRECT_SCOPE int tcf_csum_act(struct sk_buff *skb,
protocol = skb->protocol;
orig_vlan_tag_present = true;
} else {
- struct vlan_hdr *vlan = (struct vlan_hdr *)skb->data;
+ struct vlan_hdr *vlan;
+ if (!pskb_may_pull(skb, VLAN_HLEN))
+ goto drop;
+
+ vlan = (struct vlan_hdr *)skb->data;
protocol = vlan->h_vlan_encapsulated_proto;
skb_pull(skb, VLAN_HLEN);
skb_reset_network_header(skb);
--
2.53.0
^ permalink raw reply related
* [PATCH AUTOSEL 7.0] netfilter: require Ethernet MAC header before using eth_hdr()
From: Sasha Levin @ 2026-04-20 13:21 UTC (permalink / raw)
To: patches, stable
Cc: Zhengchuan Liang, Florian Westphal, Ren Wei, Ren Wei, Sasha Levin,
pablo, davem, dsahern, edumazet, kuba, pabeni, netfilter-devel,
coreteam, netdev, linux-kernel
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>
From: Zhengchuan Liang <zcliangcn@gmail.com>
[ Upstream commit 62443dc21114c0bbc476fa62973db89743f2f137 ]
`ip6t_eui64`, `xt_mac`, the `bitmap:ip,mac`, `hash:ip,mac`, and
`hash:mac` ipset types, and `nf_log_syslog` access `eth_hdr(skb)`
after either assuming that the skb is associated with an Ethernet
device or checking only that the `ETH_HLEN` bytes at
`skb_mac_header(skb)` lie between `skb->head` and `skb->data`.
Make these paths first verify that the skb is associated with an
Ethernet device, that the MAC header was set, and that it spans at
least a full Ethernet header before accessing `eth_hdr(skb)`.
Suggested-by: Florian Westphal <fw@strlen.de>
Tested-by: Ren Wei <enjou1224z@gmail.com>
Signed-off-by: Zhengchuan Liang <zcliangcn@gmail.com>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
`skb_mac_header_was_set` has been available since 2013, so it's
available in all currently supported stable trees. `skb_mac_header_len`
was introduced in 2017, also available in all supported stable trees
(5.4+).
Now I have all the information needed for the full analysis. Let me
compile it.
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: Subject Line
- **Subsystem**: netfilter (multiple files: ip6t_eui64, xt_mac, ipset
types, nf_log_syslog)
- **Action verb**: "require" (ensuring precondition is met before use)
- **Summary**: Require Ethernet MAC header validation before calling
`eth_hdr(skb)` across multiple netfilter modules
Record: [netfilter] [require] [validate MAC header is Ethernet and
properly set before accessing eth_hdr(skb)]
### Step 1.2: Tags
- **Suggested-by: Florian Westphal** - the netfilter subsystem co-
maintainer suggested this broader fix
- **Tested-by: Ren Wei** - fix was tested
- **Signed-off-by: Florian Westphal** - the netfilter maintainer signed
off and merged it
- No Fixes: tag (expected - this is a broader hardening patch)
- No Cc: stable tag (expected)
Record: Florian Westphal (netfilter maintainer) suggested and signed off
on this patch. Tested.
### Step 1.3: Commit Body
The commit explains that multiple netfilter modules access
`eth_hdr(skb)` after either:
1. Assuming the skb is associated with an Ethernet device, OR
2. Only checking that ETH_HLEN bytes at `skb_mac_header(skb)` lie
between `skb->head` and `skb->data` (raw pointer arithmetic)
The fix adds three-part validation: (1) device is Ethernet
(`ARPHRD_ETHER`), (2) MAC header was set (`skb_mac_header_was_set`), (3)
MAC header spans a full Ethernet header (`skb_mac_header_len >=
ETH_HLEN`).
Record: Bug: `eth_hdr(skb)` accessed without proper validation that skb
has a valid Ethernet MAC header. Can lead to out-of-bounds reads. Root
cause: inadequate validation before dereferencing the MAC header.
### Step 1.4: Hidden Bug Fix Detection
This IS a memory safety fix. The commit message says "require...before
using" which means the existing code accesses `eth_hdr()` without proper
guards. Confirmed by KASAN report mentioned in the v2 changelog of patch
1/2. Florian Westphal explicitly identified the other files as
"suspicious spots."
Record: Yes, this is a genuine memory safety bug fix - prevents out-of-
bounds access on the MAC header.
## PHASE 2: DIFF ANALYSIS
### Step 2.1: Inventory
- **net/ipv6/netfilter/ip6t_eui64.c**: +5/-2 lines (adds ARPHRD_ETHER
check, uses `skb_mac_header_was_set`/`skb_mac_header_len`)
- **net/netfilter/ipset/ip_set_bitmap_ipmac.c**: +3/-2 lines
- **net/netfilter/ipset/ip_set_hash_ipmac.c**: +5/-4 lines (two
functions)
- **net/netfilter/ipset/ip_set_hash_mac.c**: +3/-2 lines
- **net/netfilter/nf_log_syslog.c**: +6/-1 lines (two functions)
- **net/netfilter/xt_mac.c**: +1/-3 lines
Total: ~23 lines added, ~14 removed. Six files, all in netfilter
subsystem.
Record: Multi-file but mechanical/repetitive change. Each file gets the
same validation pattern. Scope: contained to netfilter MAC header
access.
### Step 2.2: Code Flow Changes
Each hunk follows the same pattern:
- **Before**: Raw pointer arithmetic `skb_mac_header(skb) < skb->head ||
skb_mac_header(skb) + ETH_HLEN > skb->data`, or NO check at all
- **After**: Proper three-part check: `!skb->dev || skb->dev->type !=
ARPHRD_ETHER || !skb_mac_header_was_set(skb) ||
skb_mac_header_len(skb) < ETH_HLEN`
### Step 2.3: Bug Mechanism
**Category**: Memory safety (out-of-bounds read / invalid memory access)
The old checks were insufficient:
1. **ip6t_eui64.c**: Only checked pointer bounds, not device type
2. **ipset files**: Only checked pointer bounds, not device type or
`skb_mac_header_was_set`
3. **nf_log_syslog.c dump_arp_packet**: NO check at all before
`eth_hdr(skb)`
4. **nf_log_syslog.c dump_mac_header**: Checked device type via switch
but not MAC header validity
5. **xt_mac.c**: Already had ARPHRD_ETHER check but used raw pointer
comparison instead of proper API
Without proper validation, if the MAC header isn't set or isn't
Ethernet, `eth_hdr(skb)` returns a pointer to potentially uninitialized
or out-of-bounds memory.
### Step 2.4: Fix Quality
- **Obviously correct**: Yes. The pattern is simple and repeated
mechanically.
- **Minimal/surgical**: Yes. Only replaces old check with new one; no
logic changes.
- **Regression risk**: Very low. Adding validation before access can
only make the code safer. If device isn't Ethernet, these functions
should return early anyway.
Record: High quality fix. Uses proper kernel APIs instead of raw pointer
arithmetic.
## PHASE 3: GIT HISTORY
### Step 3.1: Blame
- The buggy code in ipset files dates from their initial introduction
- `xt_mac.c` buggy check from 2010 (Jan Engelhardt, commit
1d1c397db95f1c)
- `ip6t_eui64.c` dates back to Linux 2.6.12 (2005)
- `nf_log_syslog.c` `dump_arp_packet` and `dump_mac_header` from the
nf_log consolidation era
Record: Bugs present since the code was written. Affects all stable
trees.
### Step 3.2: Fixes tag
No Fixes: tag on this commit. Patch 1/2 has `Fixes: 1da177e4c3f41`
("Linux-2.6.12-rc2").
### Step 3.3: Prerequisites
This commit (2/2) depends on commit fdce0b3590f72 (1/2) for the
`ip6t_eui64.c` changes only. The other 5 files are independent.
Record: `ip6t_eui64.c` hunk requires patch 1/2 first. Other files:
standalone.
### Step 3.4: Author
Written by Zhengchuan Liang, **suggested by and signed off by Florian
Westphal** (netfilter maintainer). Very high confidence in the fix.
### Step 3.5: Dependencies
`skb_mac_header_was_set()` available since 2013. `skb_mac_header_len()`
available since 2017. Both available in all supported stable trees.
## PHASE 4: MAILING LIST RESEARCH
### Step 4.1-4.4: Patch Discussion
- **v1** (March 31, 2026): Single-patch fixing only `ip6t_eui64.c`
- Florian Westphal (netfilter maintainer) reviewed v1 and:
- Asked "why is net/netfilter/xt_mac.c safe?" - implying it isn't
- Suggested using `skb_mac_header_len()` instead of raw pointer checks
- Suggested adding `ARPHRD_ETHER` device type check
- Identified "other suspicious spots" in `nf_log_syslog.c` and ipset
- Asked the author to make a patch covering all of them
- **v2** (April 4, 2026): Split into 2 patches. Patch 1/2 is the focused
eui64 fix, patch 2/2 (this commit) is the broader hardening suggested
by Florian.
Record: This patch was directly suggested and shaped by the netfilter
subsystem maintainer. Strong endorsement.
### Step 4.5: Stable Discussion
The v2 changelog mentions "KASAN report" with a PoC, indicating this is
a confirmed memory safety issue, not theoretical.
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1-5.4: Function Analysis
- `eui64_mt6()`: Called from netfilter match evaluation (PRE_ROUTING,
LOCAL_IN, FORWARD hooks)
- `bitmap_ipmac_kadt()`, `hash_ipmac4_kadt()`, `hash_ipmac6_kadt()`,
`hash_mac4_kadt()`: Called from ipset kernel-side operations
- `dump_arp_packet()`, `dump_mac_header()`: Called from nf_log_syslog
packet logging
- All are reachable from packet processing paths triggered by network
traffic
Record: All affected functions are on hot packet processing paths,
triggered by normal network traffic with appropriate netfilter rules
configured.
## PHASE 6: STABLE TREE ANALYSIS
### Step 6.1: Code Existence
- `xt_mac.c`: Unchanged since v5.4+ (will apply cleanly)
- ipset files: Unchanged since v5.15+ (will apply cleanly)
- `nf_log_syslog.c`: Has some churn but the relevant functions exist in
v5.15+
- `ip6t_eui64.c`: Needs patch 1/2 as prerequisite
### Step 6.2: Backport Complications
For `ip6t_eui64.c`, patch 1/2 (fdce0b3590f72) must also be backported.
Other files: clean apply expected.
## PHASE 7: SUBSYSTEM CONTEXT
### Step 7.1: Subsystem
- **Subsystem**: Netfilter (net/netfilter/, net/ipv6/netfilter/)
- **Criticality**: IMPORTANT - netfilter is the Linux firewall
subsystem, used by nearly all networked systems
### Step 7.2: Activity
Active subsystem with regular maintenance.
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: Affected Users
Anyone using netfilter with MAC-address matching rules (iptables -m mac,
ip6tables eui64 match, ipset with mac types) or logging with MACDECODE
flag.
### Step 8.2: Trigger Conditions
- KASAN-confirmed: a PoC exists
- Triggered by network traffic matching rules that use MAC header access
- Could be triggered by non-Ethernet packets reaching netfilter rules
that assume Ethernet
### Step 8.3: Severity
- **Out-of-bounds read on MAC header**: Can cause kernel crash (oops),
potential info leak
- **KASAN-confirmed**: Severity HIGH
### Step 8.4: Risk-Benefit
- **Benefit**: HIGH - prevents memory safety bugs across 6 netfilter
modules
- **Risk**: VERY LOW - mechanical replacement of validation checks, each
change is 1-3 lines, obviously correct
- **Ratio**: Strongly favorable
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: Evidence
**FOR backporting:**
- KASAN-confirmed memory safety bug with PoC
- Suggested and signed off by netfilter maintainer Florian Westphal
- Tested
- Small, mechanical, obviously correct changes
- Uses proper kernel APIs
- Affects widely-used netfilter modules
- Buggy code present in all stable trees
- Functions available since kernel 4.x/5.x
**AGAINST backporting:**
- Part of a 2-patch series (ip6t_eui64.c hunk depends on patch 1/2)
- No explicit Cc: stable (expected)
- Touches 6 files (but all changes are identical pattern)
### Step 9.2: Stable Rules Checklist
1. Obviously correct? **YES** - mechanical pattern replacement,
maintainer-suggested
2. Fixes real bug? **YES** - KASAN-confirmed out-of-bounds access
3. Important issue? **YES** - memory safety / potential crash / info
leak
4. Small and contained? **YES** - ~37 lines total across 6 files, all
same pattern
5. No new features? **YES** - only tightens validation
6. Can apply to stable? **YES** (with patch 1/2 for ip6t_eui64.c)
### Step 9.3: Exception Categories
Not an exception category - this is a straightforward bug fix.
### Step 9.4: Decision
This is a clear YES. Memory safety fix in the netfilter subsystem,
KASAN-confirmed, suggested by the maintainer, obviously correct, small
scope.
## Verification
- [Phase 1] Parsed tags: Suggested-by and Signed-off-by Florian Westphal
(netfilter maintainer), Tested-by Ren Wei
- [Phase 2] Diff analysis: 6 files modified, each replacing inadequate
MAC header validation with proper 3-part check (device type + header
set + header length)
- [Phase 2] Confirmed `nf_log_syslog.c:dump_arp_packet()` had NO
validation before `eth_hdr(skb)` access (line 81-83 in current tree)
- [Phase 2] Confirmed `nf_log_syslog.c:dump_mac_header()` entered
ARPHRD_ETHER case without MAC header validity check (line 791-793)
- [Phase 3] git blame: buggy code in ip6t_eui64.c from Linux 2.6.12
(2005), xt_mac.c from 2010, ipset from initial introduction
- [Phase 3] Confirmed patch 2/2 depends on patch 1/2 (fdce0b3590f72) for
ip6t_eui64.c hunk only
- [Phase 3] Confirmed `skb_mac_header_was_set` available since 2013,
`skb_mac_header_len` since 2017 - both in all supported stable trees
- [Phase 4] b4 dig found series at lore: v1->v2 evolution, v2 is [PATCH
nf v2 2/2]
- [Phase 4] Mailing list: Florian Westphal explicitly asked for broader
fix covering nf_log_syslog.c and ipset
- [Phase 4] v2 changelog mentions "KASAN report" with PoC confirming
real vulnerability
- [Phase 5] All affected functions on packet processing paths (netfilter
hooks, ipset kadt, nf_log)
- [Phase 6] xt_mac.c unchanged since v5.4, ipset files unchanged since
v5.15 - clean apply expected
- [Phase 6] nf_log_syslog.c has more churn but relevant code sections
exist in v5.15+
- [Phase 8] Failure mode: out-of-bounds memory read -> kernel oops or
info leak, severity HIGH
- UNVERIFIED: Exact applicability to v5.10.y and v5.4.y for
nf_log_syslog.c (nf_log consolidation happened around v5.12) - does
not affect decision since most files apply cleanly
**YES**
net/ipv6/netfilter/ip6t_eui64.c | 7 +++++--
net/netfilter/ipset/ip_set_bitmap_ipmac.c | 5 +++--
net/netfilter/ipset/ip_set_hash_ipmac.c | 9 +++++----
net/netfilter/ipset/ip_set_hash_mac.c | 5 +++--
net/netfilter/nf_log_syslog.c | 8 +++++++-
net/netfilter/xt_mac.c | 4 +---
6 files changed, 24 insertions(+), 14 deletions(-)
diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c
index da69a27e8332c..bbb684f9964c0 100644
--- a/net/ipv6/netfilter/ip6t_eui64.c
+++ b/net/ipv6/netfilter/ip6t_eui64.c
@@ -7,6 +7,7 @@
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/ipv6.h>
+#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/netfilter/x_tables.h>
@@ -21,8 +22,10 @@ eui64_mt6(const struct sk_buff *skb, struct xt_action_param *par)
{
unsigned char eui64[8];
- if (!(skb_mac_header(skb) >= skb->head &&
- skb_mac_header(skb) + ETH_HLEN <= skb->data)) {
+ if (!skb->dev || skb->dev->type != ARPHRD_ETHER)
+ return false;
+
+ if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN) {
par->hotdrop = true;
return false;
}
diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
index 2c625e0f49ec0..752f59ef87442 100644
--- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c
+++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
@@ -11,6 +11,7 @@
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/errno.h>
+#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/netlink.h>
#include <linux/jiffies.h>
@@ -220,8 +221,8 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
return -IPSET_ERR_BITMAP_RANGE;
/* Backward compatibility: we don't check the second flag */
- if (skb_mac_header(skb) < skb->head ||
- (skb_mac_header(skb) + ETH_HLEN) > skb->data)
+ if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
+ !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
return -EINVAL;
e.id = ip_to_id(map, ip);
diff --git a/net/netfilter/ipset/ip_set_hash_ipmac.c b/net/netfilter/ipset/ip_set_hash_ipmac.c
index 467c59a83c0ab..b9a2681e24888 100644
--- a/net/netfilter/ipset/ip_set_hash_ipmac.c
+++ b/net/netfilter/ipset/ip_set_hash_ipmac.c
@@ -11,6 +11,7 @@
#include <linux/skbuff.h>
#include <linux/errno.h>
#include <linux/random.h>
+#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <net/ip.h>
#include <net/ipv6.h>
@@ -89,8 +90,8 @@ hash_ipmac4_kadt(struct ip_set *set, const struct sk_buff *skb,
struct hash_ipmac4_elem e = { .ip = 0, { .foo[0] = 0, .foo[1] = 0 } };
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
- if (skb_mac_header(skb) < skb->head ||
- (skb_mac_header(skb) + ETH_HLEN) > skb->data)
+ if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
+ !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
return -EINVAL;
if (opt->flags & IPSET_DIM_TWO_SRC)
@@ -205,8 +206,8 @@ hash_ipmac6_kadt(struct ip_set *set, const struct sk_buff *skb,
};
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
- if (skb_mac_header(skb) < skb->head ||
- (skb_mac_header(skb) + ETH_HLEN) > skb->data)
+ if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
+ !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
return -EINVAL;
if (opt->flags & IPSET_DIM_TWO_SRC)
diff --git a/net/netfilter/ipset/ip_set_hash_mac.c b/net/netfilter/ipset/ip_set_hash_mac.c
index 718814730acf6..41a122591fe24 100644
--- a/net/netfilter/ipset/ip_set_hash_mac.c
+++ b/net/netfilter/ipset/ip_set_hash_mac.c
@@ -8,6 +8,7 @@
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/errno.h>
+#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <net/netlink.h>
@@ -77,8 +78,8 @@ hash_mac4_kadt(struct ip_set *set, const struct sk_buff *skb,
struct hash_mac4_elem e = { { .foo[0] = 0, .foo[1] = 0 } };
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
- if (skb_mac_header(skb) < skb->head ||
- (skb_mac_header(skb) + ETH_HLEN) > skb->data)
+ if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
+ !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
return -EINVAL;
if (opt->flags & IPSET_DIM_ONE_SRC)
diff --git a/net/netfilter/nf_log_syslog.c b/net/netfilter/nf_log_syslog.c
index 41503847d9d7f..98d2b9db16efe 100644
--- a/net/netfilter/nf_log_syslog.c
+++ b/net/netfilter/nf_log_syslog.c
@@ -78,7 +78,10 @@ dump_arp_packet(struct nf_log_buf *m,
else
logflags = NF_LOG_DEFAULT_MASK;
- if (logflags & NF_LOG_MACDECODE) {
+ if ((logflags & NF_LOG_MACDECODE) &&
+ skb->dev && skb->dev->type == ARPHRD_ETHER &&
+ skb_mac_header_was_set(skb) &&
+ skb_mac_header_len(skb) >= ETH_HLEN) {
nf_log_buf_add(m, "MACSRC=%pM MACDST=%pM ",
eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest);
nf_log_dump_vlan(m, skb);
@@ -789,6 +792,9 @@ static void dump_mac_header(struct nf_log_buf *m,
switch (dev->type) {
case ARPHRD_ETHER:
+ if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+ return;
+
nf_log_buf_add(m, "MACSRC=%pM MACDST=%pM ",
eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest);
nf_log_dump_vlan(m, skb);
diff --git a/net/netfilter/xt_mac.c b/net/netfilter/xt_mac.c
index 81649da57ba5d..4798cd2ca26ed 100644
--- a/net/netfilter/xt_mac.c
+++ b/net/netfilter/xt_mac.c
@@ -29,9 +29,7 @@ static bool mac_mt(const struct sk_buff *skb, struct xt_action_param *par)
if (skb->dev == NULL || skb->dev->type != ARPHRD_ETHER)
return false;
- if (skb_mac_header(skb) < skb->head)
- return false;
- if (skb_mac_header(skb) + ETH_HLEN > skb->data)
+ if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
return false;
ret = ether_addr_equal(eth_hdr(skb)->h_source, info->srcaddr);
ret ^= info->invert;
--
2.53.0
^ permalink raw reply related
* [PATCH AUTOSEL 7.0-6.18] hinic3: Add msg_send_lock for message sending concurrecy
From: Sasha Levin @ 2026-04-20 13:21 UTC (permalink / raw)
To: patches, stable
Cc: Fan Gong, Zhu Yikai, Paolo Abeni, Sasha Levin, andrew+netdev,
davem, edumazet, kuba, netdev, linux-kernel
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>
From: Fan Gong <gongfan1@huawei.com>
[ Upstream commit 2a76f900d17dcb9e8322770ac9bcae34517805b3 ]
As send_mbox_msg is invoked by 3 functions: hinic3_send_mbox_to_mgmt,
hinic3_response_mbox_to_mgmt and hinic3_send_mbox_to_mgmt_no_ack, only
hinic3_response_mbox_to_mgmt does not has mutex and the other two has
mbox->mbox_send_lock because their send actions are mutually exclusive.
As hinic3_response_mbox_to_mgmt does not conflict with them in send
actions but in mailbox resources, add the new mutex(msg_send_lock) in
send_mbox_msg to ensure message concurrency.
Besdies, in mbox_send_seg change FIELD_PREP to FIELD_GET in
MBOX_STATUS_FINISHED and MBOX_STATUS_SUCCESS to be more reasonable.
Co-developed-by: Zhu Yikai <zhuyikai1@h-partners.com>
Signed-off-by: Zhu Yikai <zhuyikai1@h-partners.com>
Signed-off-by: Fan Gong <gongfan1@huawei.com>
Link: https://patch.msgid.link/d83f7f6eb4b5e94642a558fab75d61292c347e48.1773062356.git.zhuyikai1@h-partners.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Now I have all the information needed. Let me compile the full analysis.
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: Subject Line
- **Subsystem:** `hinic3` (Huawei network driver)
- **Action verb:** "Add" (a mutex for concurrency)
- **Summary:** Adds `msg_send_lock` (actually `mbox_seg_send_lock`)
mutex to protect `send_mbox_msg()` from concurrent access
- Record: [hinic3] [add/fix] [add mutex for message sending concurrency
protection]
### Step 1.2: Tags
- **Co-developed-by:** Zhu Yikai
- **Signed-off-by:** Zhu Yikai, Fan Gong (primary author/submitter),
Paolo Abeni (net maintainer)
- **Link:** to patch.msgid.link
- No Fixes: tag (expected for candidates under review)
- No Reported-by: tag (no bug report, but race found by code inspection)
- No Cc: stable tag (expected)
- Record: Accepted by net maintainer (Paolo Abeni). No syzbot/reporter.
The author (Fan Gong) is a regular hinic3 driver developer with many
commits.
### Step 1.3: Commit Body
- **Bug:** `send_mbox_msg()` is called by 3 functions. Two
(`hinic3_send_mbox_to_mgmt`, `hinic3_send_mbox_to_mgmt_no_ack`) hold
`mbox_send_lock`, but `hinic3_response_mbox_to_mgmt` does not. Since
`hinic3_response_mbox_to_mgmt` can run concurrently with the others
and they all share hardware mailbox resources, a race condition
exists.
- **Also:** FIELD_PREP changed to FIELD_GET in two macros (cosmetic fix
for semantic correctness).
- Record: Race condition in shared hardware mailbox resources. The
response function can run from a workqueue handler concurrently with
user-initiated sends.
### Step 1.4: Hidden Bug Fix Detection
- This is an explicit concurrency fix, not disguised. The commit message
openly describes the missing synchronization.
- Record: Not a hidden fix; explicitly described race condition fix.
## PHASE 2: DIFF ANALYSIS
### Step 2.1: Inventory
- **Files:** `hinic3_mbox.c` (+4/-2), `hinic3_mbox.h` (+4/+0)
- **Functions modified:** `MBOX_STATUS_FINISHED` macro,
`MBOX_STATUS_SUCCESS` macro, `hinic3_mbox_pre_init()`,
`send_mbox_msg()`
- **Scope:** Small, single-subsystem, surgical fix. ~8 net new lines.
- Record: 2 files, ~8 lines added, minimal scope.
### Step 2.2: Code Flow Change
1. **FIELD_PREP→FIELD_GET macros:** For mask 0xFF (starts at bit 0),
both produce `val & 0xFF`. No functional change — purely semantic
correctness.
2. **`hinic3_mbox_pre_init()`:** Added
`mutex_init(&mbox->mbox_seg_send_lock)`.
3. **`send_mbox_msg()`:** Wraps the entire message preparation and
segment send loop with
`mutex_lock/unlock(&mbox->mbox_seg_send_lock)`.
- Record: Before: `send_mbox_msg()` had no internal locking. After:
Protected by `mbox_seg_send_lock`.
### Step 2.3: Bug Mechanism
- **Category:** Race condition / synchronization fix
- **Mechanism:** `hinic3_response_mbox_to_mgmt()` calls
`send_mbox_msg()` without any lock. Concurrently,
`hinic3_send_mbox_to_mgmt()` or `hinic3_send_mbox_to_mgmt_no_ack()`
can also call `send_mbox_msg()`. Both paths access the shared hardware
mailbox area (`mbox->send_mbox`), including MMIO writes, DMA writeback
status, and hardware control registers. Without the new lock,
interleaved access corrupts mailbox state.
- Record: Race condition on shared hardware mailbox resources between
response and send paths.
### Step 2.4: Fix Quality
- The fix is obviously correct: adds a mutex around a shared critical
section.
- The lock hierarchy is documented: `mbox_send_lock ->
mbox_seg_send_lock`.
- No deadlock risk: `mbox_seg_send_lock` is always the innermost lock.
- The FIELD_PREP→FIELD_GET change is a no-op for 0xFF mask but adds
clutter.
- Record: Fix is correct, minimal, well-documented hierarchy. Low
regression risk.
## PHASE 3: GIT HISTORY
### Step 3.1: Blame
- All of `send_mbox_msg()` and the macros were introduced by commit
`a8255ea56aee9` (Fan Gong, 2025-08-20) "hinic3: Mailbox management
interfaces".
- `hinic3_response_mbox_to_mgmt()` was introduced by `a30cc9b277903`
(Fan Gong, 2026-01-14) "hinic3: Add PF management interfaces".
- The race has existed since PF management was added (a30cc9b), which
first introduced the unprotected call path from a workqueue.
- Record: Bug introduced in a30cc9b277903 (v6.19 timeframe), present in
7.0 tree.
### Step 3.2: Fixes Tag
- No Fixes: tag present. Expected for this review pipeline.
### Step 3.3: File History
- hinic3 is a very new driver, first appearing in v6.16-rc1.
- The mbox code has been stable since initial introduction, with only
minor style fixes.
- Record: Standalone fix, no prerequisites needed beyond existing code.
### Step 3.4: Author
- Fan Gong is the primary hinic3 driver developer with 10+ commits.
- Record: Author is the driver developer/maintainer.
### Step 3.5: Dependencies
- This patch is self-contained. It adds a new mutex field and uses it.
No other patches needed.
- Record: No dependencies. Applies standalone.
## PHASE 4: MAILING LIST
### Step 4.1-4.5
- b4 dig could not find this specific commit (it may not be in the
current tree yet since it's a candidate).
- The original mailbox commit series was found via b4 dig for the parent
commit.
- lore.kernel.org was blocked by bot protection during fetch.
- The patch was accepted by Paolo Abeni (net maintainer), giving it
strong review credibility.
- Record: Accepted by net maintainer. Could not fetch full lore
discussion due to access restrictions.
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1-5.4: Function Analysis
- `send_mbox_msg()` is called from 3 places (confirmed by grep):
1. `hinic3_send_mbox_to_mgmt()` (line 815) - holds `mbox_send_lock`
2. `hinic3_response_mbox_to_mgmt()` (line 873) - NO lock held
3. `hinic3_send_mbox_to_mgmt_no_ack()` (line 886) - holds
`mbox_send_lock`
- `hinic3_response_mbox_to_mgmt()` is called from
`hinic3_recv_mgmt_msg_work_handler()` in a workqueue, triggered by
incoming management messages from firmware.
- `hinic3_send_mbox_to_mgmt()` is called from many places: RSS config,
NIC config, EQ setup, HW comm, command queue — any management
operation.
- The race is easily triggerable: if the driver receives a management
message while simultaneously sending one (very common scenario during
initialization or config changes).
- Record: Race is reachable from normal driver operation paths.
### Step 5.5: Similar Patterns
- The older hinic driver (drivers/net/ethernet/huawei/hinic/) uses
similar mbox locking patterns.
- Record: Pattern is common in Huawei NIC drivers.
## PHASE 6: STABLE TREE ANALYSIS
### Step 6.1: Code in Stable Trees
- hinic3 was introduced in v6.16-rc1. This commit is for v7.0 stable.
- The buggy code exists in the 7.0 tree (confirmed by reading the
files).
- The driver does NOT exist in older stable trees (6.12.y, 6.6.y, etc.).
- Record: Code exists only in 7.0 stable tree.
### Step 6.2: Backport Complications
- The patch should apply cleanly to 7.0 — the files haven't changed
significantly.
- Record: Clean apply expected.
### Step 6.3: Related Fixes
- No related fixes for this issue already in stable.
- Record: No existing related fixes.
## PHASE 7: SUBSYSTEM CONTEXT
### Step 7.1: Subsystem Criticality
- drivers/net/ethernet/ — network driver, IMPORTANT level
- hinic3 is a Huawei enterprise NIC driver (used in Huawei server
platforms)
- Record: [Network driver] [IMPORTANT — enterprise NIC used in Huawei
servers]
### Step 7.2: Subsystem Activity
- Very active — new driver still being built out with many patches.
- Record: Highly active.
## PHASE 8: IMPACT AND RISK
### Step 8.1: Affected Users
- Users of Huawei hinic3 NICs (enterprise/datacenter environments).
- Record: Driver-specific but enterprise users.
### Step 8.2: Trigger Conditions
- Triggered when a management response from the workqueue coincides with
a management send. This is realistic during driver initialization,
configuration changes, or firmware events.
- Record: Realistic trigger during normal NIC operation.
### Step 8.3: Failure Mode
- Corrupted mailbox messages → firmware communication failure → garbled
responses, timeouts, potential driver malfunction.
- Severity: HIGH (hardware communication failure, potential driver
instability)
- Record: Hardware mailbox corruption, driver instability. Severity
HIGH.
### Step 8.4: Risk-Benefit
- **Benefit:** Fixes a real race condition in hardware resource access.
Prevents mailbox corruption. HIGH.
- **Risk:** ~8 lines, adds a well-understood mutex. VERY LOW.
- Record: Excellent risk-benefit ratio.
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: Evidence Summary
**FOR backporting:**
- Fixes a real race condition in concurrent access to shared hardware
mailbox resources
- Small, surgical fix (~8 lines of real change)
- Self-contained, no dependencies
- Author is the driver developer, patch accepted by net maintainer
- Code exists in 7.0 stable tree
- Clean apply expected
- Race is triggerable under normal operation (workqueue response vs.
user send)
**AGAINST backporting:**
- No Fixes: tag, no Reported-by: (found by code inspection, not user
report)
- Bundles a cosmetic change (FIELD_PREP→FIELD_GET) with the race fix
- Very new driver (first in 6.16), limited user base
- The FIELD_PREP→FIELD_GET change is functionally a no-op for mask 0xFF
### Step 9.2: Stable Rules Checklist
1. Obviously correct and tested? **YES** — standard mutex addition,
accepted by maintainer
2. Fixes real bug? **YES** — race condition in hardware resource access
3. Important issue? **YES** — can cause driver/firmware communication
failure
4. Small and contained? **YES** — ~8 lines, 2 files in same driver
5. No new features? **Correct** — no new features
6. Applies to stable? **YES** — should apply cleanly to 7.0
### Step 9.3: Exception Categories
- Not an exception category; this is a standard race condition fix.
### Verification
- [Phase 1] Parsed commit message: race condition described for
`send_mbox_msg()` concurrent access
- [Phase 2] Diff: mutex_init + lock/unlock in `send_mbox_msg()`,
FIELD_PREP→FIELD_GET (no-op for 0xFF)
- [Phase 3] git blame: `send_mbox_msg()` from a8255ea56aee9
(2025-08-20), response caller from a30cc9b277903 (2026-01-14)
- [Phase 3] git describe: hinic3 first in v6.16-rc1, present in v7.0
- [Phase 4] b4 dig: could not find this specific commit in local repo
(candidate not yet applied)
- [Phase 4] Lore fetch blocked by bot protection
- [Phase 5] grep confirmed 3 callers of `send_mbox_msg()`, only response
path is unprotected
- [Phase 5] Confirmed `hinic3_response_mbox_to_mgmt()` called from
workqueue handler (`hinic3_recv_mgmt_msg_work_handler`)
- [Phase 5] Confirmed shared resources: `mbox->send_mbox` (MMIO data
area), writeback status, HW registers
- [Phase 6] Code exists in 7.0 tree, confirmed by reading files
- [Phase 8] Race is triggerable during normal NIC operation when mgmt
response and send overlap
- UNVERIFIED: Could not read full mailing list discussion due to lore
access restriction
The fix addresses a genuine race condition where concurrent calls to
`send_mbox_msg()` from an unprotected response path and a locked send
path can corrupt shared hardware mailbox resources. The fix is small,
surgical, obviously correct, and self-contained. The bundled
FIELD_PREP→FIELD_GET change is a no-op for the specific mask value (0xFF
at bit position 0) and adds no risk.
**YES**
drivers/net/ethernet/huawei/hinic3/hinic3_mbox.c | 9 +++++++--
drivers/net/ethernet/huawei/hinic3/hinic3_mbox.h | 4 ++++
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mbox.c b/drivers/net/ethernet/huawei/hinic3/hinic3_mbox.c
index 826fa8879a113..65528b2a7b7c8 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mbox.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mbox.c
@@ -50,9 +50,9 @@
#define MBOX_WB_STATUS_NOT_FINISHED 0x00
#define MBOX_STATUS_FINISHED(wb) \
- ((FIELD_PREP(MBOX_WB_STATUS_MASK, (wb))) != MBOX_WB_STATUS_NOT_FINISHED)
+ ((FIELD_GET(MBOX_WB_STATUS_MASK, (wb))) != MBOX_WB_STATUS_NOT_FINISHED)
#define MBOX_STATUS_SUCCESS(wb) \
- ((FIELD_PREP(MBOX_WB_STATUS_MASK, (wb))) == \
+ ((FIELD_GET(MBOX_WB_STATUS_MASK, (wb))) == \
MBOX_WB_STATUS_FINISHED_SUCCESS)
#define MBOX_STATUS_ERRCODE(wb) \
((wb) & MBOX_WB_ERROR_CODE_MASK)
@@ -395,6 +395,7 @@ static int hinic3_mbox_pre_init(struct hinic3_hwdev *hwdev,
{
mbox->hwdev = hwdev;
mutex_init(&mbox->mbox_send_lock);
+ mutex_init(&mbox->mbox_seg_send_lock);
spin_lock_init(&mbox->mbox_lock);
mbox->workq = create_singlethread_workqueue(HINIC3_MBOX_WQ_NAME);
@@ -706,6 +707,8 @@ static int send_mbox_msg(struct hinic3_mbox *mbox, u8 mod, u16 cmd,
else
rsp_aeq_id = 0;
+ mutex_lock(&mbox->mbox_seg_send_lock);
+
if (dst_func == MBOX_MGMT_FUNC_ID &&
!(hwdev->features[0] & MBOX_COMM_F_MBOX_SEGMENT)) {
err = mbox_prepare_dma_msg(mbox, ack_type, &dma_msg,
@@ -759,6 +762,8 @@ static int send_mbox_msg(struct hinic3_mbox *mbox, u8 mod, u16 cmd,
}
err_send:
+ mutex_unlock(&mbox->mbox_seg_send_lock);
+
return err;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mbox.h b/drivers/net/ethernet/huawei/hinic3/hinic3_mbox.h
index e26f22d1d5641..30de0c1295038 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mbox.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mbox.h
@@ -114,6 +114,10 @@ struct hinic3_mbox {
struct hinic3_hwdev *hwdev;
/* lock for send mbox message and ack message */
struct mutex mbox_send_lock;
+ /* lock for send message transmission.
+ * The lock hierarchy is mbox_send_lock -> mbox_seg_send_lock.
+ */
+ struct mutex mbox_seg_send_lock;
struct hinic3_send_mbox send_mbox;
struct mbox_dma_queue sync_msg_queue;
struct mbox_dma_queue async_msg_queue;
--
2.53.0
^ permalink raw reply related
* [PATCH AUTOSEL 6.18] netfilter: ctnetlink: ensure safe access to master conntrack
From: Sasha Levin @ 2026-04-20 13:21 UTC (permalink / raw)
To: patches, stable
Cc: Pablo Neira Ayuso, Florian Westphal, Sasha Levin, davem, edumazet,
kuba, pabeni, netfilter-devel, coreteam, netdev, linux-kernel
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>
From: Pablo Neira Ayuso <pablo@netfilter.org>
[ Upstream commit bffcaad9afdfe45d7fc777397d3b83c1e3ebffe5 ]
Holding reference on the expectation is not sufficient, the master
conntrack object can just go away, making exp->master invalid.
To access exp->master safely:
- Grab the nf_conntrack_expect_lock, this gets serialized with
clean_from_lists() which also holds this lock when the master
conntrack goes away.
- Hold reference on master conntrack via nf_conntrack_find_get().
Not so easy since the master tuple to look up for the master conntrack
is not available in the existing problematic paths.
This patch goes for extending the nf_conntrack_expect_lock section
to address this issue for simplicity, in the cases that are described
below this is just slightly extending the lock section.
The add expectation command already holds a reference to the master
conntrack from ctnetlink_create_expect().
However, the delete expectation command needs to grab the spinlock
before looking up for the expectation. Expand the existing spinlock
section to address this to cover the expectation lookup. Note that,
the nf_ct_expect_iterate_net() calls already grabs the spinlock while
iterating over the expectation table, which is correct.
The get expectation command needs to grab the spinlock to ensure master
conntrack does not go away. This also expands the existing spinlock
section to cover the expectation lookup too. I needed to move the
netlink skb allocation out of the spinlock to keep it GFP_KERNEL.
For the expectation events, the IPEXP_DESTROY event is already delivered
under the spinlock, just move the delivery of IPEXP_NEW under the
spinlock too because the master conntrack event cache is reached through
exp->master.
While at it, add lockdep notations to help identify what codepaths need
to grab the spinlock.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Error: Failed to generate final synthesis
include/net/netfilter/nf_conntrack_core.h | 5 ++++
net/netfilter/nf_conntrack_ecache.c | 2 ++
net/netfilter/nf_conntrack_expect.c | 10 +++++++-
net/netfilter/nf_conntrack_netlink.c | 28 +++++++++++++++--------
4 files changed, 35 insertions(+), 10 deletions(-)
diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
index 3384859a89210..8883575adcc1e 100644
--- a/include/net/netfilter/nf_conntrack_core.h
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -83,6 +83,11 @@ void nf_conntrack_lock(spinlock_t *lock);
extern spinlock_t nf_conntrack_expect_lock;
+static inline void lockdep_nfct_expect_lock_held(void)
+{
+ lockdep_assert_held(&nf_conntrack_expect_lock);
+}
+
/* ctnetlink code shared by both ctnetlink and nf_conntrack_bpf */
static inline void __nf_ct_set_timeout(struct nf_conn *ct, u64 timeout)
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c
index 81baf20826046..9df159448b897 100644
--- a/net/netfilter/nf_conntrack_ecache.c
+++ b/net/netfilter/nf_conntrack_ecache.c
@@ -247,6 +247,8 @@ void nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
struct nf_ct_event_notifier *notify;
struct nf_conntrack_ecache *e;
+ lockdep_nfct_expect_lock_held();
+
rcu_read_lock();
notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
if (!notify)
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 2234c444a320e..24d0576d84b7f 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -51,6 +51,7 @@ void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp,
struct net *net = nf_ct_exp_net(exp);
struct nf_conntrack_net *cnet;
+ lockdep_nfct_expect_lock_held();
WARN_ON(!master_help);
WARN_ON(timer_pending(&exp->timeout));
@@ -118,6 +119,8 @@ nf_ct_exp_equal(const struct nf_conntrack_tuple *tuple,
bool nf_ct_remove_expect(struct nf_conntrack_expect *exp)
{
+ lockdep_nfct_expect_lock_held();
+
if (timer_delete(&exp->timeout)) {
nf_ct_unlink_expect(exp);
nf_ct_expect_put(exp);
@@ -177,6 +180,8 @@ nf_ct_find_expectation(struct net *net,
struct nf_conntrack_expect *i, *exp = NULL;
unsigned int h;
+ lockdep_nfct_expect_lock_held();
+
if (!cnet->expect_count)
return NULL;
@@ -459,6 +464,8 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect,
unsigned int h;
int ret = 0;
+ lockdep_nfct_expect_lock_held();
+
if (!master_help) {
ret = -ESHUTDOWN;
goto out;
@@ -515,8 +522,9 @@ int nf_ct_expect_related_report(struct nf_conntrack_expect *expect,
nf_ct_expect_insert(expect);
- spin_unlock_bh(&nf_conntrack_expect_lock);
nf_ct_expect_event_report(IPEXP_NEW, expect, portid, report);
+ spin_unlock_bh(&nf_conntrack_expect_lock);
+
return 0;
out:
spin_unlock_bh(&nf_conntrack_expect_lock);
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 879413b9fa06a..becffc15e7579 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -3337,31 +3337,37 @@ static int ctnetlink_get_expect(struct sk_buff *skb,
if (err < 0)
return err;
+ skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!skb2)
+ return -ENOMEM;
+
+ spin_lock_bh(&nf_conntrack_expect_lock);
exp = nf_ct_expect_find_get(info->net, &zone, &tuple);
- if (!exp)
+ if (!exp) {
+ spin_unlock_bh(&nf_conntrack_expect_lock);
+ kfree_skb(skb2);
return -ENOENT;
+ }
if (cda[CTA_EXPECT_ID]) {
__be32 id = nla_get_be32(cda[CTA_EXPECT_ID]);
if (id != nf_expect_get_id(exp)) {
nf_ct_expect_put(exp);
+ spin_unlock_bh(&nf_conntrack_expect_lock);
+ kfree_skb(skb2);
return -ENOENT;
}
}
- skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
- if (!skb2) {
- nf_ct_expect_put(exp);
- return -ENOMEM;
- }
-
rcu_read_lock();
err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).portid,
info->nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW,
exp);
rcu_read_unlock();
nf_ct_expect_put(exp);
+ spin_unlock_bh(&nf_conntrack_expect_lock);
+
if (err <= 0) {
kfree_skb(skb2);
return -ENOMEM;
@@ -3408,22 +3414,26 @@ static int ctnetlink_del_expect(struct sk_buff *skb,
if (err < 0)
return err;
+ spin_lock_bh(&nf_conntrack_expect_lock);
+
/* bump usage count to 2 */
exp = nf_ct_expect_find_get(info->net, &zone, &tuple);
- if (!exp)
+ if (!exp) {
+ spin_unlock_bh(&nf_conntrack_expect_lock);
return -ENOENT;
+ }
if (cda[CTA_EXPECT_ID]) {
__be32 id = nla_get_be32(cda[CTA_EXPECT_ID]);
if (id != nf_expect_get_id(exp)) {
nf_ct_expect_put(exp);
+ spin_unlock_bh(&nf_conntrack_expect_lock);
return -ENOENT;
}
}
/* after list removal, usage count == 1 */
- spin_lock_bh(&nf_conntrack_expect_lock);
if (timer_delete(&exp->timeout)) {
nf_ct_unlink_expect_report(exp, NETLINK_CB(skb).portid,
nlmsg_report(info->nlh));
--
2.53.0
^ permalink raw reply related
* [PATCH AUTOSEL 7.0-5.10] net: hamradio: bpqether: validate frame length in bpq_rcv()
From: Sasha Levin @ 2026-04-20 13:21 UTC (permalink / raw)
To: patches, stable
Cc: Mashiro Chen, Joerg Reuter, Jakub Kicinski, Sasha Levin,
andrew+netdev, davem, edumazet, pabeni, netdev, linux-kernel
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>
From: Mashiro Chen <mashiro.chen@mailbox.org>
[ Upstream commit 6183bd8723a3eecd2d89cbc506fe938bc6288345 ]
The BPQ length field is decoded as:
len = skb->data[0] + skb->data[1] * 256 - 5;
If the sender sets bytes [0..1] to values whose combined value is
less than 5, len becomes negative. Passing a negative int to
skb_trim() silently converts to a huge unsigned value, causing the
function to be a no-op. The frame is then passed up to AX.25 with
its original (untrimmed) payload, delivering garbage beyond the
declared frame boundary.
Additionally, a negative len corrupts the 64-bit rx_bytes counter
through implicit sign-extension.
Add a bounds check before pulling the length bytes: reject frames
where len is negative or exceeds the remaining skb data.
Acked-by: Joerg Reuter <jreuter@yaina.de>
Signed-off-by: Mashiro Chen <mashiro.chen@mailbox.org>
Link: https://patch.msgid.link/20260409024927.24397-2-mashiro.chen@mailbox.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Now I have all the information I need. Let me compile the complete
analysis.
---
## PHASE 1: COMMIT MESSAGE FORENSICS
**Step 1.1: Subject Line**
- Subsystem: `net: hamradio: bpqether`
- Action verb: "validate" — implies adding a missing safety check (a bug
fix)
- Summary: Add bounds checking to the frame length parsing in
`bpq_rcv()`
Record: [net/hamradio/bpqether] [validate] [Add missing frame length
bounds check in receive path]
**Step 1.2: Tags**
- `Acked-by: Joerg Reuter <jreuter@yaina.de>` — Joerg Reuter IS the
hamradio subsystem maintainer (confirmed from MODULE_AUTHOR)
- `Signed-off-by: Mashiro Chen <mashiro.chen@mailbox.org>` — patch
author
- `Link: https://patch.msgid.link/20260409024927.24397-2-
mashiro.chen@mailbox.org` — lore reference
- `Signed-off-by: Jakub Kicinski <kuba@kernel.org>` — netdev maintainer
applied it
- IMPORTANT: The original submission (from the mbox) includes `Cc:
stable@vger.kernel.org` which was stripped during merge
Record: Acked by subsystem maintainer. Originally Cc'd to stable.
Applied by netdev maintainer.
**Step 1.3: Commit Body**
The bug mechanism is clearly described:
- `len = skb->data[0] + skb->data[1] * 256 - 5` can produce a negative
value if bytes [0..1] sum to < 5
- Passing negative `int` to `skb_trim(unsigned int)` produces a huge
unsigned value, making it a no-op
- Frame is delivered to AX.25 with untrimmed garbage payload
- Negative `len` also corrupts the 64-bit `rx_bytes` counter via
implicit sign-extension
Record: Bug is clearly described with specific mechanism. Two distinct
problems: garbage data delivery and stats corruption.
**Step 1.4: Hidden Bug Fix**
This is explicitly a validation/bug fix — "validate" means adding a
missing safety check.
Record: Not hidden — explicitly a bug fix adding missing input
validation.
## PHASE 2: DIFF ANALYSIS
**Step 2.1: Inventory**
- 1 file modified: `drivers/net/hamradio/bpqether.c`
- +3 lines added, 0 removed
- Function modified: `bpq_rcv()`
- Scope: single-file surgical fix
Record: [1 file, +3 lines, bpq_rcv()] [Minimal single-file fix]
**Step 2.2: Code Flow Change**
The single hunk inserts a bounds check after the length calculation:
```190:192:drivers/net/hamradio/bpqether.c
if (len < 0 || len > skb->len - 2)
goto drop_unlock;
```
- BEFORE: `len` is calculated and used unconditionally — negative `len`
passes through
- AFTER: Negative or oversized `len` causes the frame to be dropped
- This is on the data receive path (normal path for incoming frames)
Record: [Before: no validation on computed len → After: reject frames
with invalid len]
**Step 2.3: Bug Mechanism**
Category: **Logic/correctness fix + type conversion bug**
- `len` is `int` (line 152), computed from untrusted network data
- `skb_trim()` takes `unsigned int len` (confirmed from header: `void
skb_trim(struct sk_buff *skb, unsigned int len)`)
- Negative `int` → huge `unsigned int` → `skb->len > len` is false → no
trimming occurs
- `dev->stats.rx_bytes += len` with negative `len` corrupts stats via
sign extension to 64-bit
The fix also checks `len > skb->len - 2` to reject frames claiming more
data than present (the `-2` accounts for the 2 length bytes about to be
pulled).
Record: [Type conversion bug causing no-op trim + stats corruption. Fix
adds proper bounds check.]
**Step 2.4: Fix Quality**
- Obviously correct: a bounds check of `len < 0 || len > skb->len - 2`
before using `len`
- Minimal/surgical: 3 lines in one location
- No regression risk: rejecting invalid frames cannot harm valid
operation
- Uses existing `drop_unlock` error path (already well-tested)
Record: [Clearly correct, minimal, no regression risk]
## PHASE 3: GIT HISTORY
**Step 3.1: Blame**
The buggy line (`len = skb->data[0] + skb->data[1] * 256 - 5`) dates to
commit `1da177e4c3f41` — Linus Torvalds' initial Linux import
(2005-04-16). This code has been present in every Linux version ever
released.
Record: [Bug present since initial Linux git commit — affects ALL stable
trees]
**Step 3.2: Fixes Tag**
No explicit `Fixes:` tag. The buggy code predates git history.
Record: [N/A — bug predates git history, all stable trees affected]
**Step 3.3: File History**
Recent changes to `bpqether.c` are all unrelated refactoring (lockdep,
netdev_features, dev_addr_set). None touch the `bpq_rcv()` length
parsing logic. The function `bpq_rcv` hasn't been meaningfully modified
in its length handling since the initial commit.
Record: [No related changes or prerequisites. Standalone fix.]
**Step 3.4: Author**
Mashiro Chen appears to be a contributor fixing input validation issues
(this series fixes two hamradio drivers). The patch was Acked by Joerg
Reuter (subsystem maintainer) and applied by Jakub Kicinski (netdev
maintainer).
Record: [Contributor fix, but Acked by subsystem maintainer and applied
by netdev maintainer — high confidence]
**Step 3.5: Dependencies**
This is patch 1/2 in a series, but both patches are independent
(different files: `bpqether.c` vs `scc.c`). No dependencies.
Record: [Self-contained, no dependencies. Applies standalone.]
## PHASE 4: MAILING LIST RESEARCH
**Step 4.1: Original Discussion**
From the b4 am output, the thread at
`20260409024927.24397-1-mashiro.chen@mailbox.org` contains 5 messages.
This is v2; the change between v1 and v2 for bpqether was only "add
Acked-by: Joerg Reuter" (no code change).
Critical finding from the mbox: **The original patch included `Cc:
stable@vger.kernel.org`**, indicating the author explicitly nominated it
for stable. This tag was stripped during the merge process (common
netdev practice).
Record: [Original submission Cc'd to stable. v2 adds only Acked-by.
Acked by subsystem maintainer.]
**Step 4.2: Reviewers**
- Acked-by: Joerg Reuter (hamradio subsystem maintainer)
- Applied by: Jakub Kicinski (netdev co-maintainer)
- CC'd to linux-hams mailing list
Record: [Reviewed by the right people]
**Step 4.3-4.5: Bug Report / Stable Discussion**
No external bug report referenced. This appears to be found by code
inspection. The author explicitly Cc'd stable.
Record: [Found by code inspection, author nominated for stable]
## PHASE 5: CODE SEMANTIC ANALYSIS
**Step 5.1: Functions Modified**
Only `bpq_rcv()`.
**Step 5.2: Callers**
`bpq_rcv` is registered as a packet_type handler via
`bpq_packet_type.func = bpq_rcv` (line 93). It is called by the kernel
networking stack for every incoming BPQ ethernet frame (`ETH_P_BPQ`).
This is the main receive path for the driver.
Record: [Called by kernel network stack on every incoming BPQ frame]
**Step 5.3-5.4: Call Chain**
The receive path: network driver → netif_receive_skb → protocol dispatch
→ `bpq_rcv()` → ax25_type_trans → netif_rx.
Any BPQ frame arriving on the network can trigger this. No special
privileges needed to send a malformed Ethernet frame on a local network.
Record: [Reachable from any incoming network frame — attack surface for
local network]
**Step 5.5: Similar Patterns**
The second patch in the series fixes a similar input validation issue in
`scc.c`, suggesting systematic review of hamradio drivers.
Record: [Systematic validation audit by author]
## PHASE 6: CROSS-REFERENCING AND STABLE TREE ANALYSIS
**Step 6.1: Code Exists in Stable?**
Yes. The buggy code (line 188: `len = skb->data[0] + skb->data[1] * 256
- 5`) has been present since the initial commit and exists in ALL stable
trees. The changes since v5.4 and v6.1 to this file are all unrelated
refactoring that don't touch the `bpq_rcv()` length logic.
Record: [Bug exists in ALL stable trees from v5.4 through v7.0]
**Step 6.2: Backport Complications**
None. The surrounding code in `bpq_rcv()` is essentially unchanged. The
fix is a 3-line insertion with no context dependencies on recent
changes.
Record: [Clean apply expected to all stable trees]
**Step 6.3: Related Fixes Already in Stable**
No prior fix for this issue exists.
Record: [No prior fix]
## PHASE 7: SUBSYSTEM CONTEXT
**Step 7.1: Subsystem**
- Path: `drivers/net/hamradio/` — Amateur (ham) radio networking driver
- Criticality: PERIPHERAL (niche driver for ham radio enthusiasts)
- However: it processes network frames and the bug is a missing input
validation — security relevance
Record: [Peripheral subsystem, but network input validation issue gives
it security relevance]
**Step 7.2: Activity**
The file has had minimal changes. Mature, stable code that rarely gets
touched.
Record: [Very mature code — bug has been present for ~20 years]
## PHASE 8: IMPACT AND RISK ASSESSMENT
**Step 8.1: Who Is Affected**
Users of the BPQ (AX.25-over-Ethernet) hamradio protocol. While niche,
these are real users.
Record: [Driver-specific: ham radio BPQ users]
**Step 8.2: Trigger Conditions**
- Any malformed BPQ frame with length field < 5 triggers the bug
- Can be triggered by any device on the local Ethernet segment (no
privileges needed)
- Reliably reproducible — no race condition
Record: [Triggered by malformed network frame from local network,
reliably reproducible, no auth needed]
**Step 8.3: Failure Mode**
- Garbage data delivered to AX.25 protocol — potential info leak /
protocol confusion
- Stats counter corruption (rx_bytes goes wildly negative)
- Severity: MEDIUM-HIGH (garbage data delivery from network, potential
security implication)
Record: [Garbage data delivery + stats corruption. Severity: MEDIUM-
HIGH]
**Step 8.4: Risk-Benefit**
- BENEFIT: Prevents garbage data delivery and counter corruption from
malformed frames. Has been broken for 20 years.
- RISK: Extremely low. 3-line bounds check using existing `drop_unlock`
path. Obviously correct.
Record: [High benefit, very low risk. Excellent ratio.]
## PHASE 9: FINAL SYNTHESIS
**Step 9.1: Evidence Compilation**
FOR backporting:
- Fixes a real input validation bug present since the initial Linux
commit
- 3-line surgical fix — minimal risk
- Obviously correct bounds check
- Acked by subsystem maintainer (Joerg Reuter)
- Applied by netdev co-maintainer (Jakub Kicinski)
- Author explicitly Cc'd stable@vger.kernel.org in original submission
- Prevents garbage data delivery to AX.25 from malformed frames
- Prevents stats counter corruption
- Will apply cleanly to all stable trees
- No dependencies, self-contained
AGAINST backporting:
- Niche driver (ham radio) — limited user base
- No crash/panic, "only" garbage data and stats corruption
**Step 9.2: Stable Rules Checklist**
1. Obviously correct and tested? **YES** — trivial bounds check, Acked
by maintainer
2. Fixes a real bug? **YES** — garbage data delivery + counter
corruption
3. Important issue? **YES** — input validation on network data
(security-adjacent)
4. Small and contained? **YES** — 3 lines, 1 file
5. No new features/APIs? **YES** — pure bug fix
6. Applies to stable? **YES** — code unchanged since initial commit
**Step 9.3: Exception Categories**
Not an exception category — this is a standard bug fix.
**Step 9.4: Decision**
This is a textbook stable backport: small, obviously correct input
validation fix for network-facing code, Acked by subsystem maintainer,
explicitly nominated for stable by author, fixes a 20-year-old bug.
## Verification
- [Phase 1] Parsed tags: Acked-by Joerg Reuter, Link to
patch.msgid.link, SOB from Jakub Kicinski
- [Phase 2] Diff analysis: +3 lines adding bounds check in `bpq_rcv()`
before `skb_trim`/`skb_pull`
- [Phase 2] Confirmed `skb_trim()` takes `unsigned int len`
(include/linux/skbuff.h:3321)
- [Phase 3] git blame: buggy code from commit 1da177e4c3f41 (Linus
initial, 2005-04-16), present in all stable trees
- [Phase 3] git log: no recent changes touch the length handling in
bpq_rcv()
- [Phase 4] b4 am: found original thread, 5 messages, v2 series with 2
patches
- [Phase 4] Read mbox: original submission includes `Cc:
stable@vger.kernel.org` (line 28 of mbx)
- [Phase 4] Cover letter: v2 changes for bpqether are "no code change;
add Acked-by"
- [Phase 5] bpq_rcv registered as packet_type handler, called on every
incoming BPQ frame
- [Phase 6] Code exists in all active stable trees (v5.4+), no
divergence in affected lines
- [Phase 6] Clean apply expected — surrounding code unchanged
- [Phase 8] Failure mode: garbage data to AX.25 + counter corruption,
severity MEDIUM-HIGH
**YES**
drivers/net/hamradio/bpqether.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 045c5177262ea..214fd1f819a1b 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -187,6 +187,9 @@ static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ty
len = skb->data[0] + skb->data[1] * 256 - 5;
+ if (len < 0 || len > skb->len - 2)
+ goto drop_unlock;
+
skb_pull(skb, 2); /* Remove the length bytes */
skb_trim(skb, len); /* Set the length of the data */
--
2.53.0
^ permalink raw reply related
* [PATCH AUTOSEL 6.18] bridge: guard local VLAN-0 FDB helpers against NULL vlan group
From: Sasha Levin @ 2026-04-20 13:20 UTC (permalink / raw)
To: patches, stable
Cc: Zijing Yin, Ido Schimmel, Nikolay Aleksandrov, Jakub Kicinski,
Sasha Levin, davem, edumazet, pabeni, petrm, bridge, netdev,
linux-kernel
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>
From: Zijing Yin <yzjaurora@gmail.com>
[ Upstream commit 1979645e1842cb7017525a61a0e0e0beb924d02a ]
When CONFIG_BRIDGE_VLAN_FILTERING is not set, br_vlan_group() and
nbp_vlan_group() return NULL (br_private.h stub definitions). The
BR_BOOLOPT_FDB_LOCAL_VLAN_0 toggle code is compiled unconditionally and
reaches br_fdb_delete_locals_per_vlan_port() and
br_fdb_insert_locals_per_vlan_port(), where the NULL vlan group pointer
is dereferenced via list_for_each_entry(v, &vg->vlan_list, vlist).
The observed crash is in the delete path, triggered when creating a
bridge with IFLA_BR_MULTI_BOOLOPT containing BR_BOOLOPT_FDB_LOCAL_VLAN_0
via RTM_NEWLINK. The insert helper has the same bug pattern.
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000056: 0000 [#1] KASAN NOPTI
KASAN: null-ptr-deref in range [0x00000000000002b0-0x00000000000002b7]
RIP: 0010:br_fdb_delete_locals_per_vlan+0x2b9/0x310
Call Trace:
br_fdb_toggle_local_vlan_0+0x452/0x4c0
br_toggle_fdb_local_vlan_0+0x31/0x80 net/bridge/br.c:276
br_boolopt_toggle net/bridge/br.c:313
br_boolopt_multi_toggle net/bridge/br.c:364
br_changelink net/bridge/br_netlink.c:1542
br_dev_newlink net/bridge/br_netlink.c:1575
Add NULL checks for the vlan group pointer in both helpers, returning
early when there are no VLANs to iterate. This matches the existing
pattern used by other bridge FDB functions such as br_fdb_add() and
br_fdb_delete().
Fixes: 21446c06b441 ("net: bridge: Introduce UAPI for BR_BOOLOPT_FDB_LOCAL_VLAN_0")
Signed-off-by: Zijing Yin <yzjaurora@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/20260402140153.3925663-1-yzjaurora@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Error: Failed to generate final synthesis
net/bridge/br_fdb.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index 0501ffcb8a3dd..e2c17f620f009 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -597,6 +597,9 @@ static void br_fdb_delete_locals_per_vlan_port(struct net_bridge *br,
dev = br->dev;
}
+ if (!vg)
+ return;
+
list_for_each_entry(v, &vg->vlan_list, vlist)
br_fdb_find_delete_local(br, p, dev->dev_addr, v->vid);
}
@@ -630,6 +633,9 @@ static int br_fdb_insert_locals_per_vlan_port(struct net_bridge *br,
dev = br->dev;
}
+ if (!vg)
+ return 0;
+
list_for_each_entry(v, &vg->vlan_list, vlist) {
if (!br_vlan_should_use(v))
continue;
--
2.53.0
^ permalink raw reply related
* [PATCH AUTOSEL 6.18] netfilter: nft_set_pipapo_avx2: don't return non-matching entry on expiry
From: Sasha Levin @ 2026-04-20 13:20 UTC (permalink / raw)
To: patches, stable
Cc: Florian Westphal, Stefano Brivio, Pablo Neira Ayuso, Sasha Levin,
davem, edumazet, kuba, pabeni, netfilter-devel, coreteam, netdev,
linux-kernel
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>
From: Florian Westphal <fw@strlen.de>
[ Upstream commit d3c0037ffe1273fa1961e779ff6906234d6cf53c ]
New test case fails unexpectedly when avx2 matching functions are used.
The test first loads a ranomly generated pipapo set
with 'ipv4 . port' key, i.e. nft -f foo.
This works. Then, it reloads the set after a flush:
(echo flush set t s; cat foo) | nft -f -
This is expected to work, because its the same set after all and it was
already loaded once.
But with avx2, this fails: nft reports a clashing element.
The reported clash is of following form:
We successfully re-inserted
a . b
c . d
Then we try to insert a . d
avx2 finds the already existing a . d, which (due to 'flush set') is marked
as invalid in the new generation. It skips the element and moves to next.
Due to incorrect masking, the skip-step finds the next matching
element *only considering the first field*,
i.e. we return the already reinserted "a . b", even though the
last field is different and the entry should not have been matched.
No such error is reported for the generic c implementation (no avx2) or when
the last field has to use the 'nft_pipapo_avx2_lookup_slow' fallback.
Bisection points to
7711f4bb4b36 ("netfilter: nft_set_pipapo: fix range overlap detection")
but that fix merely uncovers this bug.
Before this commit, the wrong element is returned, but erronously
reported as a full, identical duplicate.
The root-cause is too early return in the avx2 match functions.
When we process the last field, we should continue to process data
until the entire input size has been consumed to make sure no stale
bits remain in the map.
Link: https://lore.kernel.org/netfilter-devel/20260321152506.037f68c0@elisabeth/
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Error: Failed to generate final synthesis
net/netfilter/nft_set_pipapo_avx2.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/net/netfilter/nft_set_pipapo_avx2.c b/net/netfilter/nft_set_pipapo_avx2.c
index 7ff90325c97fa..6395982e4d95c 100644
--- a/net/netfilter/nft_set_pipapo_avx2.c
+++ b/net/netfilter/nft_set_pipapo_avx2.c
@@ -242,7 +242,7 @@ static int nft_pipapo_avx2_lookup_4b_2(unsigned long *map, unsigned long *fill,
b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last);
if (last)
- return b;
+ ret = b;
if (unlikely(ret == -1))
ret = b / XSAVE_YMM_SIZE;
@@ -319,7 +319,7 @@ static int nft_pipapo_avx2_lookup_4b_4(unsigned long *map, unsigned long *fill,
b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last);
if (last)
- return b;
+ ret = b;
if (unlikely(ret == -1))
ret = b / XSAVE_YMM_SIZE;
@@ -414,7 +414,7 @@ static int nft_pipapo_avx2_lookup_4b_8(unsigned long *map, unsigned long *fill,
b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last);
if (last)
- return b;
+ ret = b;
if (unlikely(ret == -1))
ret = b / XSAVE_YMM_SIZE;
@@ -505,7 +505,7 @@ static int nft_pipapo_avx2_lookup_4b_12(unsigned long *map, unsigned long *fill,
b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last);
if (last)
- return b;
+ ret = b;
if (unlikely(ret == -1))
ret = b / XSAVE_YMM_SIZE;
@@ -641,7 +641,7 @@ static int nft_pipapo_avx2_lookup_4b_32(unsigned long *map, unsigned long *fill,
b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last);
if (last)
- return b;
+ ret = b;
if (unlikely(ret == -1))
ret = b / XSAVE_YMM_SIZE;
@@ -699,7 +699,7 @@ static int nft_pipapo_avx2_lookup_8b_1(unsigned long *map, unsigned long *fill,
b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last);
if (last)
- return b;
+ ret = b;
if (unlikely(ret == -1))
ret = b / XSAVE_YMM_SIZE;
@@ -764,7 +764,7 @@ static int nft_pipapo_avx2_lookup_8b_2(unsigned long *map, unsigned long *fill,
b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last);
if (last)
- return b;
+ ret = b;
if (unlikely(ret == -1))
ret = b / XSAVE_YMM_SIZE;
@@ -839,7 +839,7 @@ static int nft_pipapo_avx2_lookup_8b_4(unsigned long *map, unsigned long *fill,
b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last);
if (last)
- return b;
+ ret = b;
if (unlikely(ret == -1))
ret = b / XSAVE_YMM_SIZE;
@@ -925,7 +925,7 @@ static int nft_pipapo_avx2_lookup_8b_6(unsigned long *map, unsigned long *fill,
b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last);
if (last)
- return b;
+ ret = b;
if (unlikely(ret == -1))
ret = b / XSAVE_YMM_SIZE;
@@ -1019,7 +1019,7 @@ static int nft_pipapo_avx2_lookup_8b_16(unsigned long *map, unsigned long *fill,
b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last);
if (last)
- return b;
+ ret = b;
if (unlikely(ret == -1))
ret = b / XSAVE_YMM_SIZE;
--
2.53.0
^ permalink raw reply related
* [PATCH AUTOSEL 6.18] xfrm: account XFRMA_IF_ID in aevent size calculation
From: Sasha Levin @ 2026-04-20 13:20 UTC (permalink / raw)
To: patches, stable
Cc: Keenan Dong, Steffen Klassert, Sasha Levin, davem, edumazet, kuba,
pabeni, sln, eyal.birger, benedictwong, netdev, linux-kernel
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>
From: Keenan Dong <keenanat2000@gmail.com>
[ Upstream commit 7081d46d32312f1a31f0e0e99c6835a394037599 ]
xfrm_get_ae() allocates the reply skb with xfrm_aevent_msgsize(), then
build_aevent() appends attributes including XFRMA_IF_ID when x->if_id is
set.
xfrm_aevent_msgsize() does not include space for XFRMA_IF_ID. For states
with if_id, build_aevent() can fail with -EMSGSIZE and hit BUG_ON(err < 0)
in xfrm_get_ae(), turning a malformed netlink interaction into a kernel
panic.
Account XFRMA_IF_ID in the size calculation unconditionally and replace
the BUG_ON with normal error unwinding.
Fixes: 7e6526404ade ("xfrm: Add a new lookup key to match xfrm interfaces.")
Reported-by: Keenan Dong <keenanat2000@gmail.com>
Signed-off-by: Keenan Dong <keenanat2000@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Error: Failed to generate final synthesis
net/xfrm/xfrm_user.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 306e4f65ce264..1ddcf2a1eff7a 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2668,7 +2668,8 @@ static inline unsigned int xfrm_aevent_msgsize(struct xfrm_state *x)
+ nla_total_size(4) /* XFRM_AE_RTHR */
+ nla_total_size(4) /* XFRM_AE_ETHR */
+ nla_total_size(sizeof(x->dir)) /* XFRMA_SA_DIR */
- + nla_total_size(4); /* XFRMA_SA_PCPU */
+ + nla_total_size(4) /* XFRMA_SA_PCPU */
+ + nla_total_size(sizeof(x->if_id)); /* XFRMA_IF_ID */
}
static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, const struct km_event *c)
@@ -2780,7 +2781,12 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
c.portid = nlh->nlmsg_pid;
err = build_aevent(r_skb, x, &c);
- BUG_ON(err < 0);
+ if (err < 0) {
+ spin_unlock_bh(&x->lock);
+ xfrm_state_put(x);
+ kfree_skb(r_skb);
+ return err;
+ }
err = nlmsg_unicast(net->xfrm.nlsk, r_skb, NETLINK_CB(skb).portid);
spin_unlock_bh(&x->lock);
--
2.53.0
^ permalink raw reply related
* [PATCH AUTOSEL 7.0-5.10] net: hamradio: scc: validate bufsize in SIOCSCCSMEM ioctl
From: Sasha Levin @ 2026-04-20 13:20 UTC (permalink / raw)
To: patches, stable
Cc: Mashiro Chen, Joerg Reuter, Jakub Kicinski, Sasha Levin,
andrew+netdev, davem, edumazet, pabeni, linux-hams, netdev,
linux-kernel
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>
From: Mashiro Chen <mashiro.chen@mailbox.org>
[ Upstream commit 8263e484d6622464ec72a5ad563f62492d84fa54 ]
The SIOCSCCSMEM ioctl copies a scc_mem_config from user space and
assigns its bufsize field directly to scc->stat.bufsize without any
range validation:
scc->stat.bufsize = memcfg.bufsize;
If a privileged user (CAP_SYS_RAWIO) sets bufsize to 0, the receive
interrupt handler later calls dev_alloc_skb(0) and immediately writes
a KISS type byte via skb_put_u8() into a zero-capacity socket buffer,
corrupting the adjacent skb_shared_info region.
Reject bufsize values smaller than 16; this is large enough to hold
at least one KISS header byte plus useful data.
Signed-off-by: Mashiro Chen <mashiro.chen@mailbox.org>
Acked-by: Joerg Reuter <jreuter@yaina.de>
Link: https://patch.msgid.link/20260409024927.24397-3-mashiro.chen@mailbox.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
All the data is gathered. Let me compile the complete analysis.
---
## PHASE 1: COMMIT MESSAGE FORENSICS
**Step 1.1: Subject Line**
- Subsystem: `net: hamradio: scc`
- Action verb: "validate" — indicates adding missing input validation,
i.e., fixing missing bounds checking
- Summary: Add missing bounds check on `bufsize` parameter from
userspace ioctl
**Step 1.2: Tags**
- `Signed-off-by: Mashiro Chen` — patch author
- `Acked-by: Joerg Reuter <jreuter@yaina.de>` — this is the **original
driver author** (copyright holder since 1993, confirmed in file
header). Strong endorsement.
- `Link:` to patch.msgid.link — standard netdev submission
- `Signed-off-by: Jakub Kicinski` — netdev maintainer applied it. Strong
trust signal.
**Step 1.3: Commit Body**
- Bug: `SIOCSCCSMEM` ioctl copies `bufsize` from userspace without
validation
- Symptom: If `bufsize` is set to 0, `dev_alloc_skb(0)` creates a zero-
capacity skb, then `skb_put_u8()` writes past the buffer, corrupting
`skb_shared_info`
- This is a **memory corruption bug** triggered via ioctl (requires
CAP_SYS_RAWIO)
- Fix: reject `bufsize < 16`
**Step 1.4: Hidden Bug Fix?**
Not hidden — this is an explicit, well-described input validation bug
fix preventing memory corruption.
## PHASE 2: DIFF ANALYSIS
**Step 2.1: Inventory**
- 1 file changed: `drivers/net/hamradio/scc.c`
- 2 lines added, 0 lines removed
- Function: `scc_net_siocdevprivate()`
**Step 2.2: Code Flow**
- Before: `memcfg.bufsize` assigned directly to `scc->stat.bufsize`
after `copy_from_user`, no validation
- After: `memcfg.bufsize < 16` returns `-EINVAL` before assignment
**Step 2.3: Bug Mechanism**
Category: **Buffer overflow / out-of-bounds write**. Setting `bufsize=0`
causes `dev_alloc_skb(0)` in `scc_rxint()`, then `skb_put_u8()` writes 1
byte into a zero-capacity buffer, corrupting adjacent `skb_shared_info`.
**Step 2.4: Fix Quality**
- Obviously correct: 2-line bounds check before assignment
- Minimal and surgical — cannot introduce a regression
- No side effects, no locking changes, no API changes
## PHASE 3: GIT HISTORY INVESTIGATION
**Step 3.1: Blame**
The buggy code (line 1912: `scc->stat.bufsize = memcfg.bufsize`) traces
to `^1da177e4c3f41` (Linus Torvalds, 2005-04-16) — this is the initial
Linux git import. The bug has existed since the **very beginning of the
kernel source tree**.
**Step 3.2: Fixes tag**
No explicit `Fixes:` tag (expected — this is why it needs manual
review). The buggy code predates git history.
**Step 3.3: File history**
Changes since v6.6 are only treewide renames (`timer_container_of`,
`timer_delete_sync`, `irq_get_nr_irqs`). The SIOCSCCSMEM handler and
`scc_rxint()` are completely untouched.
**Step 3.5: Dependencies**
None. The fix is self-contained — a simple bounds check addition.
## PHASE 4: MAILING LIST
Lore is protected by anti-scraping measures and couldn't be fetched
directly. However:
- The patch was **Acked-by the original driver author** Joerg Reuter
- It was applied by **netdev maintainer Jakub Kicinski**
- It's patch 3 of a series (from message-id), but the fix is completely
standalone
## PHASE 5: CODE SEMANTIC ANALYSIS
**Step 5.1: Functions modified**
`scc_net_siocdevprivate()` — the ioctl handler
**Step 5.2: Consumer of `bufsize`**
`scc_rxint()` (line 535) uses `scc->stat.bufsize` as the argument to
`dev_alloc_skb()`. This is an **interrupt handler** — called on every
received character from the Z8530 chip. When `bufsize=0`:
1. `dev_alloc_skb(0)` succeeds (returns a valid skb with 0 data
capacity)
2. `skb_put_u8(skb, 0)` at line 546 writes 1 byte past the data area
into `skb_shared_info`
3. This is **memory corruption in interrupt context**
**Step 5.4: Reachability**
The ioctl requires `CAP_SYS_RAWIO`. The corruption path is: ioctl sets
bufsize → hardware interrupt fires → `scc_rxint()` → `dev_alloc_skb(0)`
→ `skb_put_u8` overflows.
## PHASE 6: STABLE TREE ANALYSIS
**Step 6.1: Code exists in all stable trees**
Verified: the identical vulnerable code exists in v5.15, v6.1, and v6.6.
The buggy code dates to the initial kernel.
**Step 6.2: Clean apply**
The surrounding code is identical in v6.1 and v6.6 (verified). The
2-line addition will apply cleanly to all active stable trees.
## PHASE 7: SUBSYSTEM CONTEXT
- Subsystem: `drivers/net/hamradio` — networking driver (ham radio
Z8530)
- Criticality: PERIPHERAL (niche hardware), but the bug is a **memory
corruption**, which elevates priority regardless of driver popularity
## PHASE 8: IMPACT AND RISK ASSESSMENT
**Step 8.1: Affected users** — Users of Z8530-based ham radio hardware
(niche, but real)
**Step 8.2: Trigger** — Requires `CAP_SYS_RAWIO` to set the bad bufsize
via ioctl, then hardware interrupt triggers corruption. Privileged user
action.
**Step 8.3: Severity** — **HIGH**: Memory corruption in interrupt
context. Corrupting `skb_shared_info` can lead to unpredictable behavior
including crashes, further memory corruption, or potential exploitation.
**Step 8.4: Risk-Benefit**
- Benefit: Prevents memory corruption from invalid ioctl input
- Risk: Near zero — 2 lines of obvious bounds checking
- Ratio: Excellent — trivial fix for a real memory corruption bug
## PHASE 9: FINAL SYNTHESIS
**Evidence FOR backporting:**
- Fixes real memory corruption (skb_shared_info overwrite in interrupt
context)
- Only 2 lines added — obviously correct bounds check
- Buggy code exists since initial kernel tree — affects ALL stable trees
- Patch applies cleanly to all stable trees (verified v5.15, v6.1, v6.6)
- Acked by original driver author (Joerg Reuter)
- Applied by netdev maintainer (Jakub Kicinski)
- No dependencies, fully self-contained
- Zero regression risk
**Evidence AGAINST backporting:**
- Requires CAP_SYS_RAWIO (privileged) to trigger
- Niche driver (ham radio hardware)
**Stable rules checklist:**
1. Obviously correct and tested? **YES** — trivial 2-line bounds check,
acked by driver author
2. Fixes a real bug? **YES** — memory corruption from unchecked
userspace input
3. Important issue? **YES** — memory corruption in interrupt context
4. Small and contained? **YES** — 2 lines in one file
5. No new features/APIs? **YES** — pure validation addition
6. Applies to stable? **YES** — verified identical code in all active
stable trees
## Verification
- [Phase 1] Parsed tags: Acked-by Joerg Reuter (driver author), SOB by
Jakub Kicinski (netdev maintainer)
- [Phase 2] Diff: 2 lines added to `scc_net_siocdevprivate()`, bounds
check on `memcfg.bufsize`
- [Phase 3] git blame: buggy code at line 1912 dates to `^1da177e4c3f41`
(initial git import, 2005), present in ALL stable trees
- [Phase 3] git log v6.1/v6.6/v5.15 -- scc.c: only treewide changes,
SIOCSCCSMEM handler untouched
- [Phase 5] Traced `scc->stat.bufsize` consumer: `scc_rxint()` line 535
calls `dev_alloc_skb(bufsize)`, line 546 `skb_put_u8` overflows when
bufsize=0
- [Phase 6] git show v6.1/v6.6/v5.15: SIOCSCCSMEM handler code is byte-
for-byte identical — clean apply confirmed
- [Phase 4] Lore unavailable due to anti-scraping protection — could not
verify discussion thread directly
- [Phase 8] Failure mode: memory corruption (skb_shared_info overwrite)
in interrupt context, severity HIGH
**YES**
drivers/net/hamradio/scc.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index ae5048efde686..8569db4a71401 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -1909,6 +1909,8 @@ static int scc_net_siocdevprivate(struct net_device *dev,
if (!capable(CAP_SYS_RAWIO)) return -EPERM;
if (!arg || copy_from_user(&memcfg, arg, sizeof(memcfg)))
return -EINVAL;
+ if (memcfg.bufsize < 16)
+ return -EINVAL;
scc->stat.bufsize = memcfg.bufsize;
return 0;
--
2.53.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox