Skip to contentSkip to conversation

net: netdev name hash leaks kernel text base

PATCH In review Zhengchuan Liang 4 participants 6 messages Oct 2

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover net: netdev name hash leaks kernel text base

Hi,

An unprivileged user can recover the kernel text base and defeat KASLR by timing SIOCGIFINDEX lookups for attacker-chosen nonexistent interface names. These lookups reach dev_get_by_name_rcu() and fail with ENODEV without requiring capabilities or changes to network devices.

dev_name_hash() passes the struct net pointer to full_name_hash() as its salt. A missing name that hashes to the same bucket as a resident name, such as "lo", requires an extra chain traversal and takes measurably longer to look up. For a known kernel image, the collision pattern across possible KASLR slides identifies the runtime address of init_net and thus the kernel text base.

I reproduced the issue as an unprivileged user on x86-64 and arm64. A tested reproducer is available privately to maintainers on request.

Zhengchuan Liang (1):
net: use random salt for netdev name hash to prevent text base leak

 net/core/dev.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
Signature · 1 line
2.25.1
#1 lore raw

PATCH 1/1 net: use random salt for netdev name hash to prevent text base leak

dev_name_hash() uses the network namespace pointer as the salt for the network device name hash table. Unprivileged users can use SIOCGIFINDEX to look up attacker-chosen nonexistent names. Timing these lookups reveals which names share a bucket with an existing name, allowing the salt to be recovered. For init_net, recovering the salt reveals the kernel text base and defeats KASLR.

Use the per-network namespace random value from net_hash_mix() as the salt instead. The value remains stable for the lifetime of the namespace. Since all name insertions and lookups use dev_name_hash(), this only changes bucket placement.

Fixes 8387ff2577eb ("vfs: make the string hashes salt the hash")
Assisted-by LLM
---
 net/core/dev.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
net/core/dev.c +5 -1
index 18dc88990510..f3eca7fa2481 100644
@@ -98,6 +98,7 @@
 #include <linux/bpf.h>
 #include <linux/bpf_trace.h>
 #include <net/net_namespace.h>
+#include <net/netns/hash.h>
 #include <net/sock.h>
 #include <net/busy_poll.h>
 #include <linux/rtnetlink.h>
@@ -193,7 +194,10 @@ static inline void dev_base_seq_inc(struct net *net)
 
 static inline struct hlist_head *dev_name_hash(struct net *net, const char *name)
 {
-	unsigned int hash = full_name_hash(net, name, strnlen(name, IFNAMSIZ));
+	unsigned long salt = net_hash_mix(net);
+	unsigned int hash;
+
+	hash = full_name_hash((void *)salt, name, strnlen(name, IFNAMSIZ));
 
 	return &net->dev_name_head[hash_32(hash, NETDEV_HASHBITS)];
 }
Signature · 1 line
2.25.1
maintainer
#2 lore raw

Re: [PATCH net 1/1] net: use random salt for netdev name hash to prevent text base leak

Quoted 34 lines · Zhengchuan Liang

dev_name_hash() uses the network namespace pointer as the salt for the network device name hash table. Unprivileged users can use SIOCGIFINDEX to look up attacker-chosen nonexistent names. Timing these lookups reveals which names share a bucket with an existing name, allowing the salt to be recovered. For init_net, recovering the salt reveals the kernel text base and defeats KASLR.

Use the per-network namespace random value from net_hash_mix() as the salt instead. The value remains stable for the lifetime of the namespace. Since all name insertions and lookups use dev_name_hash(), this only changes bucket placement.

Fixes 8387ff2577eb ("vfs: make the string hashes salt the hash")
Assisted-by LLM
---
 net/core/dev.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
net/core/dev.c +1 -0
index 18dc88990510..f3eca7fa2481 100644
@@ -98,6 +98,7 @@
 #include <linux/bpf.h>
 #include <linux/bpf_trace.h>
 #include <net/net_namespace.h>
+#include <net/netns/hash.h>
 #include <net/sock.h>
 #include <net/busy_poll.h>
 #include <linux/rtnetlink.h>

net/core/dev.c static inline void dev_base_seq_inc(struct net *net) · line 202

Quoted 10 lines
net/core/dev.c +4 -1
@@ -193,7 +194,10 @@ static inline void dev_base_seq_inc(struct net *net)
 
 static inline struct hlist_head *dev_name_hash(struct net *net, const char *name)
 {
-       unsigned int hash = full_name_hash(net, name, strnlen(name, IFNAMSIZ));
+       unsigned long salt = net_hash_mix(net);
+       unsigned int hash;
+
+       hash = full_name_hash((void *)salt, name, strnlen(name, IFNAMSIZ));
 
        return &net->dev_name_head[hash_32(hash, NETDEV_HASHBITS)];

Thanks for your patch.

CC Linus.

It seems this patch should target net-next, local KASLR attacks are not a serious concern.

Your patch would allow an attacker to disclose net_hash_mix. Leaking net->hash_mix compromises other per-netns hash tables.

u32 hash_mix is too weak for full_name_hash()

1) What about passing NULL salt instead?

net->dev_name_head is already a per-netns hash table,
and only CAP_NET_ADMIN inside that netns can add/rename devices in it.

2) I thought about widening net->hash_mix to unsigned long (get_random_long()) (but not change net_hash_mix() u32 return type to avoid side effects)

But full_name_hash() skips HASH_MIX for len < 8, any 64-bit salt passed to full_name_hash() can be recovered quite easily.

pw-bot: cr

#3 lore raw

Re: [PATCH net 1/1] net: use random salt for netdev name hash to prevent text base leak

Quoted 5 lines · Eric Dumazet

CC Linus.

It seems this patch should target net-next, local KASLR attacks are not a serious concern.

Correct: local KASLR on its own is pretty much a nothing-burger. Most hardware effectively gives it to people one way or another through timing channels in ways we can't really fix. So KASLR is really only just "some bits of randomness against remote attackers", nothing more.

And yes, filename name hashing shouldn't use anything really secret - the filename hash is much too simple and fundmanetally cannot be a secure hash - that typically you shouldn't use any *real* secret hashes for it. Using a NULL hash is not uncommon and typically better than using something you actually want to protect.

I think the most common use of salt is the dentry pointer of the parent dentry pointer. Which isn't great either, in how it exposes bits of a kernel pointer, but it basically ends up being similar to
KASLR: at some point, local kernel pointer values typically *are* something you can probe with some time and effort with timing attacks. We try to not expose it willy-nilly, but if somebody spends the effort, they can do cache and TLB probing and it's not "cryptographic security" and never will be.

So yes, don't use anything you wan tto keep *really* secret as the name hash seed.

Linus

#4 lore raw
In reply to Zhengchuan Liang
This is an automated message. This series looks like a fix, but its commit messages seem to be missing some information:

Hi!

This is an automated message. This series looks like a fix, but its commit messages seem to be missing some information:

- How the issue was discovered, e.g. hit in production, hit during development, syzbot report, manual code inspection, LLM or static analysis tool scan.

Please do not repost the series just to address the above. Instead, reply to this email with the missing information, so that reviewers can take it into account. If the series needs another revision for other reasons, please include the information in the commit messages then.

The evaluation is done by an LLM so it may be wrong, if you think that is the case please reply and explain.

#5 lore raw
Quoted 10 lines · On Thu, Oct 1, 2026 at 11:59 PM <[email protected]> wrote:

Hi!

This is an automated message. This series looks like a fix, but its commit messages seem to be missing some information:

- How the issue was discovered, e.g. hit in production, hit during development, syzbot report, manual code inspection, LLM or static analysis tool scan.

The issue was discovered using an LLM.

Quoted 8 lines

Please do not repost the series just to address the above. Instead, reply to this email with the missing information, so that reviewers can take it into account. If the series needs another revision for other reasons, please include the information in the commit messages then.

The evaluation is done by an LLM so it may be wrong, if you think that is the case please reply and explain.