Thread (3 messages) 3 messages, 3 authors, 25m ago

[PATCH v2] xfrm: account XFRMA_IF_ID and XFRMA_OFFLOAD_DEV in acquire/polexpire/expire size calculations

flat view
HOTtoday

From: Adrian Martinez Garcia <hidden>
Date: 2026-10-12 14:39:44
Subsystem: networking [general], networking [ipsec], the rest · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Steffen Klassert, Herbert Xu, Linus Torvalds

From 534cb2b5fb8da81677f2955aac8a98d9aa89694b Mon Sep 17 00:00:00 2001
From: Adrian Martinez <redacted>
Date: Sun, 11 Oct 2026 06:53:31 +0000
Subject: [PATCH] xfrm: account XFRMA_IF_ID and XFRMA_OFFLOAD_DEV in
 acquire/polexpire/expire size calculations

xfrm_send_acquire() and xfrm_exp_policy_notify() allocate their reply skb
with xfrm_acquire_msgsize() and xfrm_polexpire_msgsize(), then build_acquire()
and build_polexpire() append attributes including XFRMA_IF_ID (when the
policy if_id is set) and XFRMA_OFFLOAD_DEV (when the policy is bound to an
xfrm offload device).  Neither size helper reserves space for these two
conditionally emitted attributes, so for policies carrying if_id, mark,
pcpu and/or an offload device the builders can run out of skb tailroom,
fail with -EMSGSIZE and hit BUG_ON(err < 0), turning a netlink event into
a kernel panic.

build_expire() has the same XFRMA_IF_ID undercount in xfrm_expire_msgsize();
its caller already handles -EMSGSIZE gracefully, so the only effect there
is a dropped EXPIRE notification.

This is the same bug class as CVE-2026-43107, whose fix (7081d46d32)
only covered the aevent pair.

Account XFRMA_IF_ID and XFRMA_OFFLOAD_DEV in the three size calculations
unconditionally, and replace the two BUG_ONs with normal error unwinding,
mirroring the aevent fix.

Fixes: 7e6526404ade ("xfrm: Add a new lookup key to match xfrm interfaces.")
Signed-off-by: Adrian Martinez <redacted>
---
 net/xfrm/xfrm_user.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index a2587c7e..5eb79b0b 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -3927,7 +3927,8 @@ static inline unsigned int xfrm_expire_msgsize(void)
 	return NLMSG_ALIGN(sizeof(struct xfrm_user_expire)) +
 	       nla_total_size(sizeof(struct xfrm_mark)) +
 	       nla_total_size(sizeof_field(struct xfrm_state, dir)) +
-	       nla_total_size(4); /* XFRMA_SA_PCPU */
+	       nla_total_size(4) + /* XFRMA_SA_PCPU */
+	       nla_total_size(4); /* XFRMA_IF_ID */
 }

 static int build_expire(struct sk_buff *skb, struct xfrm_state *x,
const struct km_event *c)
@@ -4177,6 +4178,8 @@ static inline unsigned int
xfrm_acquire_msgsize(struct xfrm_state *x,
 	       + nla_total_size(sizeof(struct xfrm_mark))
 	       + nla_total_size(xfrm_user_sec_ctx_size(x->security))
 	       + nla_total_size(4) /* XFRMA_SA_PCPU */
+	       + nla_total_size(sizeof(xp->if_id)) /* XFRMA_IF_ID */
+	       + nla_total_size(sizeof(struct xfrm_user_offload)) /*
XFRMA_OFFLOAD_DEV */
 	       + userpolicy_type_attrsize();
 }
@@ -4236,7 +4239,10 @@ static int xfrm_send_acquire(struct xfrm_state
*x, struct xfrm_tmpl *xt,
 		return -ENOMEM;

 	err = build_acquire(skb, x, xt, xp);
-	BUG_ON(err < 0);
+	if (err < 0) {
+		kfree_skb(skb);
+		return err;
+	}

 	return xfrm_nlmsg_multicast(net, skb, 0, XFRMNLGRP_ACQUIRE);
 }
@@ -4307,6 +4313,8 @@ static inline unsigned int
xfrm_polexpire_msgsize(struct xfrm_policy *xp)
 	       + nla_total_size(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr)
 	       + nla_total_size(xfrm_user_sec_ctx_size(xp->security))
 	       + nla_total_size(sizeof(struct xfrm_mark))
+	       + nla_total_size(sizeof(xp->if_id)) /* XFRMA_IF_ID */
+	       + nla_total_size(sizeof(struct xfrm_user_offload)) /*
XFRMA_OFFLOAD_DEV */
 	       + userpolicy_type_attrsize();
 }
@@ -4358,7 +4366,10 @@ static int xfrm_exp_policy_notify(struct
xfrm_policy *xp, int dir, const struct
 		return -ENOMEM;

 	err = build_polexpire(skb, xp, dir, c);
-	BUG_ON(err < 0);
+	if (err < 0) {
+		kfree_skb(skb);
+		return err;
+	}

 	return xfrm_nlmsg_multicast(net, skb, 0, XFRMNLGRP_EXPIRE);
 }
-- 
2.43.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help