Re: [PATCH net] netlink: avoid hashing the network namespace pointer

From: Eric Dumazet

Date: Wed Oct 07 2026 - 01:43:01 EST




On 10/7/26 00:41, Kyle Zeng wrote:
The netlink rhashtable key includes a raw struct net pointer and a
user-controlled port ID. Both /proc/net/netlink and socket diagnostics
expose the table's bucket order. By binding and rebinding chosen
NETLINK_USERSOCK port IDs, an unprivileged reader can distinguish equal
buckets and recover the low bits of the Jenkins hash. Its 32-bit seed
and the limited set of kernel-image slides can then be searched offline
to recover the address of init_net.

Use the namespace's unique, non-address ID in the comparison key
instead. This ID is assigned before the per-net initializers run and
remains unchanged for the namespace's lifetime. The lookup key and
object hash are still built by netlink_compare_arg_init(), keeping
lookup, insertion, removal and rehashing consistent while preserving
namespace separation. Neither public table walker needs to change.


Please use net->net_cookie instead.

It has the same value in current trees (net->net_cookie = ns_tree_gen_id(net)),
but ns.ns_id only appeared in 6.18, while your Fixes: tag points to
a 2015 commit.

net_cookie is set at the top of setup_net() in stable kernels >= 5.15,
so backports would be trivial.

> struct netlink_compare_arg
> {
> - possible_net_t pnet;
> + u64 netns_id;

'netns_id' is confusing, we already have NETNSA_NSID and net->netns_ids.

> - !net_eq(sock_net(&nlk->sk), read_pnet(&x->pnet));
> + sock_net(&nlk->sk)->ns.ns_id != x->netns_id;

We now dereference sock_net() from netlink_compare(), under RCU,
possibly for a socket of a dismantling netns.

I think this is fine (sockets are freed after call_rcu(), and
cleanup_net() has an rcu_barrier() before freeing the netns),
but please mention it in the changelog.

Thanks.