Commit 291d5dc8 authored by Paolo Abeni's avatar Paolo Abeni
Browse files
Steffen Klassert says:

====================
pull request (net): ipsec 2025-07-23

1) Premption fixes for xfrm_state_find.
   From Sabrina Dubroca.

2) Initialize offload path also for SW IPsec GRO. This fixes a
   performance regression on SW IPsec offload.
   From Leon Romanovsky.

3) Fix IPsec UDP GRO for IKE packets.
   From Tobias Brunner,

4) Fix transport header setting for IPcomp after decompressing.
   From Fernando Fernandez Mancera.

5)  Fix use-after-free when xfrmi_changelink tries to change
    collect_md for a xfrm interface.
    From Eyal Birger .

6) Delete the special IPcomp x->tunnel state along with the state x
   to avoid refcount problems.
   From Sabrina Dubroca.

Please pull or let me know if there are problems.

* tag 'ipsec-2025-07-23' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec:
  Revert "xfrm: destroy xfrm_state synchronously on net exit path"
  xfrm: delete x->tunnel as we delete x
  xfrm: interface: fix use-after-free after changing collect_md xfrm interface
  xfrm: ipcomp: adjust transport header after decompressing
  xfrm: Set transport header to fix UDP GRO handling
  xfrm: always initialize offload path
  xfrm: state: use a consistent pcpu_id in xfrm_state_find
  xfrm: state: initialize state_ptrs earlier in xfrm_state_find
====================

Link: https://patch.msgid.link/20250723075417.3432644-1-steffen.klassert@secunet.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 89fd905d 28712d6e
Loading
Loading
Loading
Loading
+4 −11
Original line number Diff line number Diff line
@@ -441,7 +441,6 @@ int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo);
int xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo);

void xfrm_flush_gc(void);
void xfrm_state_delete_tunnel(struct xfrm_state *x);

struct xfrm_type {
	struct module		*owner;
@@ -474,7 +473,7 @@ struct xfrm_type_offload {

int xfrm_register_type_offload(const struct xfrm_type_offload *type, unsigned short family);
void xfrm_unregister_type_offload(const struct xfrm_type_offload *type, unsigned short family);
void xfrm_set_type_offload(struct xfrm_state *x);
void xfrm_set_type_offload(struct xfrm_state *x, bool try_load);
static inline void xfrm_unset_type_offload(struct xfrm_state *x)
{
	if (!x->type_offload)
@@ -916,7 +915,7 @@ static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols)
		xfrm_pol_put(pols[i]);
}

void __xfrm_state_destroy(struct xfrm_state *, bool);
void __xfrm_state_destroy(struct xfrm_state *);

static inline void __xfrm_state_put(struct xfrm_state *x)
{
@@ -926,13 +925,7 @@ static inline void __xfrm_state_put(struct xfrm_state *x)
static inline void xfrm_state_put(struct xfrm_state *x)
{
	if (refcount_dec_and_test(&x->refcnt))
		__xfrm_state_destroy(x, false);
}

static inline void xfrm_state_put_sync(struct xfrm_state *x)
{
	if (refcount_dec_and_test(&x->refcnt))
		__xfrm_state_destroy(x, true);
		__xfrm_state_destroy(x);
}

static inline void xfrm_state_hold(struct xfrm_state *x)
@@ -1770,7 +1763,7 @@ struct xfrmk_spdinfo {

struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq, u32 pcpu_num);
int xfrm_state_delete(struct xfrm_state *x);
int xfrm_state_flush(struct net *net, u8 proto, bool task_valid, bool sync);
int xfrm_state_flush(struct net *net, u8 proto, bool task_valid);
int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_valid);
int xfrm_dev_policy_flush(struct net *net, struct net_device *dev,
			  bool task_valid);
+2 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ static int ipcomp4_err(struct sk_buff *skb, u32 info)
}

/* We always hold one tunnel user reference to indicate a tunnel */
static struct lock_class_key xfrm_state_lock_key;
static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
{
	struct net *net = xs_net(x);
@@ -62,6 +63,7 @@ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
	t = xfrm_state_alloc(net);
	if (!t)
		goto out;
	lockdep_set_class(&t->lock, &xfrm_state_lock_key);

	t->id.proto = IPPROTO_IPIP;
	t->id.spi = x->props.saddr.a4;
+3 −0
Original line number Diff line number Diff line
@@ -202,6 +202,9 @@ struct sk_buff *xfrm4_gro_udp_encap_rcv(struct sock *sk, struct list_head *head,
	if (len <= sizeof(struct ip_esp_hdr) || udpdata32[0] == 0)
		goto out;

	/* set the transport header to ESP */
	skb_set_transport_header(skb, offset);

	NAPI_GRO_CB(skb)->proto = IPPROTO_UDP;

	pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
+2 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ static int ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
	return 0;
}

static struct lock_class_key xfrm_state_lock_key;
static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
{
	struct net *net = xs_net(x);
@@ -79,6 +80,7 @@ static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
	t = xfrm_state_alloc(net);
	if (!t)
		goto out;
	lockdep_set_class(&t->lock, &xfrm_state_lock_key);

	t->id.proto = IPPROTO_IPV6;
	t->id.spi = xfrm6_tunnel_alloc_spi(net, (xfrm_address_t *)&x->props.saddr);
+3 −0
Original line number Diff line number Diff line
@@ -202,6 +202,9 @@ struct sk_buff *xfrm6_gro_udp_encap_rcv(struct sock *sk, struct list_head *head,
	if (len <= sizeof(struct ip_esp_hdr) || udpdata32[0] == 0)
		goto out;

	/* set the transport header to ESP */
	skb_set_transport_header(skb, offset);

	NAPI_GRO_CB(skb)->proto = IPPROTO_UDP;

	pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
Loading