mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH net] neighbour: stop using device addresses in hashes
@ 2026-10-06 22:41 Kyle Zeng
  2026-10-06 22:44 ` netdev-bot+sinfo
  2026-10-07  8:25 ` Ido Schimmel
  0 siblings, 2 replies; 4+ messages in thread
From: Kyle Zeng @ 2026-10-06 22:41 UTC (permalink / raw)
  To: netdev
  Cc: linux-doc, linux-kernel, dsahern, idosch, outbounddisclosures, Kyle Zeng

RTM_GETNEIGHTBL exposes the live hash multiplier and bucket mask. For
ARP, that multiplier is applied to the IPv4 key XOR hash32_ptr(dev).
Since hash32_ptr() merely folds the address, timing chosen-key misses
through the unprivileged SIOCGARP ioctl can reveal the folded address
of the loopback net_device. NDISC uses the same address-dependent
first hash term.

Give each net_device an independent random neighbour hash discriminator
at allocation time and use it in both protocol hashes. Keep it immutable
so that lookups, insertion and rehashing agree even if the device's
ifindex or network namespace changes. This retains the cross-namespace
hash distribution that motivated using the device pointer, without
putting a kernel address into the observable hash. A dedicated value
also avoids making a salt used by unrelated network hashes observable.

The existing NDTA_CONFIG fields and neighbour key comparisons can stay
unchanged. Update the net_device cacheline documentation and assertions
for the new read-mostly field.

Fixes: b14f243a42c7 ("net: Dont use ifindices in hash fns")
Assisted-by: Codex:gpt-6-astra
Signed-off-by: Kyle Zeng <kylebot@openai.com>
---
 Documentation/networking/net_cachelines/net_device.rst | 1 +
 include/linux/netdevice.h                              | 2 ++
 include/net/arp.h                                      | 3 +--
 include/net/ndisc.h                                    | 3 +--
 net/core/dev.c                                         | 4 +++-
 5 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/Documentation/networking/net_cachelines/net_device.rst b/Documentation/networking/net_cachelines/net_device.rst
index 512f6d6fa3d8f8b4a861b87b1b2d5f8c4156d6cf..f6e8e7522ea73e25f0eea304fef5676c3be57c8a 100644
--- a/Documentation/networking/net_cachelines/net_device.rst
+++ b/Documentation/networking/net_cachelines/net_device.rst
@@ -30,6 +30,7 @@ xdp_features_t                      xdp_features
 struct net_device_ops*              netdev_ops                  read_mostly                             netdev_core_pick_tx,netdev_start_xmit(tx)
 struct xdp_metadata_ops*            xdp_metadata_ops
 int                                 ifindex                                         read_mostly         ip6_rcv_core
+u32                                 neigh_hash_mix              read_mostly         read_mostly         arp_hashfn,ndisc_hashfn(tx/rx)
 unsigned_short                      gflags
 unsigned_short                      hard_header_len             read_mostly         read_mostly         ip6_xmit(tx);gro_list_prepare(rx)
 unsigned_int                        mtu                         read_mostly                             ip_finish_output2
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 87cafc932e9e6584405821a87be0e31e0fc65b77..b7fd5c40bb7831f403c4558e2fcdacad50b8cdd8 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1878,6 +1878,7 @@ enum netdev_reg_state {
  *				disabled together with the latter.
  *
  *	@ifindex:	interface index
+ *	@neigh_hash_mix: Immutable per-device random salt for neighbour table hashing
  *	@group:		The group the device belongs to
  *
  *	@stats:		Statistics struct, which was left as a legacy, use
@@ -2209,6 +2210,7 @@ struct net_device {
 	enum netdev_stat_type	pcpu_stat_type:8;
 	netdev_features_t	features;
 	struct inet6_dev __rcu	*ip6_ptr;
+	u32			neigh_hash_mix;
 	__cacheline_group_end(net_device_read_txrx);
 
 	/* RX read-mostly hotpath */
diff --git a/include/net/arp.h b/include/net/arp.h
index e8747e0713c79f6f4934bb8474498f59cc5b189c..f32d2318ba08353e5c0f31479d102043a9d8127a 100644
--- a/include/net/arp.h
+++ b/include/net/arp.h
@@ -4,7 +4,6 @@
 #define _ARP_H
 
 #include <linux/if_arp.h>
-#include <linux/hash.h>
 #include <net/neighbour.h>
 
 
@@ -13,7 +12,7 @@ extern struct neigh_table arp_tbl;
 static inline u32 arp_hashfn(const void *pkey, const struct net_device *dev, u32 *hash_rnd)
 {
 	u32 key = *(const u32 *)pkey;
-	u32 val = key ^ hash32_ptr(dev);
+	u32 val = key ^ dev->neigh_hash_mix;
 
 	return val * hash_rnd[0];
 }
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index 9e5379ad2d8e004e1c6be2ed6b37aaf4fb55d553..ab9c7750052e8ffc53fe1c9b69f27cb239b4e4c4 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -54,7 +54,6 @@ enum {
 #include <linux/types.h>
 #include <linux/if_arp.h>
 #include <linux/netdevice.h>
-#include <linux/hash.h>
 
 #include <net/neighbour.h>
 
@@ -346,7 +345,7 @@ static inline u32 ndisc_hashfn(const void *pkey, const struct net_device *dev, _
 {
 	const u32 *p32 = pkey;
 
-	return (((p32[0] ^ hash32_ptr(dev)) * hash_rnd[0]) +
+	return (((p32[0] ^ dev->neigh_hash_mix) * hash_rnd[0]) +
 		(p32[1] * hash_rnd[1]) +
 		(p32[2] * hash_rnd[2]) +
 		(p32[3] * hash_rnd[3]));
diff --git a/net/core/dev.c b/net/core/dev.c
index f660fccfc0dbc56d7e1a9643525229b278bca547..d6922b4ee64fe0fe60896a8ce69cf90bf174a156 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -12131,6 +12131,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
 		return NULL;
 
 	dev->priv_len = sizeof_priv;
+	dev->neigh_hash_mix = get_random_u32();
 
 	ref_tracker_dir_init(&dev->refcnt_tracker, 128, "netdev");
 #ifdef CONFIG_PCPU_DEV_REFCNT
@@ -13353,7 +13354,8 @@ static void __init net_dev_struct_check(void)
 	CACHELINE_ASSERT_GROUP_MEMBER(struct net_device, net_device_read_txrx, hard_header_len);
 	CACHELINE_ASSERT_GROUP_MEMBER(struct net_device, net_device_read_txrx, features);
 	CACHELINE_ASSERT_GROUP_MEMBER(struct net_device, net_device_read_txrx, ip6_ptr);
-	CACHELINE_ASSERT_GROUP_SIZE(struct net_device, net_device_read_txrx, 46);
+	CACHELINE_ASSERT_GROUP_MEMBER(struct net_device, net_device_read_txrx, neigh_hash_mix);
+	CACHELINE_ASSERT_GROUP_SIZE(struct net_device, net_device_read_txrx, 50);
 
 	/* RX read-mostly hotpath */
 	CACHELINE_ASSERT_GROUP_MEMBER(struct net_device, net_device_read_rx, ptype_specific);
-- 
2.53.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net] neighbour: stop using device addresses in hashes
  2026-10-06 22:41 [PATCH net] neighbour: stop using device addresses in hashes Kyle Zeng
@ 2026-10-06 22:44 ` netdev-bot+sinfo
  2026-10-07  8:25 ` Ido Schimmel
  1 sibling, 0 replies; 4+ messages in thread
From: netdev-bot+sinfo @ 2026-10-06 22:44 UTC (permalink / raw)
  To: Kyle Zeng
  Cc: netdev, linux-doc, linux-kernel, dsahern, idosch, outbounddisclosures

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.

 - Whether the issue was actually triggered, or is only theoretical
   (e.g. found by code inspection). If it was triggered please include
   the symptoms, like the stack trace or error messages.

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.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net] neighbour: stop using device addresses in hashes
  2026-10-06 22:41 [PATCH net] neighbour: stop using device addresses in hashes Kyle Zeng
  2026-10-06 22:44 ` netdev-bot+sinfo
@ 2026-10-07  8:25 ` Ido Schimmel
  2026-10-07  8:54   ` Eric Dumazet
  1 sibling, 1 reply; 4+ messages in thread
From: Ido Schimmel @ 2026-10-07  8:25 UTC (permalink / raw)
  To: Kyle Zeng, edumazet
  Cc: netdev, linux-doc, linux-kernel, dsahern, outbounddisclosures

On Tue, Oct 06, 2026 at 03:41:18PM -0700, Kyle Zeng wrote:
> RTM_GETNEIGHTBL exposes the live hash multiplier and bucket mask. For
> ARP, that multiplier is applied to the IPv4 key XOR hash32_ptr(dev).
> Since hash32_ptr() merely folds the address, timing chosen-key misses
> through the unprivileged SIOCGARP ioctl can reveal the folded address
> of the loopback net_device. NDISC uses the same address-dependent
> first hash term.
> 
> Give each net_device an independent random neighbour hash discriminator
> at allocation time and use it in both protocol hashes. Keep it immutable
> so that lookups, insertion and rehashing agree even if the device's
> ifindex or network namespace changes. This retains the cross-namespace
> hash distribution that motivated using the device pointer, without
> putting a kernel address into the observable hash. A dedicated value
> also avoids making a salt used by unrelated network hashes observable.
> 
> The existing NDTA_CONFIG fields and neighbour key comparisons can stay
> unchanged. Update the net_device cacheline documentation and assertions
> for the new read-mostly field.
> 
> Fixes: b14f243a42c7 ("net: Dont use ifindices in hash fns")
> Assisted-by: Codex:gpt-6-astra
> Signed-off-by: Kyle Zeng <kylebot@openai.com>
> ---
>  Documentation/networking/net_cachelines/net_device.rst | 1 +
>  include/linux/netdevice.h                              | 2 ++
>  include/net/arp.h                                      | 3 +--
>  include/net/ndisc.h                                    | 3 +--
>  net/core/dev.c                                         | 4 +++-
>  5 files changed, 8 insertions(+), 5 deletions(-)

Eric,

Given [1], do you think this should be targeted at net-next?

In net-next the neighbour tables are per-netns, so we can return to
hashing based on the device index instead of its pointer. Something like
[2].

[1] https://lore.kernel.org/netdev/CAL4WiiqWwV+8JaYjsHrWDvoSt8Ng01xs9Orv4xhRpFAvhMnD6w@mail.gmail.com/
[2]
diff --git a/include/net/arp.h b/include/net/arp.h
index e932def63d62..9e583624f5b2 100644
--- a/include/net/arp.h
+++ b/include/net/arp.h
@@ -4,7 +4,6 @@
 #define _ARP_H
 
 #include <linux/if_arp.h>
-#include <linux/hash.h>
 #include <net/neighbour.h>
 
 static inline struct neigh_table *arp_table(struct net *net)
@@ -15,7 +14,7 @@ static inline struct neigh_table *arp_table(struct net *net)
 static inline u32 arp_hashfn(const void *pkey, const struct net_device *dev, u32 *hash_rnd)
 {
 	u32 key = *(const u32 *)pkey;
-	u32 val = key ^ hash32_ptr(dev);
+	u32 val = key ^ dev->ifindex;
 
 	return val * hash_rnd[0];
 }
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index 96e3bb6e83af..a97be2e69409 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -54,7 +54,6 @@ enum {
 #include <linux/types.h>
 #include <linux/if_arp.h>
 #include <linux/netdevice.h>
-#include <linux/hash.h>
 
 #include <net/neighbour.h>
 
@@ -355,7 +354,7 @@ static inline u32 ndisc_hashfn(const void *pkey, const struct net_device *dev, _
 {
 	const u32 *p32 = pkey;
 
-	return (((p32[0] ^ hash32_ptr(dev)) * hash_rnd[0]) +
+	return (((p32[0] ^ dev->ifindex) * hash_rnd[0]) +
 		(p32[1] * hash_rnd[1]) +
 		(p32[2] * hash_rnd[2]) +
 		(p32[3] * hash_rnd[3]));


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net] neighbour: stop using device addresses in hashes
  2026-10-07  8:25 ` Ido Schimmel
@ 2026-10-07  8:54   ` Eric Dumazet
  0 siblings, 0 replies; 4+ messages in thread
From: Eric Dumazet @ 2026-10-07  8:54 UTC (permalink / raw)
  To: Ido Schimmel
  Cc: Kyle Zeng, netdev, linux-doc, linux-kernel, dsahern, outbounddisclosures

Le mer. 7 oct. 2026 à 10:25, Ido Schimmel <idosch@nvidia.com> a écrit :
>
> On Tue, Oct 06, 2026 at 03:41:18PM -0700, Kyle Zeng wrote:
> > RTM_GETNEIGHTBL exposes the live hash multiplier and bucket mask. For
> > ARP, that multiplier is applied to the IPv4 key XOR hash32_ptr(dev).
> > Since hash32_ptr() merely folds the address, timing chosen-key misses
> > through the unprivileged SIOCGARP ioctl can reveal the folded address
> > of the loopback net_device. NDISC uses the same address-dependent
> > first hash term.
> >
> > Give each net_device an independent random neighbour hash discriminator
> > at allocation time and use it in both protocol hashes. Keep it immutable
> > so that lookups, insertion and rehashing agree even if the device's
> > ifindex or network namespace changes. This retains the cross-namespace
> > hash distribution that motivated using the device pointer, without
> > putting a kernel address into the observable hash. A dedicated value
> > also avoids making a salt used by unrelated network hashes observable.
> >
> > The existing NDTA_CONFIG fields and neighbour key comparisons can stay
> > unchanged. Update the net_device cacheline documentation and assertions
> > for the new read-mostly field.
> >
> > Fixes: b14f243a42c7 ("net: Dont use ifindices in hash fns")
> > Assisted-by: Codex:gpt-6-astra
> > Signed-off-by: Kyle Zeng <kylebot@openai.com>
> > ---
> >  Documentation/networking/net_cachelines/net_device.rst | 1 +
> >  include/linux/netdevice.h                              | 2 ++
> >  include/net/arp.h                                      | 3 +--
> >  include/net/ndisc.h                                    | 3 +--
> >  net/core/dev.c                                         | 4 +++-
> >  5 files changed, 8 insertions(+), 5 deletions(-)
>
> Eric,
>
> Given [1], do you think this should be targeted at net-next?
>
> In net-next the neighbour tables are per-netns, so we can return to
> hashing based on the device index instead of its pointer. Something like
> [2].

Definitely this can target net-next and avoid merge conflicts.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-10-07  8:54 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-06 22:41 [PATCH net] neighbour: stop using device addresses in hashes Kyle Zeng
2026-10-06 22:44 ` netdev-bot+sinfo
2026-10-07  8:25 ` Ido Schimmel
2026-10-07  8:54   ` Eric Dumazet

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®