aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-07-27 12:18:19 -0400
committerDavid S. Miller <davem@davemloft.net>2018-07-27 12:18:19 -0400
commitd0fdb366b6936f1ddfb4de2631484d58967a7efd (patch)
treea468f2a57c6a028368d999a36f3253f1c26be946
parent101f0cd4f2216d32f1b8a75a2154cf3997484ee2 (diff)
parent7284fdf39a912322ce97de2d30def3c6068a418c (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec
Steffen Klassert says: ==================== pull request (net): ipsec 2018-07-27 1) Fix PMTU handling of vti6. We update the PMTU on the xfrm dst_entry which is not cached anymore after the flowchache removal. So update the PMTU of the original dst_entry instead. From Eyal Birger. 2) Fix a leak of kernel memory to userspace. From Eric Dumazet. 3) Fix a possible dst_entry memleak in xfrm_lookup_route. From Tommi Rantala. 4) Fix a skb leak in case we can't call nlmsg_multicast from xfrm_nlmsg_multicast. From Florian Westphal. 5) Fix a leak of a temporary buffer in the error path of esp6_input. From Zhen Lei. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv6/esp6.c4
-rw-r--r--net/ipv6/ip6_vti.c11
-rw-r--r--net/xfrm/xfrm_policy.c3
-rw-r--r--net/xfrm/xfrm_user.c18
4 files changed, 23 insertions, 13 deletions
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 97513f35bcc5..88a7579c23bd 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -669,8 +669,10 @@ skip_cow:
669 669
670 sg_init_table(sg, nfrags); 670 sg_init_table(sg, nfrags);
671 ret = skb_to_sgvec(skb, sg, 0, skb->len); 671 ret = skb_to_sgvec(skb, sg, 0, skb->len);
672 if (unlikely(ret < 0)) 672 if (unlikely(ret < 0)) {
673 kfree(tmp);
673 goto out; 674 goto out;
675 }
674 676
675 skb->ip_summed = CHECKSUM_NONE; 677 skb->ip_summed = CHECKSUM_NONE;
676 678
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index b7f28deddaea..c72ae3a4fe09 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -480,10 +480,6 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
480 goto tx_err_dst_release; 480 goto tx_err_dst_release;
481 } 481 }
482 482
483 skb_scrub_packet(skb, !net_eq(t->net, dev_net(dev)));
484 skb_dst_set(skb, dst);
485 skb->dev = skb_dst(skb)->dev;
486
487 mtu = dst_mtu(dst); 483 mtu = dst_mtu(dst);
488 if (!skb->ignore_df && skb->len > mtu) { 484 if (!skb->ignore_df && skb->len > mtu) {
489 skb_dst_update_pmtu(skb, mtu); 485 skb_dst_update_pmtu(skb, mtu);
@@ -498,9 +494,14 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
498 htonl(mtu)); 494 htonl(mtu));
499 } 495 }
500 496
501 return -EMSGSIZE; 497 err = -EMSGSIZE;
498 goto tx_err_dst_release;
502 } 499 }
503 500
501 skb_scrub_packet(skb, !net_eq(t->net, dev_net(dev)));
502 skb_dst_set(skb, dst);
503 skb->dev = skb_dst(skb)->dev;
504
504 err = dst_output(t->net, skb->sk, skb); 505 err = dst_output(t->net, skb->sk, skb);
505 if (net_xmit_eval(err) == 0) { 506 if (net_xmit_eval(err) == 0) {
506 struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); 507 struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 5f48251c1319..7c5e8978aeaa 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2286,6 +2286,9 @@ struct dst_entry *xfrm_lookup_route(struct net *net, struct dst_entry *dst_orig,
2286 if (IS_ERR(dst) && PTR_ERR(dst) == -EREMOTE) 2286 if (IS_ERR(dst) && PTR_ERR(dst) == -EREMOTE)
2287 return make_blackhole(net, dst_orig->ops->family, dst_orig); 2287 return make_blackhole(net, dst_orig->ops->family, dst_orig);
2288 2288
2289 if (IS_ERR(dst))
2290 dst_release(dst_orig);
2291
2289 return dst; 2292 return dst;
2290} 2293}
2291EXPORT_SYMBOL(xfrm_lookup_route); 2294EXPORT_SYMBOL(xfrm_lookup_route);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 080035f056d9..33878e6e0d0a 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1025,10 +1025,12 @@ static inline int xfrm_nlmsg_multicast(struct net *net, struct sk_buff *skb,
1025{ 1025{
1026 struct sock *nlsk = rcu_dereference(net->xfrm.nlsk); 1026 struct sock *nlsk = rcu_dereference(net->xfrm.nlsk);
1027 1027
1028 if (nlsk) 1028 if (!nlsk) {
1029 return nlmsg_multicast(nlsk, skb, pid, group, GFP_ATOMIC); 1029 kfree_skb(skb);
1030 else 1030 return -EPIPE;
1031 return -1; 1031 }
1032
1033 return nlmsg_multicast(nlsk, skb, pid, group, GFP_ATOMIC);
1032} 1034}
1033 1035
1034static inline unsigned int xfrm_spdinfo_msgsize(void) 1036static inline unsigned int xfrm_spdinfo_msgsize(void)
@@ -1671,9 +1673,11 @@ static inline unsigned int userpolicy_type_attrsize(void)
1671#ifdef CONFIG_XFRM_SUB_POLICY 1673#ifdef CONFIG_XFRM_SUB_POLICY
1672static int copy_to_user_policy_type(u8 type, struct sk_buff *skb) 1674static int copy_to_user_policy_type(u8 type, struct sk_buff *skb)
1673{ 1675{
1674 struct xfrm_userpolicy_type upt = { 1676 struct xfrm_userpolicy_type upt;
1675 .type = type, 1677
1676 }; 1678 /* Sadly there are two holes in struct xfrm_userpolicy_type */
1679 memset(&upt, 0, sizeof(upt));
1680 upt.type = type;
1677 1681
1678 return nla_put(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt); 1682 return nla_put(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt);
1679} 1683}