mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 02:17:36 -04:00
net/sched: cls_flow: Dont expose folded kernel pointers
The flow classifier falls back to addr_fold() for fields that are missing
from packet headers. In map mode, userspace controls mask, xor, rshift,
addend and divisor, and can observe the resulting classid through class
statistics. This allows a tc classifier in a user/network namespace to
recover the 32-bit folded value of skb->sk, skb_dst() or skb_nfct().
Align with standard kernel practices for pointer hashing and replace the
XOR folding with a keyed siphash (which is cryptographically secure)
Fixes: e5dfb81518 ("[NET_SCHED]: Add flow classifier")
Reported-by: Kyle Zeng <kylebot@openai.com>
Tested-by: Kyle Zeng <kylebot@openai.com>
Tested-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260610101839.14135-1-jhs@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
0b7b378ce6
commit
f294fc71c4
@@ -21,6 +21,7 @@
|
||||
#include <net/inet_sock.h>
|
||||
|
||||
#include <net/pkt_cls.h>
|
||||
#include <linux/siphash.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/route.h>
|
||||
#include <net/flow_dissector.h>
|
||||
@@ -57,11 +58,15 @@ struct flow_filter {
|
||||
struct rcu_work rwork;
|
||||
};
|
||||
|
||||
static siphash_aligned_key_t flow_keys_secret __read_mostly;
|
||||
|
||||
static inline u32 addr_fold(void *addr)
|
||||
{
|
||||
unsigned long a = (unsigned long)addr;
|
||||
|
||||
return (a & 0xFFFFFFFF) ^ (BITS_PER_LONG > 32 ? a >> 32 : 0);
|
||||
#ifdef CONFIG_64BIT
|
||||
return (u32)siphash_1u64((u64)addr, &flow_keys_secret);
|
||||
#else
|
||||
return (u32)siphash_1u32((u32)addr, &flow_keys_secret);
|
||||
#endif
|
||||
}
|
||||
|
||||
static u32 flow_get_src(const struct sk_buff *skb, const struct flow_keys *flow)
|
||||
@@ -596,6 +601,7 @@ static int flow_init(struct tcf_proto *tp)
|
||||
return -ENOBUFS;
|
||||
INIT_LIST_HEAD(&head->filters);
|
||||
rcu_assign_pointer(tp->root, head);
|
||||
net_get_random_once(&flow_keys_secret, sizeof(flow_keys_secret));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user