diff options
author | David S. Miller <davem@davemloft.net> | 2018-07-27 12:18:19 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-07-27 12:18:19 -0400 |
commit | d0fdb366b6936f1ddfb4de2631484d58967a7efd (patch) | |
tree | a468f2a57c6a028368d999a36f3253f1c26be946 | |
parent | 101f0cd4f2216d32f1b8a75a2154cf3997484ee2 (diff) | |
parent | 7284fdf39a912322ce97de2d30def3c6068a418c (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.c | 4 | ||||
-rw-r--r-- | net/ipv6/ip6_vti.c | 11 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 3 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 18 |
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 | } |
2291 | EXPORT_SYMBOL(xfrm_lookup_route); | 2294 | EXPORT_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 | ||
1034 | static inline unsigned int xfrm_spdinfo_msgsize(void) | 1036 | static 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 |
1672 | static int copy_to_user_policy_type(u8 type, struct sk_buff *skb) | 1674 | static 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 | } |