Re: [PATCH] ieee802154: nl-mac: validate device pointers before dereference
From: Andrew Lunn
Date: Mon Nov 02 2026 - 09:07:52 EST
On Mon, Nov 02, 2026 at 08:17:21AM +0530, Kalpesh Solanki wrote:
> On Mon, Nov 02, 2026 at 01:13:xx +0100, Andrew Lunn wrote:
> > Did you consider the other fix? Is there a use case for setting a TUN
> > interface to ARPHRD_IEEE802154? If not, maybe return EOPNOTSUPP, or
> > EINVAL?
> >
> > Andrew
>
> Hi Andrew,
>
> Thanks for reviewing and raising this point!
>
> Regarding whether there is a use case for setting a TUN interface to
> ARPHRD_IEEE802154:
> In real hardware/subsystem usage, virtual 802.15.4 interfaces are typically
> handled via mac802154_hwsim or fakelb (which properly allocate wpan_phy and
> dev->ieee802154_ptr), rather than raw TUN. However, tun.c explicitly recognizes
> ARPHRD_IEEE802154 and ARPHRD_IEEE802154_MONITOR in tun_get_addr_len():
>
> case ARPHRD_IEEE802154:
> case ARPHRD_IEEE802154_MONITOR:
> return IEEE802154_EXTENDED_ADDR_LEN;
I looked at the history. Those two were added along with a bunch of
other ARPHRD_ values. There is nothing i could see to indicate
IEEE802154 was a deliberate choice. So i think you need the IEEE802154
Maintainers to comment on if this is useful or not.
> 1. Subsystem robustness / Defense-in-depth:
> ieee802154_llsec_dump_table(), ieee802154_dump_iface(), and
> ieee802154_nl_get_dev() assumed that any netdevice in the namespace
> with dev->type == ARPHRD_IEEE802154 has valid ieee802154_ptr and
> mlme_ops. When that assumption fails, it triggers a NULL dereference
> while holding genl_mutex, leaving the mutex permanently locked and
> deadlocking generic netlink system-wide for unprivileged users.
Which is good. An Opps with a splat makes it clear there is a bug. If
anybody cares, it will get reported and fixed.
Subsystem robustness / Defense-in-depth generally results in bugs
being hidden, rather than exposed.
The fact ieee802154 has ieee802154_ptr and the code unconditionally
accesses it suggests it is actually needed. So the commit message in
your change needs to argue why TUN is special and does not need
it. The commit message is all about "Why?". Why did you decided to fix
it this way, rather than some other way.
Is the correct fix to actually set ieee802154_ptr to something?
> Other parts of the ieee802154 subsystem already make this defensive check:
> - net/ieee802154/6lowpan/core.c (lowpan_newlink):
> if (wdev->type != ARPHRD_IEEE802154 || !wdev->ieee802154_ptr)
> - net/ieee802154/socket.c:
> if (dev->type == ARPHRD_IEEE802154 && dev->ieee802154_ptr && ...)
>
> Guarding nl-mac.c ensures the IEEE 802.15.4 netlink handlers are safe
> regardless of how an ARPHRD_IEEE802154 device was created or modified.
Now look at the history of this. Does the commit message adding this
code suggest why these checks are there?
I also wondered if IEEE802154 is special? struct net_device has:
#if IS_ENABLED(CONFIG_VLAN_8021Q)
struct vlan_info __rcu *vlan_info;
#endif
#if IS_ENABLED(CONFIG_NET_DSA)
struct dsa_port *dsa_ptr;
#endif
#if IS_ENABLED(CONFIG_TIPC)
struct tipc_bearer __rcu *tipc_ptr;
#endif
#if IS_ENABLED(CONFIG_CFG80211)
struct wireless_dev *ieee80211_ptr;
#endif
#if IS_ENABLED(CONFIG_IEEE802154) || IS_ENABLED(CONFIG_6LOWPAN)
struct wpan_dev *ieee802154_ptr;
#endif
#if IS_ENABLED(CONFIG_MPLS_ROUTING)
struct mpls_dev __rcu *mpls_ptr;
#endif
#if IS_ENABLED(CONFIG_MCTP)
struct mctp_dev __rcu *mctp_ptr;
#endif
#if IS_ENABLED(CONFIG_INET_PSP)
struct psp_dev __rcu *psp_dev;
#endif
Did you look at all of these? Can any of them cause issues in the same
way as ieee802154_ptr?
Something you learn after a while. If you find a bug, look around and
see if the same bug exists close by, because it often does.
Andrew