]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
xfrm: Sanitize marks before insert
authorPaul Chaignon <paul.chaignon@gmail.com>
Wed, 7 May 2025 11:31:58 +0000 (13:31 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 4 Jun 2025 12:38:05 +0000 (14:38 +0200)
[ Upstream commit 0b91fda3a1f044141e1e615456ff62508c32b202 ]

Prior to this patch, the mark is sanitized (applying the state's mask to
the state's value) only on inserts when checking if a conflicting XFRM
state or policy exists.

We discovered in Cilium that this same sanitization does not occur
in the hot-path __xfrm_state_lookup. In the hot-path, the sk_buff's mark
is simply compared to the state's value:

    if ((mark & x->mark.m) != x->mark.v)
        continue;

Therefore, users can define unsanitized marks (ex. 0xf42/0xf00) which will
never match any packet.

This commit updates __xfrm_state_insert and xfrm_policy_insert to store
the sanitized marks, thus removing this footgun.

This has the side effect of changing the ip output, as the
returned mark will have the mask applied to it when printed.

Fixes: 3d6acfa7641f ("xfrm: SA lookups with mark")
Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>
Signed-off-by: Louis DeLosSantos <louis.delos.devel@gmail.com>
Co-developed-by: Louis DeLosSantos <louis.delos.devel@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_state.c

index 55ef8e83292439b25e6a8406bff0ba705c743f23..16958656b6d4338f3e85c7ea1947e66d7c6d94b3 100644 (file)
@@ -1594,6 +1594,9 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
        struct xfrm_policy *delpol;
        struct hlist_head *chain;
 
+       /* Sanitize mark before store */
+       policy->mark.v &= policy->mark.m;
+
        spin_lock_bh(&net->xfrm.xfrm_policy_lock);
        chain = policy_hash_bysel(net, &policy->selector, policy->family, dir);
        if (chain)
index ff8159bae7bbfc6cf4396ceb98fd5bc6d71cf575..c1bc5d780f64079e92baf743b5adc1f21091f09a 100644 (file)
@@ -1277,6 +1277,9 @@ static void __xfrm_state_insert(struct xfrm_state *x)
 
        list_add(&x->km.all, &net->xfrm.state_all);
 
+       /* Sanitize mark before store */
+       x->mark.v &= x->mark.m;
+
        h = xfrm_dst_hash(net, &x->id.daddr, &x->props.saddr,
                          x->props.reqid, x->props.family);
        hlist_add_head_rcu(&x->bydst, net->xfrm.state_bydst + h);