* Re: [PATCH v3] net: fman: fix use-after-free on IRQF_SHARED handler after probe failure
From: Simon Horman @ 2026-06-26 16:23 UTC (permalink / raw)
To: 赵金明
Cc: Andrew Lunn, andrew+netdev, davem, edumazet, kuba, linux-kernel,
madalin.bucur, netdev, pabeni, sean.anderson
In-Reply-To: <A2160E1BFD1B78E6+202606261753007787241@uniontech.com>
On Fri, Jun 26, 2026 at 05:53:02PM +0800, 赵金明 wrote:
> Hi,
>
> The analysis is logically correct. Since fman is zero-initialized by
> kzalloc_obj(), both fman->cfg and fman->fpm_regs are NULL when
> devm_request_irq() registers the shared IRQ handler. The guard in
> fman_irq():
>
> if (!is_init_done(fman->cfg))
> return IRQ_NONE;
>
> does not protect against this case because is_init_done(NULL) returns
> true, so the handler would proceed to dereference the NULL
> fpm_regs pointer via ioread32be().
>
> However, this is a pre-existing issue unrelated to the UAF fix in this
> patch. The window is very short -- between devm_request_irq() and the
> completion of fman_init() -- and would require another device on the
> same shared IRQ line to fire an interrupt during that interval.
>
> If this should be addressed, I will send a separate patch for it.
> The current patch is focused solely on the post-IRQ-registration UAF
> on error paths.
>
> Please let me know if you would like me to handle this separately.
Thanks, I agree this can be handled separately.
^ permalink raw reply
* Re: [PATCH bpf-next v10 1/5] bpf: add bpf_icmp_send kfunc
From: Stanislav Fomichev @ 2026-06-26 16:18 UTC (permalink / raw)
To: Mahe Tardy
Cc: bpf, andrii, ast, daniel, john.fastabend, jordan, martin.lau,
yonghong.song, emil, netdev, edumazet, kuba, pabeni, davem, horms
In-Reply-To: <aj1b_z6h5xn42Hxe@gmail.com>
On 06/25, Mahe Tardy wrote:
> On Thu, Jun 25, 2026 at 09:24:59AM -0700, Stanislav Fomichev wrote:
> > On 06/25, Mahe Tardy wrote:
>
> [...]
>
> > > +__bpf_kfunc int bpf_icmp_send(struct __sk_buff *skb_ctx, int type, int code)
> > > +{
> > > + struct sk_buff *skb = (struct sk_buff *)skb_ctx;
> > > + struct sk_buff *nskb;
> > > + struct sock *sk;
> > > +
> > > + sk = skb_to_full_sk(skb);
> > > + if (sk && sk->sk_kern_sock &&
> > > + (sk->sk_protocol == IPPROTO_ICMP || sk->sk_protocol == IPPROTO_ICMPV6))
> > > + return -EBUSY;
> > > +
> > > + switch (skb->protocol) {
> > > +#if IS_ENABLED(CONFIG_INET)
> > > + case htons(ETH_P_IP): {
> > > + if (type != ICMP_DEST_UNREACH)
> > > + return -EOPNOTSUPP;
> > > + if (code < 0 || code > NR_ICMP_UNREACH ||
> > > + code == ICMP_FRAG_NEEDED) /* needs a valid next-hop MTU */
> > > + return -EINVAL;
> > > +
> > > + /* icmp_send expects skb_dst to be a real rtable. */
> > > + if (!skb_valid_dst(skb))
> > > + return -ENETUNREACH;
> > > +
> > > + nskb = skb_clone(skb, GFP_ATOMIC);
> > > + if (!nskb)
> > > + return -ENOMEM;
> > > +
> > > + memset(IPCB(nskb), 0, sizeof(*IPCB(nskb)));
> > > + icmp_send(nskb, type, code, 0);
> > > + consume_skb(nskb);
> > > + break;
> > > + }
> > > +#endif
> > > +#if IS_ENABLED(CONFIG_IPV6)
> > > + case htons(ETH_P_IPV6):
> > > + if (type != ICMPV6_DEST_UNREACH)
> > > + return -EOPNOTSUPP;
> > > + if (code < 0 || code > ICMPV6_REJECT_ROUTE)
> > > + return -EINVAL;
> >
> > [..]
> >
> > > + /* icmpv6_send may treat skb_dst as rt6_info. */
> > > + if (skb_metadata_dst(skb))
> > > + return -ENETUNREACH;
> >
> > A bit confused about this. Which part of icmpv6_send treats skb_dst as rt6_info?
> > (I see the original sashiko report about dst, but icmp6 seems to be not
> > requiring it)
>
> Yeah I was also a bit confused because this came out of nowhere as soon
> as I put the skb_valid_dst only on the IPv4 path (for different
> reasons), but there is actually a potential trace in which we have type
> confusion indeed:
>
> - icmp6_send() checks scoped source addresses and calls icmp6_iif() at net/ipv6/icmp.c:702
> - icmp6_iif() calls icmp6_dev() at net/ipv6/icmp.c:441
> - icmp6_dev() does skb_rt6_info(skb) for loopback/L3 master devices at net/ipv6/icmp.c:428
> - skb_rt6_info() casts any non-NULL dst to struct rt6_info at include/net/ip6_route.h:233
> - rt6->rt6i_idev is then dereferenced at net/ipv6/icmp.c:434
>
> When checking with pahole, we can find this on my local kernel:
>
> struct rt6_info {
> struct dst_entry dst; /* 0 136 */
> /* --- cacheline 2 boundary (128 bytes) was 8 bytes ago --- */
> struct fib6_info * from; /* 136 8 */
> int sernum; /* 144 4 */
> struct rt6key rt6i_dst; /* 148 20 */
> struct rt6key rt6i_src; /* 168 20 */
> struct in6_addr rt6i_gateway; /* 188 16 */
>
> /* XXX 4 bytes hole, try to pack */
>
> /* --- cacheline 3 boundary (192 bytes) was 16 bytes ago --- */
> struct inet6_dev * rt6i_idev; /* 208 8 */ <--- we dereference this
> u32 rt6i_flags; /* 216 4 */
> short unsigned int rt6i_nfheader_len; /* 220 2 */
>
> /* size: 224, cachelines: 4, members: 9 */
> /* sum members: 218, holes: 1, sum holes: 4 */
> /* padding: 2 */
> /* last cacheline: 32 bytes */
> };
>
> And the metadata_dst would look like this:
>
> struct metadata_dst {
> struct dst_entry dst; /* 0 136 */
> /* --- cacheline 2 boundary (128 bytes) was 8 bytes ago --- */
> enum metadata_type type; /* 136 4 */
>
> /* XXX 4 bytes hole, try to pack */
>
> union {
> struct ip_tunnel_info tun_info; /* 144 96 */
> struct hw_port_info port_info; /* 144 16 */
> struct macsec_info macsec_info; /* 144 8 */
> struct xfrm_md_info xfrm_info; /* 144 16 */
> } u; /* 144 96 */ <--- we land on this union
>
> /* size: 240, cachelines: 4, members: 3 */
> /* sum members: 236, holes: 1, sum holes: 4 */
> /* last cacheline: 48 bytes */
> };
>
> Let's say it's a struct ip_tunnel_info:
>
> struct ip_tunnel_info {
> struct ip_tunnel_key key; /* 0 64 */
>
> /* XXX last struct has 7 bytes of padding */
>
> /* --- cacheline 1 boundary (64 bytes) --- */
> struct ip_tunnel_encap encap; /* 64 8 */ <--- 144 + 64 = 208 we land here
> struct dst_cache dst_cache; /* 72 16 */
> u8 options_len; /* 88 1 */
> u8 mode; /* 89 1 */
>
> /* size: 96, cachelines: 2, members: 5 */
> /* padding: 6 */
> /* paddings: 1, sum paddings: 7 */
> /* last cacheline: 32 bytes */
> };
>
> So I imagine this is fairly tricky to trigger but still a case of type
> confusion. I have actually no idea how likely this can happen from my
> call but the trace makes sense at least.
That logic seems to exist for the icmp6_send to find the input device
(since the expected use-case for calling icmp6_send is to the incoming
skb). And since you're mainly doing egress, I don't think this path will
ever trigger (iow the check is not needed)?
Maybe you can add cgroup_ingress test case? Looks like this rt6_info
path might trigger for ipv6 lo? I don't see any ingress test in your
series, so might be good to have one regardless?
^ permalink raw reply
* Re: [PATCH] fix: net: mediatek: mtk_star_mdio_init: fix double of_node_put after devm_of_mdiobus_register
From: Andrew Lunn @ 2026-06-26 16:12 UTC (permalink / raw)
To: WenTao Liang
Cc: Daniel Borkmann, netdev, David S . Miller, Jakub Kicinski,
Paolo Abeni, stable, linux-kernel
In-Reply-To: <20260626152009.51599-1-vulab@iscas.ac.cn>
On Fri, Jun 26, 2026 at 11:20:09PM +0800, WenTao Liang wrote:
> After devm_of_mdiobus_register succeeds, the mdio_node reference
> ownership is transferred to the mii_bus device (released via
> mdiobus_release on device teardown). However, the function
> unconditionally calls of_node_put(mdio_node) after registration, causing
> a double put.
>
> Only call of_node_put when devm_of_mdiobus_register fails (i.e., when
> ownership was not transferred). On success, the bus driver manages the
> reference lifecycle.
>
> Cc: stable@vger.kernel.org
> Fixes: 9ed0a3fac08b ("net: ethernet: mtk-star-emac: use devm_of_mdiobus_register()")
> Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
Andrew
---
pw-bot: cr
^ permalink raw reply
* Re: [PATCH] fix: net: ti: cpsw_probe_dt: fix phy_node reference leak on error paths
From: Andrew Lunn @ 2026-06-26 16:12 UTC (permalink / raw)
To: WenTao Liang
Cc: Siddharth Vadapalli, Roger Quadros, netdev, Andrew Lunn,
David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-omap, stable, linux-kernel
In-Reply-To: <20260626152906.52112-1-vulab@iscas.ac.cn>
On Fri, Jun 26, 2026 at 11:29:06PM +0800, WenTao Liang wrote:
> After slave_data->phy_node is assigned (via of_node_get or
> of_parse_phandle), if subsequent calls like of_get_phy_mode or
> ti_cm_get_macid fail, the error path jumps to err_node_put which only
> releases the loop's port_np reference but not the phy_node reference.
> This causes a device_node reference leak.
>
> Release slave_data->phy_node via of_node_put before jumping to
> err_node_put on error paths after phy_node has been acquired.
>
> Cc: stable@vger.kernel.org
> Fixes: ed3525eda4c4 ("net: ethernet: ti: introduce cpsw switchdev based driver part 1 - dual-emac")
> Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
Andrew
---
pw-bot: cr
^ permalink raw reply
* Re: [PATCH] fix: net: ti: cpsw_init_common: fix excess of_node_put on parent node when cpts child not found
From: Andrew Lunn @ 2026-06-26 16:12 UTC (permalink / raw)
To: WenTao Liang
Cc: Siddharth Vadapalli, Roger Quadros, netdev, Andrew Lunn,
David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-omap, stable, linux-kernel
In-Reply-To: <20260626152945.52192-1-vulab@iscas.ac.cn>
On Fri, Jun 26, 2026 at 11:29:45PM +0800, WenTao Liang wrote:
> When no "cpts" child node exists in the device tree, cpts_node is
> assigned cpsw->dev->of_node without taking a reference via of_node_get.
> The function then unconditionally calls of_node_put(cpts_node) at the
> end, causing an excess put on the parent device node which can lead to a
> refcount underflow.
>
> Use of_node_get when falling back to the parent node to ensure the
> reference count is properly balanced with the subsequent of_node_put.
>
> Cc: stable@vger.kernel.org
> Fixes: ed3525eda4c4 ("net: ethernet: ti: introduce cpsw switchdev based driver part 1 - dual-emac")
> Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
Andrew
---
pw-bot: cr
^ permalink raw reply
* Re: [PATCH net v2 1/1] net/sched: sch_teql: Introduce slaves_lock to avoid race condition and UAF
From: Jamal Hadi Salim @ 2026-06-26 16:11 UTC (permalink / raw)
To: Simon Horman
Cc: netdev, davem, edumazet, kuba, pabeni, jiri, victor, security,
zdi-disclosures, stable, kernel test robot
In-Reply-To: <20260626141547.GA1310988@horms.kernel.org>
Hi Simon,
On Fri, Jun 26, 2026 at 10:15 AM Simon Horman <horms@kernel.org> wrote:
>
> On Fri, Jun 26, 2026 at 06:16:43AM -0400, Jamal Hadi Salim wrote:
> > "
> >
> > On Wed, Jun 24, 2026 at 6:40 PM Jamal Hadi Salim <jhs@mojatatu.com> wrote:
> > >
> > > The teql master->slaves singly linked list is not protected against
> > > multiple writes. It can be mod'ed concurently from teql_master_xmit(),
> > > teql_dequeue(), teql_init() and teql_destroy() without holding any list
> > > lock or RCU protection.
> > >
> > > zdi-disclosures@trendmicro.com has demonstrated that the qdisc is freed
> > > after an RCU grace period, but teql_master_xmit() running on another
> > > CPU can still hold a stale pointer into the list, resulting in a
> > > slab-use-after-free:
> > >
> > > BUG: KASAN: slab-use-after-free in teql_destroy+0x3ca/0x440 linux/net/sched/sch_teql.c:142
> > > Read of size 8 at addr ffff88802923aa80 by task ip/10024
> > >
> > > The zdi-disclosures@trendmicro.com repro created concurrent AF_PACKET
> > > senders on a teql device against a thread that repeatedly adds/deletes the
> > > slave qdisc, together with a SLUB spray that reclaims the freed slot; the
> > > resulting UAF is controllable enough to be turned into a read/write
> > > primitive against the freed qdisc object.
> > >
> > > The fix?
> > > Add a per-master slaves_lock spinlock that serializes all mutations of
> > > master->slaves and the NEXT_SLAVE() links in teql_destroy() and
> > > teql_qdisc_init(). teql_master_xmit() also takes the same slaves_lock
> > > around those updates.
> > > Annotate master->slaves and the per-slave ->next pointer with __rcu and
> > > use the appropriate RCU accessors everywhere they are touched:
> > > rcu_assign_pointer() on the writer side (under slaves_lock),
> > > rcu_dereference_protected() for the writer-side loads (also under
> > > slaves_lock), rcu_dereference_bh() for the loads in teql_master_xmit() and
> > > rtnl_dereference() for the loads in teql_master_open()/teql_master_mtu(),
> > > which run under RTNL.
> > > Pair this with rcu_read_lock_bh()/rcu_read_unlock_bh() around the list
> > > traversal in teql_master_xmit(), so that readers either observe a fully
> > > linked list or are deferred until the in-flight mutation completes. The two
> > > early-return paths in teql_master_xmit() are updated to release the RCU-bh
> > > read-side critical section before returning, since leaving it held would
> > > disable BH on that CPU for good.
> > >
> >
> > sashiko-gemini's complaints:
> > https://sashiko.dev/#/patchset/20260624224016.24018-1-jhs%40mojatatu.com
> > seem bogus to me (someone correct me if i am wrong). I am only going
> > to address the first claim of "TOCTOU / "resurrection" race in
> > teql_master_xmit()"
> > teql_master_xmit() holds rcu_read_lock_bh() across the entire
> > traversal. teql_destroy() freeing can only proceed once the qdisc's
> > RCU grace period has elapsed - so where is this TOCTOU? Let's say this
> > were true: both calls hold the slaves_lock.
> > The other issues are of similar nature.
>
> Hi Jamal,
>
> I think the central question here is about the protection offered by RCU
> in these code paths. And while I agree it protects the use of elements
> of the list, I think the problem flagged relates to the management of
> the list itself.
>
> The example AI gave me when I asked is like this:
>
> Assume a TEQL master has one slave, `q`.
> The list is circular: `q->next == q`.
>
> 1. CPU A (Transmitting): Enters `teql_master_xmit()`.
> It reads `master->sla ves` and gets a local pointer to `q`.
>
> 2. CPU B (Destroying): Calls `teql_destroy(q)`.
> It takes the lock, unlinks `q`, and sets `master->slaves = NULL`.
> The list is now logically empty.
>
> 3. CPU A: Finishes its work and prepares to rotate the list head
> to the next slave.
> It takes the lock.
>
> 4. CPU A (The "Use" / The Resurrection):
> It executes: `rcu_assign_pointer(master->slaves, NEXT_SLAVE(q));`
> Because `q` was circular, `NEXT_SLAVE(q)` is still `q`.
>
> 5. CPU A: Releases the lock.
> **The global `master->slaves` is now `q` again.**
>
> 6. The System: The RCU grace period expires. CPU B finishes
> `teql_destroy()` and the memory for `q` is freed.
>
> The global `master->slaves` pointer is now a **dangling pointer**
> pointing to freed memory.
>
Yeah, thats the same earlier claim of TOCTOU (what sashiko-gemini
claimed was "resurrecting the freed q")
My view is rcu read lock blocks the subsequent call_rcu free - and
destroy() and xmit() already serialize on slaves_lock.
I could be totaly wrong, but it's almost like sashiko-gemini thinks
that the list-mutation lock _alone_ governs the object lifetime.
The rcu read-side critical section prevents the UAF, not just the
slaves_lock alone
Only reason i added slaves_lock was to prevent corrupting the list
state (whereas the RCU read lock prevents premature free).
In step #4 above this thing somehow leaves out any mention of the rcu
read lock entirely and places the free in step 6 as if it was
independent of CPU A's critical section.
I am not sure how to improve it.
> > OTOH, sashiko-claude
> > (https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260624224016.24018-1-jhs%40mojatatu.com)
> > does make some valid claims which are low value, so not sure a resend
> > is worth it.
> > For example in claim 1 it says "Should the changelog mention this
> > teql_dequeue() site too?" Sure I can - but just because I provided
> > extra information in the commit log, which I could have omitted, now I
> > have to add more info? ;->
>
> FWIIW, I think there is a value in tightening up the commit message.
> E.g. so it's accurate when we look at again in two years time.
> But I also lean towards it not being necessary to post an update
> only to address this.
>
>
> > The second claim is "rcu_dereference_bh()
> > should be rcu_dereference_protected() on writer side". Sparse didnt
> > complain and i dont see this as breakage rather a consistency measure.
>
> I think it would be good to address in the long run. But as per my comment
> immediately above, I also lean towards it not being necessary to post an
> update only to address this.
I can resend with these two taken care of - but i am skeptical of what
sashiko-gemini is claiming (and i admit as a human the AI may see
something i am totally missing).
cheers,
jamal
>
> > Unless I am missing something ..
> >
> > cheers,
> > jamal
^ permalink raw reply
* Re: [PATCH] fix: net: ti: cpts_of_mux_clk_setup: fix device_node reference leak on success path
From: Andrew Lunn @ 2026-06-26 16:11 UTC (permalink / raw)
To: WenTao Liang
Cc: Andrew Lunn, netdev, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Grygorii Strashko, linux-omap,
stable, linux-kernel
In-Reply-To: <20260626153148.52612-1-vulab@iscas.ac.cn>
On Fri, Jun 26, 2026 at 11:31:48PM +0800, WenTao Liang wrote:
> of_get_child_by_name acquires a device_node reference for refclk_np, and
> of_clk_add_hw_provider additionally takes an extra reference internally.
> On the success path, the function returns 0 without calling
> of_node_put(refclk_np), leaking the initial reference.
>
> Add of_node_put(refclk_np) before returning success to properly release
> the acquired reference.
>
> Cc: stable@vger.kernel.org
> Fixes: a3047a81ba13 ("net: ethernet: ti: cpts: add support for ext rftclk selection")
> Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
Andrew
---
pw-bot: cr
^ permalink raw reply
* Re: [PATCH] fix: net: mdio: of_phy_register_fixed_link: fix phy_device reference leak via discarded pointer
From: Andrew Lunn @ 2026-06-26 16:11 UTC (permalink / raw)
To: WenTao Liang
Cc: Andrew Lunn, netdev, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, stable, linux-kernel
In-Reply-To: <20260626153330.52741-1-vulab@iscas.ac.cn>
On Fri, Jun 26, 2026 at 11:33:30PM +0800, WenTao Liang wrote:
> fixed_phy_register returns a struct phy_device pointer with a held
> reference on success. However, the register_phy label discards the
> pointer via PTR_ERR_OR_ZERO, and the phy_device's fwnode is not set, so
> of_phy_deregister_fixed_link cannot find the device via
> bus_find_device_by_fwnode to clean it up. This permanently leaks the
> phy_device and its device_node reference.
>
> Store the returned phy_device pointer and set dev->fwnode so the
> deregister path can properly locate and clean it up.
>
> Cc: stable@vger.kernel.org
> Fixes: 24c30dbbcdda ("of/mdio: Add support function for Ethernet fixed-link property")
> Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
Andrew
---
pw-bot: cr
^ permalink raw reply
* Re: [PATCH] fix: net: phy: phy_sfp_probe: fix kref leak when phy_setup_sfp_port fails after sfp_bus_add_upstream
From: Andrew Lunn @ 2026-06-26 16:11 UTC (permalink / raw)
To: WenTao Liang
Cc: Andrew Lunn, netdev, Heiner Kallweit, Russell King,
David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
stable, linux-kernel
In-Reply-To: <20260626153443.52842-1-vulab@iscas.ac.cn>
On Fri, Jun 26, 2026 at 11:34:43PM +0800, WenTao Liang wrote:
> sfp_bus_add_upstream unconditionally acquires a kref on the SFP bus. When
> this call succeeds but the subsequent phy_setup_sfp_port fails, the error
> path returns without releasing the upstream reference. Since probe fails,
> the device's remove function (which would normally clean this up) will
> never be called, permanently leaking the kref.
>
> Call sfp_bus_del_upstream on the error path after a successful
> sfp_bus_add_upstream to properly release the upstream reference.
>
> Cc: stable@vger.kernel.org
> Fixes: 298e54fa810e ("net: phy: add core phylib sfp support")
> Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
Andrew
---
pw-bot: cr
^ permalink raw reply
* Re: [PATCH v2] fix: net: renesas: rswitch_mii_register: fix double of_node_put after of_mdiobus_register
From: Andrew Lunn @ 2026-06-26 16:10 UTC (permalink / raw)
To: WenTao Liang
Cc: netdev, Yoshihiro Shimoda, David S . Miller, Jakub Kicinski,
Paolo Abeni, stable, linux-kernel
In-Reply-To: <20260626152550.51911-1-vulab@iscas.ac.cn>
On Fri, Jun 26, 2026 at 11:25:50PM +0800, WenTao Liang wrote:
> After of_mdiobus_register succeeds, the mdio_np reference ownership is
> transferred to the mii_bus device (released via fwnode_handle_put during
> mdiobus_release). The success path calls of_node_put(mdio_np) which,
> combined with the automatic release via bus teardown, results in a double
> put and refcount underflow.
>
> Move of_node_put so it is only called in the error path where
> of_mdiobus_register failed. On success, the bus driver manages the
> reference lifecycle.
Please stop with these patches.
First please read:
https://www.kernel.org/doc/html/latest/process/maintainer-netdev.html
and
https://docs.kernel.org/process/submitting-patches.html
You are getting a lot of things wrong.
* don’t repost your patches within one 24h period
* Don't thread new versions of a patch to the old one
* Include version history, how is v2 different to v1
* When you see your own patch is broken, reply with NACK, and explain
what is wrong with it.
Until you learn how to correctly submit patches, please only submit
them one at a time, get it accepted, and move onto the next. Otherwise
you are wasting peoples time, and getting yourself a bad reputation.
Andrew
^ permalink raw reply
* Re: [PATCH] fix: net: cadence: macb_mii_init: fix double of_node_put on mdio_np after macb_mdiobus_register
From: Andrew Lunn @ 2026-06-26 16:02 UTC (permalink / raw)
To: WenTao Liang
Cc: Nicolas Ferre, netdev, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, stable, linux-kernel
In-Reply-To: <20260626151449.50969-1-vulab@iscas.ac.cn>
On Fri, Jun 26, 2026 at 11:14:49PM +0800, WenTao Liang wrote:
> After macb_mdiobus_register succeeds, the mdio_np reference ownership is
> transferred to the mii_bus device (stored in mii_bus->dev.of_node). When
> the subsequent macb_mii_probe fails, the error path jumps to
> err_out_unregister_bus which calls mdiobus_free (releasing the node via
> fwnode_handle_put) and then falls through to err_out which calls
> of_node_put(mdio_np) again, causing a double put.
>
> Move the of_node_put to only execute on paths where the reference was not
> transferred (i.e., before successful macb_mdiobus_register).
>
> Cc: stable@vger.kernel.org
> Fixes: ef8a2e27289e ("net: macb: fix probing of PHY not described in the dt")
> Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
> ---
> drivers/net/ethernet/cadence/macb_main.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
> index a12aa21244e8..c58e089e5888 100644
> --- a/drivers/net/ethernet/cadence/macb_main.c
> +++ b/drivers/net/ethernet/cadence/macb_main.c
> @@ -1170,6 +1170,9 @@ static int macb_mii_init(struct macb *bp)
> mdiobus_unregister(bp->mii_bus);
> err_out_free_mdiobus:
> mdiobus_free(bp->mii_bus);
> + of_node_put(mdio_np);
> + return err;
> +
> err_out:
> of_node_put(mdio_np);
This does not look correct.
You say if mdiobus_register() is successful, mdiobus_free() will
release the reference.
If macb_mii_probe() fails, we have successfully done
mdiobus_register(). It does a goto err_out_unregister_bus, which calls
mdiobus_unregister(), mdiobus_free() releasing the reference, and then
with your patch of_node_put(). This looks like a double put to me.
I think i already said this once, consider the risk of your patches,
particularly if you cannot test them.
Andrew
^ permalink raw reply
* [PATCH net v2 2/2] net: ethernet: oa_tc6: Improvement in buffer overflow handling
From: Selvamani Rajagopal via B4 Relay @ 2026-06-26 15:35 UTC (permalink / raw)
To: Parthiban Veerasooran, Andrew Lunn, Piergiorgio Beruto,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: netdev, linux-kernel, Andrew Lunn, Parthiban Veerasooran,
Selvamani Rajagopal
In-Reply-To: <20260626-fix-race-condition-and-crash-v2-0-b6c5c10e604f@onsemi.com>
From: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
When oversubscribed traffic causes lot of buffer overflow errors,
probably due to loss of data chunks, driver fails to find a
data chunk with end_valid bit set, before it runs out of sk buffer
space. As a result, assert is seen during skb_put.
Now check is made if tail + len > end, driver abandons the current
data and starts look for a data chunk with start_valid bit,
that is a new frame.
Fixes: d70a0d8f2f2d ("net: ethernet: oa_tc6: implement receive path to receive rx ethernet frames")
Signed-off-by: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
---
changes in v2
- Check rx_skb pointer before new allocation and NULL before use.
---
drivers/net/ethernet/oa_tc6.c | 69 +++++++++++++++++++++++++++++++------------
1 file changed, 50 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index 3fd4851ee66d..c59daa032e70 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -692,6 +692,12 @@ static void oa_tc6_free_pending_skbs(struct oa_tc6 *tc6)
oa_tc6_cleanup_waiting_tx_skb(tc6);
}
+static void oa_tc6_look_for_new_frame(struct oa_tc6 *tc6)
+{
+ tc6->rx_buf_overflow = true;
+ oa_tc6_cleanup_ongoing_rx_skb(tc6);
+}
+
/* If the failure is at SPI interface level, masking and clearing
* the interrupt of the device won't work. Since SPI interrupt is
* disabled, it should stop the repeated interrupts.
@@ -729,8 +735,7 @@ static int oa_tc6_process_extended_status(struct oa_tc6 *tc6)
}
if (FIELD_GET(STATUS0_RX_BUFFER_OVERFLOW_ERROR, value)) {
- tc6->rx_buf_overflow = true;
- oa_tc6_cleanup_ongoing_rx_skb(tc6);
+ oa_tc6_look_for_new_frame(tc6);
net_err_ratelimited("%s: Receive buffer overflow error\n",
tc6->netdev->name);
return -EAGAIN;
@@ -811,13 +816,35 @@ static void oa_tc6_submit_rx_skb(struct oa_tc6 *tc6)
tc6->rx_skb = NULL;
}
-static void oa_tc6_update_rx_skb(struct oa_tc6 *tc6, u8 *payload, u8 length)
+/* On oversubscribed traffic condition, particularly with overwhelming rx
+ * buffer overflow errors, there could be data chunk loss. If tail + length
+ * goes beyond end pointer, that is an indication that the data chunk with
+ * end_valid bit is lost. Time to look for a data chunk with start_valid bit.
+ *
+ * If rx_skb is NULL, it is time to start looking for data chunk with
+ * start_bit.
+ */
+static int oa_tc6_update_rx_skb(struct oa_tc6 *tc6, u8 *payload, u8 length)
{
+ if (!tc6->rx_skb ||
+ (tc6->rx_skb->tail + length) > tc6->rx_skb->end) {
+ oa_tc6_look_for_new_frame(tc6);
+ return -EAGAIN;
+ }
+
memcpy(skb_put(tc6->rx_skb, length), payload, length);
+ return 0;
}
+/* On overwhelming rx buffer overflow errors, due to data chunk loss, it is
+ * possible that we get two data chunks with start_valid bit set, without
+ * end_valid bit set in between. In this case, rx_skb would have a valid
+ * buffer pointer. We should release, if a valid pointer is found before
+ * allocating a new one.
+ */
static int oa_tc6_allocate_rx_skb(struct oa_tc6 *tc6)
{
+ oa_tc6_cleanup_ongoing_rx_skb(tc6);
tc6->rx_skb = netdev_alloc_skb_ip_align(tc6->netdev, tc6->netdev->mtu +
ETH_HLEN + ETH_FCS_LEN);
if (!tc6->rx_skb) {
@@ -837,7 +864,9 @@ static int oa_tc6_prcs_complete_rx_frame(struct oa_tc6 *tc6, u8 *payload,
if (ret)
return ret;
- oa_tc6_update_rx_skb(tc6, payload, size);
+ ret = oa_tc6_update_rx_skb(tc6, payload, size);
+ if (ret)
+ return ret;
oa_tc6_submit_rx_skb(tc6);
@@ -852,22 +881,24 @@ static int oa_tc6_prcs_rx_frame_start(struct oa_tc6 *tc6, u8 *payload, u16 size)
if (ret)
return ret;
- oa_tc6_update_rx_skb(tc6, payload, size);
-
- return 0;
+ return oa_tc6_update_rx_skb(tc6, payload, size);
}
-static void oa_tc6_prcs_rx_frame_end(struct oa_tc6 *tc6, u8 *payload, u16 size)
+static int oa_tc6_prcs_rx_frame_end(struct oa_tc6 *tc6, u8 *payload, u16 size)
{
- oa_tc6_update_rx_skb(tc6, payload, size);
+ int ret;
- oa_tc6_submit_rx_skb(tc6);
+ ret = oa_tc6_update_rx_skb(tc6, payload, size);
+ if (!ret)
+ oa_tc6_submit_rx_skb(tc6);
+ return ret;
}
-static void oa_tc6_prcs_ongoing_rx_frame(struct oa_tc6 *tc6, u8 *payload,
- u32 footer)
+static int oa_tc6_prcs_ongoing_rx_frame(struct oa_tc6 *tc6, u8 *payload,
+ u32 footer)
{
- oa_tc6_update_rx_skb(tc6, payload, OA_TC6_CHUNK_PAYLOAD_SIZE);
+ return oa_tc6_update_rx_skb(tc6, payload,
+ OA_TC6_CHUNK_PAYLOAD_SIZE);
}
static int oa_tc6_prcs_rx_chunk_payload(struct oa_tc6 *tc6, u8 *data,
@@ -880,6 +911,7 @@ static int oa_tc6_prcs_rx_chunk_payload(struct oa_tc6 *tc6, u8 *data,
bool start_valid = FIELD_GET(OA_TC6_DATA_FOOTER_START_VALID, footer);
bool end_valid = FIELD_GET(OA_TC6_DATA_FOOTER_END_VALID, footer);
u16 size;
+ int ret;
/* Restart the new rx frame after receiving rx buffer overflow error */
if (start_valid && tc6->rx_buf_overflow)
@@ -907,8 +939,7 @@ static int oa_tc6_prcs_rx_chunk_payload(struct oa_tc6 *tc6, u8 *data,
/* Process the chunk with only rx frame end */
if (end_valid && !start_valid) {
size = end_byte_offset + 1;
- oa_tc6_prcs_rx_frame_end(tc6, data, size);
- return 0;
+ return oa_tc6_prcs_rx_frame_end(tc6, data, size);
}
/* Process the chunk with previous rx frame end and next rx frame
@@ -921,7 +952,9 @@ static int oa_tc6_prcs_rx_chunk_payload(struct oa_tc6 *tc6, u8 *data,
*/
if (tc6->rx_skb) {
size = end_byte_offset + 1;
- oa_tc6_prcs_rx_frame_end(tc6, data, size);
+ ret = oa_tc6_prcs_rx_frame_end(tc6, data, size);
+ if (ret)
+ return ret;
}
size = OA_TC6_CHUNK_PAYLOAD_SIZE - start_byte_offset;
return oa_tc6_prcs_rx_frame_start(tc6,
@@ -930,9 +963,7 @@ static int oa_tc6_prcs_rx_chunk_payload(struct oa_tc6 *tc6, u8 *data,
}
/* Process the chunk with ongoing rx frame data */
- oa_tc6_prcs_ongoing_rx_frame(tc6, data, footer);
-
- return 0;
+ return oa_tc6_prcs_ongoing_rx_frame(tc6, data, footer);
}
static u32 oa_tc6_get_rx_chunk_footer(struct oa_tc6 *tc6, u16 footer_offset)
--
2.43.0
^ permalink raw reply related
* [PATCH net v2 1/2] net: ethernet: oa_tc6: Protect skb pointer used by two different kernel instances
From: Selvamani Rajagopal via B4 Relay @ 2026-06-26 15:35 UTC (permalink / raw)
To: Parthiban Veerasooran, Andrew Lunn, Piergiorgio Beruto,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: netdev, linux-kernel, Andrew Lunn, Parthiban Veerasooran,
Selvamani Rajagopal
In-Reply-To: <20260626-fix-race-condition-and-crash-v2-0-b6c5c10e604f@onsemi.com>
From: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
Threaded IRQ uses waiting_tx_skb. Transmit path also uses
this pointer without any mutual exclusion protection. As a
result, it might leak skb buffer, particularly threaded IRQ
runs in the middle of tranmsmit path, near skb_linearize.
Fixes: b542d13fab0f ("net: ethernet: oa_tc6: Interrupt is active low, level triggered.")
Signed-off-by: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
---
changes in v2:
added the missing prefix to the title
---
drivers/net/ethernet/oa_tc6.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index 0727d53345a3..3fd4851ee66d 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -672,10 +672,16 @@ static void oa_tc6_cleanup_ongoing_tx_skb(struct oa_tc6 *tc6)
static void oa_tc6_cleanup_waiting_tx_skb(struct oa_tc6 *tc6)
{
- if (tc6->waiting_tx_skb) {
+ struct sk_buff *skb;
+
+ spin_lock_bh(&tc6->tx_skb_lock);
+ skb = tc6->waiting_tx_skb;
+ tc6->waiting_tx_skb = NULL;
+ spin_unlock_bh(&tc6->tx_skb_lock);
+
+ if (skb) {
tc6->netdev->stats.tx_dropped++;
- kfree_skb(tc6->waiting_tx_skb);
- tc6->waiting_tx_skb = NULL;
+ kfree_skb(skb);
}
}
@@ -1250,11 +1256,6 @@ EXPORT_SYMBOL_GPL(oa_tc6_zero_align_receive_frame_enable);
*/
netdev_tx_t oa_tc6_start_xmit(struct oa_tc6 *tc6, struct sk_buff *skb)
{
- if (tc6->disable_traffic || tc6->waiting_tx_skb) {
- netif_stop_queue(tc6->netdev);
- return NETDEV_TX_BUSY;
- }
-
if (skb_linearize(skb)) {
dev_kfree_skb_any(skb);
tc6->netdev->stats.tx_dropped++;
@@ -1262,6 +1263,11 @@ netdev_tx_t oa_tc6_start_xmit(struct oa_tc6 *tc6, struct sk_buff *skb)
}
spin_lock_bh(&tc6->tx_skb_lock);
+ if (tc6->disable_traffic || tc6->waiting_tx_skb) {
+ netif_stop_queue(tc6->netdev);
+ spin_unlock_bh(&tc6->tx_skb_lock);
+ return NETDEV_TX_BUSY;
+ }
tc6->waiting_tx_skb = skb;
spin_unlock_bh(&tc6->tx_skb_lock);
--
2.43.0
^ permalink raw reply related
* [PATCH net v2 0/2] Fix to possible skb leak due to race condtion in tx path
From: Selvamani Rajagopal via B4 Relay @ 2026-06-26 15:35 UTC (permalink / raw)
To: Parthiban Veerasooran, Andrew Lunn, Piergiorgio Beruto,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: netdev, linux-kernel, Andrew Lunn, Parthiban Veerasooran,
Selvamani Rajagopal
Now the traffic is handled in threaded IRQ, and the
disable_traffic flag is checked before handling the
data, new race condition is exposed, in which
buffer may leak, if threaded IRQ interrupts the
trasmit path midway.
With this change, disable_traffic and waiting_tx_skb
pointer are protected by spin lock/unlock pair.
This is highlighted in Sashiko review
https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260611-level-trigger-v5-0-4533a9e85ce2%40onsemi.com
Also on buffer overrun condition, probably due to loss of
SPI data chunks, receive path doesn't see the expected
data chunk with end_valid bit set. As a result, driver
keeps adding data chunks to the skb before running out
of space and kernel panic is seen.
With this change, before adding data to the skb, if there
is no space, skb is freed and driver starts looking for
new frame by looking for a data chunk with start_valid
bit set.
[ 705.405490] skbuff: skb_over_panic: text:ffffffd2eb72a264 len:1600 put:64 head:ffffff804e5cdc40 data:ffffff804e5cdc80 tail:0x680 end:0x640 dev:eth1
[ 705.405569] ------------[ cut here ]------------
[ 705.405575] kernel BUG at net/core/skbuff.c:214!
[ 705.405589] Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
[ 6703.427690] Call trace:
[ 705.925157] skb_panic+0x58/0x68 (P)
[ 705.928726] skb_put+0x74/0x80
[ 705.931772] oa_tc6_update_rx_skb+0x44/0x98 [oa_tc6_mod]
[ 705.937084] oa_tc6_macphy_threaded_irq+0x3f4/0x900 [oa_tc6_mod]
[ 705.943084] irq_thread_fn+0x34/0xb8
[ 705.946654] irq_thread+0x1a0/0x300
[ 705.950134] kthread+0x138/0x150
[ 705.953356] ret_from_fork+0x10/0x20
Signed-off-by: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
---
Changes in v2:
- Improvment to how error -EAGAIN is handled. Took care of
couple of use cases where start_bit and end_bit may be missing or
repeated due to lost data chunks.
- Protected handling of waiting_tx_skb pointer with spin lock
- Link to v1: https://lore.kernel.org/r/20260621-fix-race-condition-and-crash-v1-0-87e290d9357f@onsemi.com
---
Selvamani Rajagopal (2):
net: ethernet: oa_tc6: Protect skb pointer used by two different kernel instances
net: ethernet: oa_tc6: Improvement in buffer overflow handling
drivers/net/ethernet/oa_tc6.c | 91 ++++++++++++++++++++++++++++++-------------
1 file changed, 64 insertions(+), 27 deletions(-)
---
base-commit: 805185b7c7a1069e407b6f7b3bc98e44d415f484
change-id: 20260621-fix-race-condition-and-crash-94d055a665c4
Best regards,
--
Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
^ permalink raw reply
* [PATCH] fix: net: phy: phy_sfp_probe: fix kref leak when phy_setup_sfp_port fails after sfp_bus_add_upstream
From: WenTao Liang @ 2026-06-26 15:34 UTC (permalink / raw)
To: Andrew Lunn, netdev
Cc: Heiner Kallweit, Russell King, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, stable, linux-kernel, WenTao Liang
sfp_bus_add_upstream unconditionally acquires a kref on the SFP bus. When
this call succeeds but the subsequent phy_setup_sfp_port fails, the error
path returns without releasing the upstream reference. Since probe fails,
the device's remove function (which would normally clean this up) will
never be called, permanently leaking the kref.
Call sfp_bus_del_upstream on the error path after a successful
sfp_bus_add_upstream to properly release the upstream reference.
Cc: stable@vger.kernel.org
Fixes: 298e54fa810e ("net: phy: add core phylib sfp support")
Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
---
drivers/net/phy/phy_device.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 3370eb822017..cd62c46de017 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1723,6 +1723,11 @@ static int phy_sfp_probe(struct phy_device *phydev)
if (!ret && phydev->sfp_bus)
ret = phy_setup_sfp_port(phydev);
+ if (ret && phydev->sfp_bus) {
+ sfp_bus_del_upstream(phydev->sfp_bus);
+ phydev->sfp_bus = NULL;
+ }
+
return ret;
}
--
2.39.5 (Apple Git-154)
^ permalink raw reply related
* [PATCH] fix: net: mdio: of_phy_register_fixed_link: fix phy_device reference leak via discarded pointer
From: WenTao Liang @ 2026-06-26 15:33 UTC (permalink / raw)
To: Andrew Lunn, netdev
Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
stable, linux-kernel, WenTao Liang
fixed_phy_register returns a struct phy_device pointer with a held
reference on success. However, the register_phy label discards the
pointer via PTR_ERR_OR_ZERO, and the phy_device's fwnode is not set, so
of_phy_deregister_fixed_link cannot find the device via
bus_find_device_by_fwnode to clean it up. This permanently leaks the
phy_device and its device_node reference.
Store the returned phy_device pointer and set dev->fwnode so the
deregister path can properly locate and clean it up.
Cc: stable@vger.kernel.org
Fixes: 24c30dbbcdda ("of/mdio: Add support function for Ethernet fixed-link property")
Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
---
drivers/net/mdio/of_mdio.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/net/mdio/of_mdio.c b/drivers/net/mdio/of_mdio.c
index b8d298c04d3f..0dd25d94fec0 100644
--- a/drivers/net/mdio/of_mdio.c
+++ b/drivers/net/mdio/of_mdio.c
@@ -456,8 +456,16 @@ int of_phy_register_fixed_link(struct device_node *np)
return -ENODEV;
-register_phy:
- return PTR_ERR_OR_ZERO(fixed_phy_register(&status, np));
+register_phy: {
+ struct phy_device *phydev;
+
+ phydev = fixed_phy_register(&status, np);
+ if (IS_ERR(phydev))
+ return PTR_ERR(phydev);
+
+ phydev->mdio.dev.fwnode = of_fwnode_handle(np);
+ return 0;
+}
}
EXPORT_SYMBOL(of_phy_register_fixed_link);
--
2.39.5 (Apple Git-154)
^ permalink raw reply related
* [PATCH] fix: net: ti: cpts_of_mux_clk_setup: fix device_node reference leak on success path
From: WenTao Liang @ 2026-06-26 15:31 UTC (permalink / raw)
To: Andrew Lunn, netdev
Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Grygorii Strashko, linux-omap, stable, linux-kernel, WenTao Liang
of_get_child_by_name acquires a device_node reference for refclk_np, and
of_clk_add_hw_provider additionally takes an extra reference internally.
On the success path, the function returns 0 without calling
of_node_put(refclk_np), leaking the initial reference.
Add of_node_put(refclk_np) before returning success to properly release
the acquired reference.
Cc: stable@vger.kernel.org
Fixes: a3047a81ba13 ("net: ethernet: ti: cpts: add support for ext rftclk selection")
Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
---
drivers/net/ethernet/ti/cpts.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index 2ba4c8795d60..d6e6d074747e 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -714,7 +714,8 @@ static int cpts_of_mux_clk_setup(struct cpts *cpts, struct device_node *node)
goto mux_fail;
}
- return ret;
+ of_node_put(refclk_np);
+ return 0;
mux_fail:
of_node_put(refclk_np);
--
2.39.5 (Apple Git-154)
^ permalink raw reply related
* Re: [PATCH net v2] net: ipa: fix SMEM state handle leaks in SMP2P init
From: Alex Elder @ 2026-06-26 15:31 UTC (permalink / raw)
To: Haoxiang Li, elder, andrew+netdev, davem, edumazet, kuba, pabeni
Cc: netdev, linux-kernel, stable
In-Reply-To: <20260624065955.2822765-1-haoxiang_li2024@163.com>
On 6/24/26 1:59 AM, Haoxiang Li wrote:
> ipa_smp2p_init() acquires two Qualcomm SMEM state handles with
> qcom_smem_state_get(). However, neither the init error paths
> nor ipa_smp2p_exit() release them.
>
> Release both handles with qcom_smem_state_put() in the init
> error paths and in ipa_smp2p_exit().
>
> Fixes: 530f9216a953 ("soc: qcom: ipa: AP/modem communications")
> Cc: stable@vger.kernel.org
> Signed-off-by: Haoxiang Li <haoxiang_li2024@163.com>
This looks good. Thank you for the fix.
Reviewed-by: Alex Elder <elder@riscstar.com>
> ---
> Changes in v2:
> - Use explicit qcom_smem_state_put() calls instead of devm helpers.
> Thanks, Alex! Thanks, Jakub!
> ---
> drivers/net/ipa/ipa_smp2p.c | 30 ++++++++++++++++++++++--------
> 1 file changed, 22 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/ipa/ipa_smp2p.c b/drivers/net/ipa/ipa_smp2p.c
> index 2f0ccdd937cc..331c00ad02c0 100644
> --- a/drivers/net/ipa/ipa_smp2p.c
> +++ b/drivers/net/ipa/ipa_smp2p.c
> @@ -232,19 +232,27 @@ ipa_smp2p_init(struct ipa *ipa, struct platform_device *pdev, bool modem_init)
> &valid_bit);
> if (IS_ERR(valid_state))
> return PTR_ERR(valid_state);
> - if (valid_bit >= 32) /* BITS_PER_U32 */
> - return -EINVAL;
> + if (valid_bit >= 32) { /* BITS_PER_U32 */
> + ret = -EINVAL;
> + goto err_valid_state_put;
> + }
>
> enabled_state = qcom_smem_state_get(dev, "ipa-clock-enabled",
> &enabled_bit);
> - if (IS_ERR(enabled_state))
> - return PTR_ERR(enabled_state);
> - if (enabled_bit >= 32) /* BITS_PER_U32 */
> - return -EINVAL;
> + if (IS_ERR(enabled_state)) {
> + ret = PTR_ERR(enabled_state);
> + goto err_valid_state_put;
> + }
> + if (enabled_bit >= 32) { /* BITS_PER_U32 */
> + ret = -EINVAL;
> + goto err_enabled_state_put;
> + }
>
> smp2p = kzalloc_obj(*smp2p);
> - if (!smp2p)
> - return -ENOMEM;
> + if (!smp2p) {
> + ret = -ENOMEM;
> + goto err_enabled_state_put;
> + }
>
> smp2p->ipa = ipa;
>
> @@ -289,6 +297,10 @@ ipa_smp2p_init(struct ipa *ipa, struct platform_device *pdev, bool modem_init)
> ipa->smp2p = NULL;
> mutex_destroy(&smp2p->mutex);
> kfree(smp2p);
> +err_enabled_state_put:
> + qcom_smem_state_put(enabled_state);
> +err_valid_state_put:
> + qcom_smem_state_put(valid_state);
>
> return ret;
> }
> @@ -305,6 +317,8 @@ void ipa_smp2p_exit(struct ipa *ipa)
> ipa_smp2p_power_release(ipa);
> ipa->smp2p = NULL;
> mutex_destroy(&smp2p->mutex);
> + qcom_smem_state_put(smp2p->enabled_state);
> + qcom_smem_state_put(smp2p->valid_state);
> kfree(smp2p);
> }
>
^ permalink raw reply
* [PATCH] fix: net: ti: cpsw_init_common: fix excess of_node_put on parent node when cpts child not found
From: WenTao Liang @ 2026-06-26 15:29 UTC (permalink / raw)
To: Siddharth Vadapalli, Roger Quadros, netdev
Cc: Andrew Lunn, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, linux-omap, stable, linux-kernel, WenTao Liang
When no "cpts" child node exists in the device tree, cpts_node is
assigned cpsw->dev->of_node without taking a reference via of_node_get.
The function then unconditionally calls of_node_put(cpts_node) at the
end, causing an excess put on the parent device node which can lead to a
refcount underflow.
Use of_node_get when falling back to the parent node to ensure the
reference count is properly balanced with the subsequent of_node_put.
Cc: stable@vger.kernel.org
Fixes: ed3525eda4c4 ("net: ethernet: ti: introduce cpsw switchdev based driver part 1 - dual-emac")
Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
---
drivers/net/ethernet/ti/cpsw_priv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/ti/cpsw_priv.c b/drivers/net/ethernet/ti/cpsw_priv.c
index 1f6f374551cb..b20567f96d78 100644
--- a/drivers/net/ethernet/ti/cpsw_priv.c
+++ b/drivers/net/ethernet/ti/cpsw_priv.c
@@ -553,7 +553,7 @@ int cpsw_init_common(struct cpsw_common *cpsw, void __iomem *ss_regs,
cpts_node = of_get_child_by_name(cpsw->dev->of_node, "cpts");
if (!cpts_node)
- cpts_node = cpsw->dev->of_node;
+ cpts_node = of_node_get(cpsw->dev->of_node);
cpsw->cpts = cpts_create(cpsw->dev, cpts_regs, cpts_node,
CPTS_N_ETX_TS);
--
2.39.5 (Apple Git-154)
^ permalink raw reply related
* [PATCH] fix: net: ti: cpsw_probe_dt: fix phy_node reference leak on error paths
From: WenTao Liang @ 2026-06-26 15:29 UTC (permalink / raw)
To: Siddharth Vadapalli, Roger Quadros, netdev
Cc: Andrew Lunn, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, linux-omap, stable, linux-kernel, WenTao Liang
After slave_data->phy_node is assigned (via of_node_get or
of_parse_phandle), if subsequent calls like of_get_phy_mode or
ti_cm_get_macid fail, the error path jumps to err_node_put which only
releases the loop's port_np reference but not the phy_node reference.
This causes a device_node reference leak.
Release slave_data->phy_node via of_node_put before jumping to
err_node_put on error paths after phy_node has been acquired.
Cc: stable@vger.kernel.org
Fixes: ed3525eda4c4 ("net: ethernet: ti: introduce cpsw switchdev based driver part 1 - dual-emac")
Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
---
drivers/net/ethernet/ti/cpsw_new.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/ti/cpsw_new.c b/drivers/net/ethernet/ti/cpsw_new.c
index c5be359f3c66..9f90d5a9d39f 100644
--- a/drivers/net/ethernet/ti/cpsw_new.c
+++ b/drivers/net/ethernet/ti/cpsw_new.c
@@ -1337,6 +1337,7 @@ static int cpsw_probe_dt(struct cpsw_common *cpsw)
if (ret) {
dev_err(dev, "%pOF read phy-mode err %d\n",
port_np, ret);
+ of_node_put(slave_data->phy_node);
goto err_node_put;
}
@@ -1344,8 +1345,10 @@ static int cpsw_probe_dt(struct cpsw_common *cpsw)
if (ret) {
ret = ti_cm_get_macid(dev, port_id - 1,
slave_data->mac_addr);
- if (ret)
+ if (ret) {
+ of_node_put(slave_data->phy_node);
goto err_node_put;
+ }
}
if (of_property_read_u32(port_np, "ti,dual-emac-pvid",
--
2.39.5 (Apple Git-154)
^ permalink raw reply related
* [PATCH v2] fix: net: renesas: rswitch_mii_register: fix double of_node_put after of_mdiobus_register
From: WenTao Liang @ 2026-06-26 15:25 UTC (permalink / raw)
To: netdev
Cc: Yoshihiro Shimoda, David S . Miller, Jakub Kicinski, Paolo Abeni,
stable, linux-kernel, WenTao Liang
In-Reply-To: <20260626152430.51835-1-vulab@iscas.ac.cn>
After of_mdiobus_register succeeds, the mdio_np reference ownership is
transferred to the mii_bus device (released via fwnode_handle_put during
mdiobus_release). The success path calls of_node_put(mdio_np) which,
combined with the automatic release via bus teardown, results in a double
put and refcount underflow.
Move of_node_put so it is only called in the error path where
of_mdiobus_register failed. On success, the bus driver manages the
reference lifecycle.
Cc: stable@vger.kernel.org
Fixes: 3590918b5d07 ("net: ethernet: renesas: Add support for Ethernet Switch")
Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
---
drivers/net/ethernet/renesas/rswitch_main.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/renesas/rswitch_main.c b/drivers/net/ethernet/renesas/rswitch_main.c
index 6fe964816322..d5f1b5fd5817 100644
--- a/drivers/net/ethernet/renesas/rswitch_main.c
+++ b/drivers/net/ethernet/renesas/rswitch_main.c
@@ -1387,15 +1387,13 @@ static int rswitch_mii_register(struct rswitch_device *rdev)
err = of_mdiobus_register(mii_bus, mdio_np);
if (err < 0) {
mdiobus_free(mii_bus);
- goto out;
+ of_node_put(mdio_np);
+ return err;
}
rdev->etha->mii = mii_bus;
-out:
- of_node_put(mdio_np);
-
- return err;
+ return 0;
}
static void rswitch_mii_unregister(struct rswitch_device *rdev)
--
2.39.5 (Apple Git-154)
^ permalink raw reply related
* [PATCH] fix: net: renesas: rswitch_mii_register: fix double of_node_put after of_mdiobus_register
From: WenTao Liang @ 2026-06-26 15:24 UTC (permalink / raw)
To: netdev
Cc: Yoshihiro Shimoda, David S . Miller, Jakub Kicinski, Paolo Abeni,
stable, linux-kernel, WenTao Liang
After of_mdiobus_register succeeds, the mdio_np reference ownership is
transferred to the mii_bus device (released via fwnode_handle_put during
mdiobus_release). The success path calls of_node_put(mdio_np) which,
combined with the automatic release via bus teardown, results in a double
put and refcount underflow.
Move of_node_put so it is only called in the error path where
of_mdiobus_register failed. On success, the bus driver manages the
reference lifecycle.
Cc: stable@vger.kernel.org
Fixes: 3590918b5d07 ("net: ethernet: renesas: Add support for Ethernet Switch")
Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
---
drivers/net/ethernet/renesas/rswitch_main.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/renesas/rswitch_main.c b/drivers/net/ethernet/renesas/rswitch_main.c
index 6fe964816322..c33add28a70c 100644
--- a/drivers/net/ethernet/renesas/rswitch_main.c
+++ b/drivers/net/ethernet/renesas/rswitch_main.c
@@ -1387,13 +1387,13 @@ static int rswitch_mii_register(struct rswitch_device *rdev)
err = of_mdiobus_register(mii_bus, mdio_np);
if (err < 0) {
mdiobus_free(mii_bus);
- goto out;
+ of_node_put(mdio_np);
+ return err;
}
rdev->etha->mii = mii_bus;
-out:
- of_node_put(mdio_np);
+ return 0;
return err;
}
--
2.39.5 (Apple Git-154)
^ permalink raw reply related
* Re: [PATCH net] net: gianfar: use of_irq_get()
From: Simon Horman @ 2026-06-26 15:23 UTC (permalink / raw)
To: Rosen Penev
Cc: netdev, claudiu.manoil, andrew+netdev, davem, edumazet, kuba,
pabeni, afleming, linux-kernel
In-Reply-To: <CAKxU2N__hbPOrPe3JUeTLF6d6+=uN+p5ez78rVg6cnrekkvQPw@mail.gmail.com>
On Thu, Jun 25, 2026 at 05:42:05PM -0700, Rosen Penev wrote:
> On Thu, Jun 25, 2026 at 2:36 AM Simon Horman <horms@kernel.org> wrote:
...
> Meh I'll submit to net-next. This is way too messy to fix for net.
Thanks. Be aware that net-next is currently closed for the merge window.
I expect it will repoen next week.
^ permalink raw reply
* Re: [PATCH] octeontx2-af: Free BPID bitmap on setup failure
From: Simon Horman @ 2026-06-26 15:22 UTC (permalink / raw)
To: haoxiang_li2024
Cc: sgoutham, lcherian, gakula, hkelam, sbhatta, andrew+netdev, davem,
edumazet, kuba, pabeni, netdev, linux-kernel, stable
In-Reply-To: <78397a8d.5bc.19efc3325e6.Coremail.haoxiang_li2024@163.com>
On Thu, Jun 25, 2026 at 08:34:31AM +0800, haoxiang_li2024 wrote:
>
>
> At 2026-06-25 01:09:30, "Simon Horman" <horms@kernel.org> wrote:
> >On Tue, Jun 23, 2026 at 07:43:16PM +0800, Haoxiang Li wrote:
> >> nix_setup_bpids() allocates bp->bpids with rvu_alloc_bitmap(), which uses
> >> a plain kcalloc(). If any of the following devm_kcalloc() allocations for
> >> the BPID mapping arrays fails, the function returns without freeing the
> >> bitmap. Free the BPID bitmap before returning from those error paths.
> >>
> >> Fixes: d6212d2e41a0 ("octeontx2-af: Create BPIDs free pool")
> >> Cc: stable@vger.kernel.org
> >> Signed-off-by: Haoxiang Li <haoxiang_li2024@163.com>
> >
> >Reviewed-by: Simon Horman <horms@kernel.org>
> >
> >I am wondering if you did a pass for any other similar problems
> >with users of rvu_alloc_bitmap.
>
> Thanks for your review! Yes, I did. I found similar issues in
> nix_setup_ipolicers() and rvu_setup_msix_resources(), and
> I will address them in follow-up patches.
Likewise, thanks.
^ permalink raw reply
* [PATCH] fix: net: mediatek: mtk_star_mdio_init: fix double of_node_put after devm_of_mdiobus_register
From: WenTao Liang @ 2026-06-26 15:20 UTC (permalink / raw)
To: Daniel Borkmann, netdev
Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, stable,
linux-kernel, WenTao Liang
After devm_of_mdiobus_register succeeds, the mdio_node reference
ownership is transferred to the mii_bus device (released via
mdiobus_release on device teardown). However, the function
unconditionally calls of_node_put(mdio_node) after registration, causing
a double put.
Only call of_node_put when devm_of_mdiobus_register fails (i.e., when
ownership was not transferred). On success, the bus driver manages the
reference lifecycle.
Cc: stable@vger.kernel.org
Fixes: 9ed0a3fac08b ("net: ethernet: mtk-star-emac: use devm_of_mdiobus_register()")
Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
---
drivers/net/ethernet/mediatek/mtk_star_emac.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index b83886a41121..b949dd240e6b 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -1446,7 +1446,10 @@ static int mtk_star_mdio_init(struct net_device *ndev)
priv->mii->priv = priv;
ret = devm_of_mdiobus_register(dev, priv->mii, mdio_node);
+ if (ret)
+ of_node_put(mdio_node);
+ return ret;
out_put_node:
of_node_put(mdio_node);
return ret;
--
2.39.5 (Apple Git-154)
^ 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