Commit b145745f authored by David S. Miller's avatar David S. Miller
Browse files


Steffen Klassert says:

====================
pull request (net): ipsec 2019-04-30

1) Fix an out-of-bound array accesses in __xfrm_policy_unlink.
   From YueHaibing.

2) Reset the secpath on failure in the ESP GRO handlers
   to avoid dereferencing an invalid pointer on error.
   From Myungho Jung.

3) Add and revert a patch that tried to add rcu annotations
   to netns_xfrm. From Su Yanjun.

4) Wait for rcu callbacks before freeing xfrm6_tunnel_spi_kmem.
   From Su Yanjun.

5) Fix forgotten vti4 ipip tunnel deregistration.
   From Jeremy Sowden:

6) Remove some duplicated log messages in vti4.
   From Jeremy Sowden.

7) Don't use IPSEC_PROTO_ANY when flushing states because
   this will flush only IPsec portocol speciffic states.
   IPPROTO_ROUTING states may remain in the lists when
   doing net exit. Fix this by replacing IPSEC_PROTO_ANY
   with zero. From Cong Wang.

8) Add length check for UDP encapsulation to fix "Oversized IP packet"
   warnings on receive side. From Sabrina Dubroca.

9) Fix xfrm interface lookup when the interface is associated to
   a vrf layer 3 master device. From Martin Willi.

10) Reload header pointers after pskb_may_pull() in _decode_session4(),
    otherwise we may read from uninitialized memory.

11) Update the documentation about xfrm[46]_gc_thresh, it
    is not used anymore after the flowcache removal.
    From Nicolas Dichtel.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6c0afef5 837f7411
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1337,6 +1337,7 @@ tag - INTEGER
	Default value is 0.

xfrm4_gc_thresh - INTEGER
	(Obsolete since linux-4.14)
	The threshold at which we will start garbage collecting for IPv4
	destination cache entries.  At twice this value the system will
	refuse new allocations.
@@ -1920,6 +1921,7 @@ echo_ignore_all - BOOLEAN
	Default: 0

xfrm6_gc_thresh - INTEGER
	(Obsolete since linux-4.14)
	The threshold at which we will start garbage collecting for IPv6
	destination cache entries.  At twice this value the system will
	refuse new allocations.
+19 −1
Original line number Diff line number Diff line
@@ -295,7 +295,8 @@ struct xfrm_replay {
};

struct xfrm_if_cb {
	struct xfrm_if	*(*decode_session)(struct sk_buff *skb);
	struct xfrm_if	*(*decode_session)(struct sk_buff *skb,
					   unsigned short family);
};

void xfrm_if_register_cb(const struct xfrm_if_cb *ifcb);
@@ -1404,6 +1405,23 @@ static inline int xfrm_state_kern(const struct xfrm_state *x)
	return atomic_read(&x->tunnel_users);
}

static inline bool xfrm_id_proto_valid(u8 proto)
{
	switch (proto) {
	case IPPROTO_AH:
	case IPPROTO_ESP:
	case IPPROTO_COMP:
#if IS_ENABLED(CONFIG_IPV6)
	case IPPROTO_ROUTING:
	case IPPROTO_DSTOPTS:
#endif
		return true;
	default:
		return false;
	}
}

/* IPSEC_PROTO_ANY only matches 3 IPsec protocols, 0 could match all. */
static inline int xfrm_id_proto_match(u8 proto, u8 userproto)
{
	return (!userproto || proto == userproto ||
+15 −5
Original line number Diff line number Diff line
@@ -226,7 +226,7 @@ static void esp_output_fill_trailer(u8 *tail, int tfclen, int plen, __u8 proto)
	tail[plen - 1] = proto;
}

static void esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp)
static int esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp)
{
	int encap_type;
	struct udphdr *uh;
@@ -234,6 +234,7 @@ static void esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, stru
	__be16 sport, dport;
	struct xfrm_encap_tmpl *encap = x->encap;
	struct ip_esp_hdr *esph = esp->esph;
	unsigned int len;

	spin_lock_bh(&x->lock);
	sport = encap->encap_sport;
@@ -241,11 +242,14 @@ static void esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, stru
	encap_type = encap->encap_type;
	spin_unlock_bh(&x->lock);

	len = skb->len + esp->tailen - skb_transport_offset(skb);
	if (len + sizeof(struct iphdr) >= IP_MAX_MTU)
		return -EMSGSIZE;

	uh = (struct udphdr *)esph;
	uh->source = sport;
	uh->dest = dport;
	uh->len = htons(skb->len + esp->tailen
		  - skb_transport_offset(skb));
	uh->len = htons(len);
	uh->check = 0;

	switch (encap_type) {
@@ -262,6 +266,8 @@ static void esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, stru

	*skb_mac_header(skb) = IPPROTO_UDP;
	esp->esph = esph;

	return 0;
}

int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp)
@@ -275,8 +281,12 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
	int tailen = esp->tailen;

	/* this is non-NULL only with UDP Encapsulation */
	if (x->encap)
		esp_output_udp_encap(x, skb, esp);
	if (x->encap) {
		int err = esp_output_udp_encap(x, skb, esp);

		if (err < 0)
			return err;
	}

	if (!skb_cloned(skb)) {
		if (tailen <= skb_tailroom(skb)) {
+5 −3
Original line number Diff line number Diff line
@@ -52,13 +52,13 @@ static struct sk_buff *esp4_gro_receive(struct list_head *head,
			goto out;

		if (sp->len == XFRM_MAX_DEPTH)
			goto out;
			goto out_reset;

		x = xfrm_state_lookup(dev_net(skb->dev), skb->mark,
				      (xfrm_address_t *)&ip_hdr(skb)->daddr,
				      spi, IPPROTO_ESP, AF_INET);
		if (!x)
			goto out;
			goto out_reset;

		sp->xvec[sp->len++] = x;
		sp->olen++;
@@ -66,7 +66,7 @@ static struct sk_buff *esp4_gro_receive(struct list_head *head,
		xo = xfrm_offload(skb);
		if (!xo) {
			xfrm_state_put(x);
			goto out;
			goto out_reset;
		}
	}

@@ -82,6 +82,8 @@ static struct sk_buff *esp4_gro_receive(struct list_head *head,
	xfrm_input(skb, IPPROTO_ESP, spi, -2);

	return ERR_PTR(-EINPROGRESS);
out_reset:
	secpath_reset(skb);
out:
	skb_push(skb, offset);
	NAPI_GRO_CB(skb)->same_flow = 0;
+4 −5
Original line number Diff line number Diff line
@@ -646,10 +646,8 @@ static int __init vti_init(void)

	msg = "ipip tunnel";
	err = xfrm4_tunnel_register(&ipip_handler, AF_INET);
	if (err < 0) {
		pr_info("%s: cant't register tunnel\n",__func__);
	if (err < 0)
		goto xfrm_tunnel_failed;
	}

	msg = "netlink interface";
	err = rtnl_link_register(&vti_link_ops);
@@ -659,9 +657,9 @@ static int __init vti_init(void)
	return err;

rtnl_link_failed:
	xfrm4_protocol_deregister(&vti_ipcomp4_protocol, IPPROTO_COMP);
xfrm_tunnel_failed:
	xfrm4_tunnel_deregister(&ipip_handler, AF_INET);
xfrm_tunnel_failed:
	xfrm4_protocol_deregister(&vti_ipcomp4_protocol, IPPROTO_COMP);
xfrm_proto_comp_failed:
	xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH);
xfrm_proto_ah_failed:
@@ -676,6 +674,7 @@ pernet_dev_failed:
static void __exit vti_fini(void)
{
	rtnl_link_unregister(&vti_link_ops);
	xfrm4_tunnel_deregister(&ipip_handler, AF_INET);
	xfrm4_protocol_deregister(&vti_ipcomp4_protocol, IPPROTO_COMP);
	xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH);
	xfrm4_protocol_deregister(&vti_esp4_protocol, IPPROTO_ESP);
Loading