* [PATCH] ieee802154: nl-mac: validate device pointers before dereference
@ 2026-11-01 9:22 Kalpesh Solanki
2026-11-01 19:43 ` Andrew Lunn
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Kalpesh Solanki @ 2026-11-01 9:22 UTC (permalink / raw)
To: alex.aring, stefan, miquel.raynal, davem, edumazet, kuba, pabeni
Cc: horms, linux-wpan, netdev, linux-kernel,
syzbot+9ea34da5ca6100593c90, Kalpesh Solanki, stable
A virtual network device (such as a TUN interface) can have its link
type set to ARPHRD_IEEE802154 via ioctl(tun_fd, TUNSETLINK,
ARPHRD_IEEE802154). However, such devices do not have an IEEE 802.15.4
private context allocated (dev->ieee802154_ptr is NULL) and do not
register MAC operations (dev->ml_priv / ieee802154_mlme_ops(dev) is NULL).
When dumping security keys via IEEE802154_LLSEC_LIST_KEY,
ieee802154_llsec_dump_table() iterates through all net devices and
dereferences data.ops->llsec assuming that any ARPHRD_IEEE802154 device
has valid mlme ops. Because data.ops is NULL, this causes an immediate
null-pointer dereference / General Protection Fault:
Oops: general protection fault, probably for non-canonical address
KASAN: null-ptr-deref in range [0x0000000000000038-0x000000000000003f]
RIP: 0010:ieee802154_llsec_dump_table+0x204/0x5d0
Call Trace:
<TASK>
genl_dumpit+0x125/0x230 net/netlink/genetlink.c:1026
netlink_dump+0x53b/0xd00 net/netlink/af_netlink.c:2351
__netlink_dump_start+0x6d6/0x990 net/netlink/af_netlink.c:2466
Similarly, ieee802154_dump_iface() and ieee802154_nl_get_dev() assume
that ARPHRD_IEEE802154 devices have valid dev->ieee802154_ptr and
ieee802154_mlme_ops(dev) pointers.
Fix this by ensuring dev->ieee802154_ptr and ieee802154_mlme_ops(dev)
are non-NULL before proceeding in ieee802154_nl_get_dev(),
ieee802154_dump_iface(), and ieee802154_llsec_dump_table().
Fixes: 3e9c156e2c21 ("ieee802154: add netlink interfaces for llsec")
Cc: stable@vger.kernel.org
Reported-by: syzbot+9ea34da5ca6100593c90@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=9ea34da5ca6100593c90
Tested-by: syzbot+9ea34da5ca6100593c90@syzkaller.appspotmail.com
Signed-off-by: Kalpesh Solanki <skalpesh942@gmail.com>
---
net/ieee802154/nl-mac.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
index 74ef0a310af..1acde5af4b5 100644
--- a/net/ieee802154/nl-mac.c
+++ b/net/ieee802154/nl-mac.c
@@ -162,7 +162,8 @@ static struct net_device *ieee802154_nl_get_dev(struct genl_info *info)
if (!dev)
return NULL;
- if (dev->type != ARPHRD_IEEE802154) {
+ if (dev->type != ARPHRD_IEEE802154 || !dev->ieee802154_ptr ||
+ !ieee802154_mlme_ops(dev)) {
dev_put(dev);
return NULL;
}
@@ -437,7 +438,8 @@ int ieee802154_dump_iface(struct sk_buff *skb, struct netlink_callback *cb)
idx = 0;
for_each_netdev(net, dev) {
- if (idx < s_idx || dev->type != ARPHRD_IEEE802154)
+ if (idx < s_idx || dev->type != ARPHRD_IEEE802154 ||
+ !dev->ieee802154_ptr || !ieee802154_mlme_ops(dev))
goto cont;
if (ieee802154_nl_fill_iface(skb, NETLINK_CB(cb->skb).portid,
@@ -771,7 +773,8 @@ ieee802154_llsec_dump_table(struct sk_buff *skb, struct netlink_callback *cb,
int rc;
for_each_netdev(net, dev) {
- if (idx < first_dev || dev->type != ARPHRD_IEEE802154)
+ if (idx < first_dev || dev->type != ARPHRD_IEEE802154 ||
+ !dev->ieee802154_ptr || !ieee802154_mlme_ops(dev))
goto skip;
data.ops = ieee802154_mlme_ops(dev);
--
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] ieee802154: nl-mac: validate device pointers before dereference
2026-11-01 9:22 [PATCH] ieee802154: nl-mac: validate device pointers before dereference Kalpesh Solanki
@ 2026-11-01 19:43 ` Andrew Lunn
2026-11-02 2:47 ` Kalpesh Solanki
2026-11-02 9:24 ` netdev-bot+sashiko
2 siblings, 0 replies; 6+ messages in thread
From: Andrew Lunn @ 2026-11-01 19:43 UTC (permalink / raw)
To: Kalpesh Solanki
Cc: alex.aring, stefan, miquel.raynal, davem, edumazet, kuba, pabeni,
horms, linux-wpan, netdev, linux-kernel,
syzbot+9ea34da5ca6100593c90, stable
On Sun, Nov 01, 2026 at 02:52:19PM +0530, Kalpesh Solanki wrote:
> A virtual network device (such as a TUN interface) can have its link
> type set to ARPHRD_IEEE802154 via ioctl(tun_fd, TUNSETLINK,
> ARPHRD_IEEE802154). However, such devices do not have an IEEE 802.15.4
> private context allocated (dev->ieee802154_ptr is NULL) and do not
> register MAC operations (dev->ml_priv / ieee802154_mlme_ops(dev) is NULL).
> Fix this by ensuring dev->ieee802154_ptr and ieee802154_mlme_ops(dev)
> are non-NULL before proceeding in ieee802154_nl_get_dev(),
> ieee802154_dump_iface(), and ieee802154_llsec_dump_table().
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
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ieee802154: nl-mac: validate device pointers before dereference
2026-11-01 9:22 [PATCH] ieee802154: nl-mac: validate device pointers before dereference Kalpesh Solanki
2026-11-01 19:43 ` Andrew Lunn
@ 2026-11-02 2:47 ` Kalpesh Solanki
2026-11-02 14:00 ` Andrew Lunn
2026-11-02 9:24 ` netdev-bot+sashiko
2 siblings, 1 reply; 6+ messages in thread
From: Kalpesh Solanki @ 2026-11-02 2:47 UTC (permalink / raw)
To: andrew
Cc: alex.aring, stefan, miquel.raynal, davem, edumazet, kuba, pabeni,
horms, linux-wpan, netdev, linux-kernel,
syzbot+9ea34da5ca6100593c90, stable, Kalpesh Solanki
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;
which sets the hardware address length to IEEE802154_EXTENDED_ADDR_LEN on
TUNSETLINK for userspace network stacks/simulators (such as IoT testbeds or
custom TAP-based emulators) that expect 802.15.4 addressing.
Regarding fixing this in drivers/net/tun.c vs net/ieee802154/nl-mac.c:
We considered returning -EOPNOTSUPP / -EINVAL in TUNSETLINK, but chose to
guard nl-mac.c for the following reasons:
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.
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.
2. Userspace ABI compatibility:
TUNSETLINK has historically permitted arbitrary link types on down
interfaces, and explicitly supports ARPHRD_IEEE802154 address lengths.
Disallowing it in TUNSETLINK might break existing user tools or test
frameworks that use TAP/TUN with this link type.
That said, if the consensus is that TUNSETLINK should reject
ARPHRD_IEEE802154 (or arbitrary link types that lack driver backend support),
I would be more than happy to submit a follow-up patch for tun.c as well.
Do you think we should reject it in tun.c in addition to guarding nl-mac.c,
or do you prefer restricting TUNSETLINK instead?
Thanks,
Kalpesh
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] ieee802154: nl-mac: validate device pointers before dereference
2026-11-02 2:47 ` Kalpesh Solanki
@ 2026-11-02 14:00 ` Andrew Lunn
0 siblings, 0 replies; 6+ messages in thread
From: Andrew Lunn @ 2026-11-02 14:00 UTC (permalink / raw)
To: Kalpesh Solanki
Cc: alex.aring, stefan, miquel.raynal, davem, edumazet, kuba, pabeni,
horms, linux-wpan, netdev, linux-kernel,
syzbot+9ea34da5ca6100593c90, stable
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
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ieee802154: nl-mac: validate device pointers before dereference
2026-11-01 9:22 [PATCH] ieee802154: nl-mac: validate device pointers before dereference Kalpesh Solanki
2026-11-01 19:43 ` Andrew Lunn
2026-11-02 2:47 ` Kalpesh Solanki
@ 2026-11-02 9:24 ` netdev-bot+sashiko
2 siblings, 0 replies; 6+ messages in thread
From: netdev-bot+sashiko @ 2026-11-02 9:24 UTC (permalink / raw)
To: skalpesh942
Cc: alex.aring, stefan, miquel.raynal, davem, edumazet, kuba, pabeni,
horms, linux-wpan, netdev, linux-kernel,
syzbot+9ea34da5ca6100593c90, stable
Thank you for your contribution! Sashiko AI review found 1 potential
issue(s) to consider.
Critical: 0 · High: 1 (2) · Medium: 0 (2) · Low: 0
If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).
- [High] The fix is incomplete within the same legacy IEEE802154
genetlink family.
Pre-existing issues:
- [High] This problem wasn't introduced by this patch, but several non-
netlink IEEE 802.15.4 paths also treat `dev->type ==…
- [High] This problem wasn't introduced by this patch, but
ieee802154_dump_iface() and ieee802154_llsec_dump_table() walk…
- [Medium] This problem wasn't introduced by this patch, but
ieee802154_llsec_dump_table() never saves its intra-table resume…
- [Medium] This problem wasn't introduced by this patch, but
llsec_iter_devkeys() (net/ieee802154/nl-mac.c:1185-1206) resets the…
--
ieee802154: nl-mac: validate device pointers before dereference
This patch adds checks for a NULL dev->ieee802154_ptr and a NULL
ieee802154_mlme_ops(dev) in ieee802154_nl_get_dev(),
ieee802154_dump_iface() and ieee802154_llsec_dump_table(). It is meant to
stop crashes on devices such as TUN interfaces whose link type was set to
ARPHRD_IEEE802154 with TUNSETLINK.
> diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
> index 74ef0a310afbb..1acde5af4b564 100644
> --- a/net/ieee802154/nl-mac.c
> +++ b/net/ieee802154/nl-mac.c
> @@ -162,7 +162,8 @@ static struct net_device *ieee802154_nl_get_dev(struct genl_info *info)
> if (!dev)
> return NULL;
>
> - if (dev->type != ARPHRD_IEEE802154) {
> + if (dev->type != ARPHRD_IEEE802154 || !dev->ieee802154_ptr ||
> + !ieee802154_mlme_ops(dev)) {
> dev_put(dev);
> return NULL;
> }
[Severity: High]
Can the IEEE802154_DEL_IFACE handler still hit the same crash?
ieee802154_del_iface() in net/ieee802154/nl-phy.c is registered in the
same nl802154_family. It does not go through ieee802154_nl_get_dev().
It looks the device up with dev_get_by_name() and only checks the link
type:
net/ieee802154/nl-phy.c:ieee802154_del_iface() {
...
dev = dev_get_by_name(genl_info_net(info), name);
if (!dev)
return rc;
if (dev->type != ARPHRD_IEEE802154)
goto out;
phy = dev->ieee802154_ptr->wpan_phy;
BUG_ON(!phy);
...
}
Take the TUN setup from the commit message (TUNSETLINK to
ARPHRD_IEEE802154 while the interface is down). An IEEE802154_DEL_IFACE
request with IEEE802154_ATTR_DEV_NAME set to the TUN name would pass the
type check and then dereference a NULL dev->ieee802154_ptr.
This op uses GENL_ADMIN_PERM, the same privilege needed for the
IEEE802154_LLSEC_LIST_KEY dump fixed here. Should ieee802154_del_iface()
get the same check?
[Severity: High]
This is a pre-existing issue, but several non-netlink 802.15.4 paths
also assume that dev->type == ARPHRD_IEEE802154 means
dev->ieee802154_ptr is valid. Would they crash with the same TUN device?
In net/ieee802154/socket.c, the short-address branch of
ieee802154_get_dev() does this. It is reachable from dgram_bind() and
dgram_sendmsg() on an unprivileged SOCK_DGRAM socket:
for_each_netdev(net, tmp) {
if (tmp->type != ARPHRD_IEEE802154)
continue;
pan_id = tmp->ieee802154_ptr->pan_id;
On an unbound socket, dgram_sendmsg() calls
dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154), which can return
the TUN device. That device is then passed to wpan_dev_hard_header():
struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
return wpan_dev->ops->header_create(skb, dev, daddr, saddr, len);
On receive, a frame written into the TUN with ETH_P_IEEE802154 goes
through ieee802154_rcv() -> ieee802154_dgram_deliver(), which reads:
pan_id = dev->ieee802154_ptr->pan_id;
short_addr = dev->ieee802154_ptr->short_addr;
hw_addr = dev->ieee802154_ptr->extended_addr;
lowpan_rcv() in net/ieee802154/6lowpan/rx.c also checks only the type
before doing this:
ldev = wdev->ieee802154_ptr->lowpan_dev;
It has no init_net restriction. Once any 6LoWPAN interface on the host
is up, a TUN in another network namespace could reach it.
ieee802154_dev_ioctl() and 6lowpan/core.c already allow for a NULL
ieee802154_ptr. Should these other sites check for it too?
> @@ -437,7 +438,8 @@ int ieee802154_dump_iface(struct sk_buff *skb, struct netlink_callback *cb)
>
> idx = 0;
> for_each_netdev(net, dev) {
> - if (idx < s_idx || dev->type != ARPHRD_IEEE802154)
> + if (idx < s_idx || dev->type != ARPHRD_IEEE802154 ||
> + !dev->ieee802154_ptr || !ieee802154_mlme_ops(dev))
> goto cont;
>
> if (ieee802154_nl_fill_iface(skb, NETLINK_CB(cb->skb).portid,
[Severity: High]
This isn't a bug introduced by this patch, but what keeps dev alive
during this walk? ieee802154_dump_iface() and
ieee802154_llsec_dump_table() loop with plain for_each_netdev(). They
hold no RTNL and no rcu_read_lock(), and take no dev_hold() on the
current device.
genl_dumpit() only takes genl_lock around the dump, because
nl802154_family has no parallel_ops. That lock does not serialize
against netdev unregistration.
The caller can't hold RTNL here either, because
ieee802154_nl_fill_iface() takes and drops it itself:
rtnl_lock();
short_addr = dev->ieee802154_ptr->short_addr;
pan_id = dev->ieee802154_ptr->pan_id;
rtnl_unlock();
RCU would not cover the llsec path, because llsec->lock_table() takes a
mutex.
Suppose the wpan interface is unregistered at the same time (ip link
del, or ieee802154_unregister_hw()). Can free_netdev() finish while the
dump is still using dev or following dev->dev_list.next?
IEEE802154_LIST_IFACE does not require GENL_ADMIN_PERM. The new
dev->ieee802154_ptr and ml_priv reads added here are part of the same
unprotected walk.
> @@ -771,7 +773,8 @@ ieee802154_llsec_dump_table(struct sk_buff *skb, struct netlink_callback *cb,
> int rc;
>
> for_each_netdev(net, dev) {
> - if (idx < first_dev || dev->type != ARPHRD_IEEE802154)
> + if (idx < first_dev || dev->type != ARPHRD_IEEE802154 ||
> + !dev->ieee802154_ptr || !ieee802154_mlme_ops(dev))
> goto skip;
>
> data.ops = ieee802154_mlme_ops(dev);
[Severity: Medium]
This is a pre-existing issue, but does ieee802154_llsec_dump_table()
lose its place inside a table when the skb fills up?
Further down, the function loads its cursors from cb->args:
data.s_idx = cb->args[1];
data.s_idx2 = cb->args[2];
The step iterators, such as llsec_iter_keys(), only advance
data->s_idx. On -EMSGSIZE the loop breaks before idx++, and only the
interface index is saved:
cb->args[0] = idx;
Nothing in nl-mac.c writes cb->args[1] or cb->args[2]. The next
callback picks the same interface and starts its table again from
index 0.
If one interface's key, device, devkey or seclevel table doesn't fit in
a single dump skb, could IEEE802154_LLSEC_LIST_KEY and the other llsec
dumps repeat the same records forever? Smaller overflows would give
duplicate records.
[Severity: Medium]
This is also a pre-existing issue, but llsec_iter_devkeys() seems to
skip device keys. It is reached through
ieee802154_llsec_dump_devkeys() -> ieee802154_llsec_dump_table():
list_for_each_entry(dpos, &data->table->devices, list) {
if (idx++ < data->s_idx)
continue;
idx2 = 0;
list_for_each_entry(kpos, &dpos->keys, list) {
if (idx2++ < data->s_idx2)
continue;
...
data->s_idx2++;
}
data->s_idx++;
}
idx2 is reset for each device, but data->s_idx2 is not. Once the first
device has emitted k keys, would the first k keys of every later device
be skipped?
The iterator still returns 0, so those devkeys would be missing from
the IEEE802154_LLSEC_LIST_DEVKEY output even when the buffer has room.
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261101092219.1278751-1-skalpesh942%40gmail.com
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ieee802154: nl-mac: validate device pointers before dereference
@ 2026-11-02 15:01 Kalpesh Solanki
0 siblings, 0 replies; 6+ messages in thread
From: Kalpesh Solanki @ 2026-11-02 15:01 UTC (permalink / raw)
To: andrew
Cc: alex.aring, stefan, miquel.raynal, davem, edumazet, kuba, pabeni,
horms, linux-wpan, netdev, linux-kernel,
syzbot+9ea34da5ca6100593c90, stable, Kalpesh Solanki
Hi Andrew,
Thank you for the thoughtful feedback and for digging into the git history.
Your point, together with the Sashiko AI review report on this patch, makes
the architectural picture very clear.
1. Analysis of Sashiko AI's findings:
Sashiko correctly pointed out that guarding only nl-mac.c is incomplete:
- net/ieee802154/nl-phy.c: ieee802154_del_iface() unconditionally reads
dev->ieee802154_ptr->wpan_phy when dev->type == ARPHRD_IEEE802154.
- net/ieee802154/socket.c: ieee802154_get_dev(), dgram_sendmsg() calling
wpan_dev_hard_header(), and ieee802154_rcv() / ieee802154_dgram_deliver()
all unconditionally dereference dev->ieee802154_ptr.
As you noted, sprinkling NULL checks across every one of these sites in the
ieee802154 subsystem would just be papering over the real issue and hiding
bugs rather than solving the fundamental cause.
2. Audit of other struct net_device subsystem pointers:
I audited the other pointers you highlighted in struct net_device:
- ieee80211_ptr (CFG80211): cfg80211 does not rely on dev->type to infer
wireless_dev; it uses dev->wireless_data or wdev backpointers, and tun.c
does not set 802.11 types in tun_get_addr_len().
- dsa_ptr (NET_DSA): strictly managed by DSA slave allocations (ARPHRD_ETHER).
- tipc_ptr (TIPC): managed through explicit bearer enable/disable, not dev->type.
- mpls_ptr / mctp_ptr: managed via rtnl/subsystem netlink ops rather than
arbitrary dev->type mapping.
ieee802154_ptr is unique because drivers/net/tun.c explicitly recognized
ARPHRD_IEEE802154 and ARPHRD_IEEE802154_MONITOR in tun_get_addr_len(),
allowing TUNSETLINK to stamp dev->type = ARPHRD_IEEE802154 onto a TUN device
without ever initializing dev->ieee802154_ptr or wpan_dev. The entire
ieee802154 subsystem operates on the invariant that any net_device with
dev->type == ARPHRD_IEEE802154 is a genuine wpan device with valid
ieee802154_ptr.
3. Proposed resolution:
Setting ieee802154_ptr to dummy ops in TUN does not make sense because TUN
devices cannot function as 802.15.4 radios (no wpan_phy, no channels, no
PAN ID, no MLME). Virtual 802.15.4 interfaces are already properly provided
by mac802154_hwsim and fakelb.
Therefore, the cleanest and most robust fix is to disallow setting
ARPHRD_IEEE802154 and ARPHRD_IEEE802154_MONITOR via TUNSETLINK in
drivers/net/tun.c (returning -EOPNOTSUPP or -EINVAL).
This single change:
- Closes the syzbot crash in nl-mac.c.
- Closes the crashes identified by Sashiko in nl-phy.c and socket.c.
- Preserves the invariant throughout net/ieee802154 that dev->type ==
ARPHRD_IEEE802154 implies a valid dev->ieee802154_ptr.
Alexander, Stefan, Miquel: as IEEE 802.15.4 maintainers, could you please
confirm if there is any legitimate use case for a TUN device claiming to be
ARPHRD_IEEE802154?
If you agree with this direction, I will withdraw this patch and submit a v2
fixing it in drivers/net/tun.c instead.
Thanks,
Kalpesh
pw-bot: cr
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-11-02 15:02 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-01 9:22 [PATCH] ieee802154: nl-mac: validate device pointers before dereference Kalpesh Solanki
2026-11-01 19:43 ` Andrew Lunn
2026-11-02 2:47 ` Kalpesh Solanki
2026-11-02 14:00 ` Andrew Lunn
2026-11-02 9:24 ` netdev-bot+sashiko
2026-11-02 15:01 Kalpesh Solanki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®