History

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec

Steffen Klassert says: ==================== pull request (net): ipsec 2022-03-09 1) Fix IPv6 PMTU discovery for xfrm interfaces. From Lina Wang. 2) Revert failing for policies and states that are configured with XFRMA_IF_ID 0. It broke a user configuration. From Kai Lueke. 3) Fix a possible buffer overflow in the ESP output path. 4) Fix ESP GSO for tunnel and BEET mode on inter address family tunnels. ====================

David S. Miller committed 4 years ago

Commit cc7e2f52 parents 71171ac 23c7f8d10 files · +70 −23Browse files

Unified · Split

10 files
  1. include/linux/netdevice.h +2 −0
  2. include/net/esp.h +2 −0
  3. net/core/gro.c +25 −0
  4. net/ipv4/esp4.c +5 −0
  5. net/ipv4/esp4_offload.c +4 −2
  6. net/ipv6/esp6.c +5 −0
  7. net/ipv6/esp6_offload.c +4 −2
  8. net/ipv6/xfrm6_output.c +16 −0
  9. net/xfrm/xfrm_interface.c +4 −1
  10. net/xfrm/xfrm_user.c +3 −18
include/linux/netdevice.h+2−0
@@ -4602,6 +4602,8 @@ int skb_csum_hwoffload_help(struct sk_buff *skb, · 4601 unmodified lines
46024602
46034603 struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
46044604 netdev_features_t features, bool tx_path);
4605+struct sk_buff *skb_eth_gso_segment(struct sk_buff *skb,
4606+ netdev_features_t features, __be16 type);
46054607 struct sk_buff *skb_mac_gso_segment(struct sk_buff *skb,
46064608 netdev_features_t features);
46074609
include/net/esp.h+2−0
@@ -4,6 +4,8 @@ · 3 unmodified lines
44
55 #include <linux/skbuff.h>
66
7+#define ESP_SKB_FRAG_MAXSIZE (PAGE_SIZE << SKB_FRAG_PAGE_ORDER)
8+
79 struct ip_esp_hdr;
810
911 static inline struct ip_esp_hdr *ip_esp_hdr(const struct sk_buff *skb)
net/core/gro.c+25−0
@@ -92,6 +92,31 @@ void dev_remove_offload(struct packet_offload *po) · 91 unmodified lines
9292 }
9393 EXPORT_SYMBOL(dev_remove_offload);
9494
95+/**
96+ * skb_eth_gso_segment - segmentation handler for ethernet protocols.
97+ * @skb: buffer to segment
98+ * @features: features for the output path (see dev->features)
99+ * @type: Ethernet Protocol ID
100+ */
101+struct sk_buff *skb_eth_gso_segment(struct sk_buff *skb,
102+ netdev_features_t features, __be16 type)
103+{
104+ struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
105+ struct packet_offload *ptype;
106+
107+ rcu_read_lock();
108+ list_for_each_entry_rcu(ptype, &offload_base, list) {
109+ if (ptype->type == type && ptype->callbacks.gso_segment) {
110+ segs = ptype->callbacks.gso_segment(skb, features);
111+ break;
112+ }
113+ }
114+ rcu_read_unlock();
115+
116+ return segs;
117+}
118+EXPORT_SYMBOL(skb_eth_gso_segment);
119+
95120 /**
96121 * skb_mac_gso_segment - mac layer segmentation handler.
97122 * @skb: buffer to segment
net/ipv4/esp4.c+5−0
@@ -446,6 +446,7 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info * · 445 unmodified lines
446446 struct page *page;
447447 struct sk_buff *trailer;
448448 int tailen = esp->tailen;
449+ unsigned int allocsz;
449450
450451 /* this is non-NULL only with TCP/UDP Encapsulation */
451452 if (x->encap) {
@@ -455,6 +456,10 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info * · 3 unmodified lines
455456 return err;
456457 }
457458
459+ allocsz = ALIGN(skb->data_len + tailen, L1_CACHE_BYTES);
460+ if (allocsz > ESP_SKB_FRAG_MAXSIZE)
461+ goto cow;
462+
458463 if (!skb_cloned(skb)) {
459464 if (tailen <= skb_tailroom(skb)) {
460465 nfrags = 1;
net/ipv4/esp4_offload.c+4−2
@@ -110,8 +110,7 @@ static struct sk_buff *xfrm4_tunnel_gso_segment(struct xfrm_state *x, · 109 unmodified lines
110110 struct sk_buff *skb,
111111 netdev_features_t features)
112112 {
113− __skb_push(skb, skb->mac_len);
114− return skb_mac_gso_segment(skb, features);
113+ return skb_eth_gso_segment(skb, features, htons(ETH_P_IP));
115114 }
116115
117116 static struct sk_buff *xfrm4_transport_gso_segment(struct xfrm_state *x,
@@ -160,6 +159,9 @@ static struct sk_buff *xfrm4_beet_gso_segment(struct xfrm_state *x, · 42 unmodified lines
160159 skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4;
161160 }
162161
162+ if (proto == IPPROTO_IPV6)
163+ skb_shinfo(skb)->gso_type |= SKB_GSO_IPXIP4;
164+
163165 __skb_pull(skb, skb_transport_offset(skb));
164166 ops = rcu_dereference(inet_offloads[proto]);
165167 if (likely(ops && ops->callbacks.gso_segment))
net/ipv6/esp6.c+5−0
@@ -482,6 +482,7 @@ int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info · 481 unmodified lines
482482 struct page *page;
483483 struct sk_buff *trailer;
484484 int tailen = esp->tailen;
485+ unsigned int allocsz;
485486
486487 if (x->encap) {
487488 int err = esp6_output_encap(x, skb, esp);
@@ -490,6 +491,10 @@ int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info · 2 unmodified lines
490491 return err;
491492 }
492493
494+ allocsz = ALIGN(skb->data_len + tailen, L1_CACHE_BYTES);
495+ if (allocsz > ESP_SKB_FRAG_MAXSIZE)
496+ goto cow;
497+
493498 if (!skb_cloned(skb)) {
494499 if (tailen <= skb_tailroom(skb)) {
495500 nfrags = 1;
net/ipv6/esp6_offload.c+4−2
@@ -145,8 +145,7 @@ static struct sk_buff *xfrm6_tunnel_gso_segment(struct xfrm_state *x, · 144 unmodified lines
145145 struct sk_buff *skb,
146146 netdev_features_t features)
147147 {
148− __skb_push(skb, skb->mac_len);
149− return skb_mac_gso_segment(skb, features);
148+ return skb_eth_gso_segment(skb, features, htons(ETH_P_IPV6));
150149 }
151150
152151 static struct sk_buff *xfrm6_transport_gso_segment(struct xfrm_state *x,
@@ -199,6 +198,9 @@ static struct sk_buff *xfrm6_beet_gso_segment(struct xfrm_state *x, · 46 unmodified lines
199198 ipv6_skip_exthdr(skb, 0, &proto, &frag);
200199 }
201200
201+ if (proto == IPPROTO_IPIP)
202+ skb_shinfo(skb)->gso_type |= SKB_GSO_IPXIP6;
203+
202204 __skb_pull(skb, skb_transport_offset(skb));
203205 ops = rcu_dereference(inet6_offloads[proto]);
204206 if (likely(ops && ops->callbacks.gso_segment))
net/ipv6/xfrm6_output.c+16−0
@@ -45,6 +45,19 @@ static int __xfrm6_output_finish(struct net *net, struct sock *sk, struct sk_buf · 44 unmodified lines
4545 return xfrm_output(sk, skb);
4646 }
4747
48+static int xfrm6_noneed_fragment(struct sk_buff *skb)
49+{
50+ struct frag_hdr *fh;
51+ u8 prevhdr = ipv6_hdr(skb)->nexthdr;
52+
53+ if (prevhdr != NEXTHDR_FRAGMENT)
54+ return 0;
55+ fh = (struct frag_hdr *)(skb->data + sizeof(struct ipv6hdr));
56+ if (fh->nexthdr == NEXTHDR_ESP || fh->nexthdr == NEXTHDR_AUTH)
57+ return 1;
58+ return 0;
59+}
60+
4861 static int __xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
4962 {
5063 struct dst_entry *dst = skb_dst(skb);
@@ -73,6 +86,9 @@ static int __xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb) · 22 unmodified lines
7386 xfrm6_local_rxpmtu(skb, mtu);
7487 kfree_skb(skb);
7588 return -EMSGSIZE;
89+ } else if (toobig && xfrm6_noneed_fragment(skb)) {
90+ skb->ignore_df = 1;
91+ goto skip_frag;
7692 } else if (!skb->ignore_df && toobig && skb->sk) {
7793 xfrm_local_error(skb, mtu);
7894 kfree_skb(skb);
net/xfrm/xfrm_interface.c+4−1
@@ -304,7 +304,10 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) · 303 unmodified lines
304304 if (mtu < IPV6_MIN_MTU)
305305 mtu = IPV6_MIN_MTU;
306306
307− icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
307+ if (skb->len > 1280)
308+ icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
309+ else
310+ goto xmit;
308311 } else {
309312 if (!(ip_hdr(skb)->frag_off & htons(IP_DF)))
310313 goto xmit;
net/xfrm/xfrm_user.c+3−18
@@ -630,13 +630,8 @@ static struct xfrm_state *xfrm_state_construct(struct net *net, · 629 unmodified lines
630630
631631 xfrm_smark_init(attrs, &x->props.smark);
632632
633− if (attrs[XFRMA_IF_ID]) {
633+ if (attrs[XFRMA_IF_ID])
634634 x->if_id = nla_get_u32(attrs[XFRMA_IF_ID]);
635− if (!x->if_id) {
636− err = -EINVAL;
637− goto error;
638− }
639− }
640635
641636 err = __xfrm_init_state(x, false, attrs[XFRMA_OFFLOAD_DEV]);
642637 if (err)
@@ -1432,13 +1427,8 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, · 789 unmodified lines
14321427
14331428 mark = xfrm_mark_get(attrs, &m);
14341429
1435− if (attrs[XFRMA_IF_ID]) {
1430+ if (attrs[XFRMA_IF_ID])
14361431 if_id = nla_get_u32(attrs[XFRMA_IF_ID]);
1437− if (!if_id) {
1438− err = -EINVAL;
1439− goto out_noput;
1440− }
1441− }
14421432
14431433 if (p->info.seq) {
14441434 x = xfrm_find_acq_byseq(net, mark, p->info.seq);
@@ -1751,13 +1741,8 @@ static struct xfrm_policy *xfrm_policy_construct(struct net *net, struct xfrm_us · 306 unmodified lines
17511741
17521742 xfrm_mark_get(attrs, &xp->mark);
17531743
1754− if (attrs[XFRMA_IF_ID]) {
1744+ if (attrs[XFRMA_IF_ID])
17551745 xp->if_id = nla_get_u32(attrs[XFRMA_IF_ID]);
1756− if (!xp->if_id) {
1757− err = -EINVAL;
1758− goto error;
1759− }
1760− }
17611746
17621747 return xp;
17631748 error: