Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

Steffen Klassert says:

====================
pull request (net): ipsec 2018-03-13

1) Refuse to insert 32 bit userspace socket policies on 64
bit systems like we do it for standard policies. We don't
have a compat layer, so inserting socket policies from
32 bit userspace will lead to a broken configuration.

2) Make the policy hold queue work without the flowcache.
Dummy bundles are not chached anymore, so we need to
generate a new one on each lookup as long as the SAs
are not yet in place.

3) Fix the validation of the esn replay attribute. The
The sanity check in verify_replay() is bypassed if
the XFRM_STATE_ESN flag is not set. Fix this by doing
the sanity check uncoditionally.
From Florian Westphal.

4) After most of the dst_entry garbage collection code
is removed, we may leak xfrm_dst entries as they are
neither cached nor tracked somewhere. Fix this by
reusing the 'uncached_list' to track xfrm_dst entries
too. From Xin Long.

5) Fix a rcu_read_lock/rcu_read_unlock imbalance in
xfrm_get_tos() From Xin Long.

6) Fix an infinite loop in xfrm_get_dst_nexthop. On
transport mode we fetch the child dst_entry after
we continue, so this pointer is never updated.
Fix this by fetching it before we continue.

7) Fix ESN sequence number gap after IPsec GSO packets.
We accidentally increment the sequence number counter
on the xfrm_state by one packet too much in the ESN
case. Fix this by setting the sequence number to the
correct value.

8) Reset the ethernet protocol after decapsulation only if a
mac header was set. Otherwise it breaks configurations
with TUN devices. From Yossi Kuperman.

9) Fix __this_cpu_read() usage in preemptible code. Use
this_cpu_read() instead in ipcomp_alloc_tfms().
From Greg Hackmann.

Please pull or let me know if there are problems.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+58 -35
+3
include/net/ip6_route.h
··· 179 179 void rt6_sync_down_dev(struct net_device *dev, unsigned long event); 180 180 void rt6_multipath_rebalance(struct rt6_info *rt); 181 181 182 + void rt6_uncached_list_add(struct rt6_info *rt); 183 + void rt6_uncached_list_del(struct rt6_info *rt); 184 + 182 185 static inline const struct rt6_info *skb_rt6_info(const struct sk_buff *skb) 183 186 { 184 187 const struct dst_entry *dst = skb_dst(skb);
+3
include/net/route.h
··· 227 227 void fib_add_ifaddr(struct in_ifaddr *); 228 228 void fib_del_ifaddr(struct in_ifaddr *, struct in_ifaddr *); 229 229 230 + void rt_add_uncached_list(struct rtable *rt); 231 + void rt_del_uncached_list(struct rtable *rt); 232 + 230 233 static inline void ip_rt_put(struct rtable *rt) 231 234 { 232 235 /* dst_release() accepts a NULL parameter.
+13 -8
net/ipv4/route.c
··· 1393 1393 1394 1394 static DEFINE_PER_CPU_ALIGNED(struct uncached_list, rt_uncached_list); 1395 1395 1396 - static void rt_add_uncached_list(struct rtable *rt) 1396 + void rt_add_uncached_list(struct rtable *rt) 1397 1397 { 1398 1398 struct uncached_list *ul = raw_cpu_ptr(&rt_uncached_list); 1399 1399 ··· 1404 1404 spin_unlock_bh(&ul->lock); 1405 1405 } 1406 1406 1407 - static void ipv4_dst_destroy(struct dst_entry *dst) 1407 + void rt_del_uncached_list(struct rtable *rt) 1408 1408 { 1409 - struct dst_metrics *p = (struct dst_metrics *)DST_METRICS_PTR(dst); 1410 - struct rtable *rt = (struct rtable *) dst; 1411 - 1412 - if (p != &dst_default_metrics && refcount_dec_and_test(&p->refcnt)) 1413 - kfree(p); 1414 - 1415 1409 if (!list_empty(&rt->rt_uncached)) { 1416 1410 struct uncached_list *ul = rt->rt_uncached_list; 1417 1411 ··· 1413 1419 list_del(&rt->rt_uncached); 1414 1420 spin_unlock_bh(&ul->lock); 1415 1421 } 1422 + } 1423 + 1424 + static void ipv4_dst_destroy(struct dst_entry *dst) 1425 + { 1426 + struct dst_metrics *p = (struct dst_metrics *)DST_METRICS_PTR(dst); 1427 + struct rtable *rt = (struct rtable *)dst; 1428 + 1429 + if (p != &dst_default_metrics && refcount_dec_and_test(&p->refcnt)) 1430 + kfree(p); 1431 + 1432 + rt_del_uncached_list(rt); 1416 1433 } 1417 1434 1418 1435 void rt_flush_dev(struct net_device *dev)
+2 -1
net/ipv4/xfrm4_mode_tunnel.c
··· 92 92 93 93 skb_reset_network_header(skb); 94 94 skb_mac_header_rebuild(skb); 95 - eth_hdr(skb)->h_proto = skb->protocol; 95 + if (skb->mac_len) 96 + eth_hdr(skb)->h_proto = skb->protocol; 96 97 97 98 err = 0; 98 99
+3 -1
net/ipv4/xfrm4_policy.c
··· 102 102 xdst->u.rt.rt_pmtu = rt->rt_pmtu; 103 103 xdst->u.rt.rt_table_id = rt->rt_table_id; 104 104 INIT_LIST_HEAD(&xdst->u.rt.rt_uncached); 105 + rt_add_uncached_list(&xdst->u.rt); 105 106 106 107 return 0; 107 108 } ··· 242 241 struct xfrm_dst *xdst = (struct xfrm_dst *)dst; 243 242 244 243 dst_destroy_metrics_generic(dst); 245 - 244 + if (xdst->u.rt.rt_uncached_list) 245 + rt_del_uncached_list(&xdst->u.rt); 246 246 xfrm_dst_destroy(xdst); 247 247 } 248 248
+2 -2
net/ipv6/route.c
··· 128 128 129 129 static DEFINE_PER_CPU_ALIGNED(struct uncached_list, rt6_uncached_list); 130 130 131 - static void rt6_uncached_list_add(struct rt6_info *rt) 131 + void rt6_uncached_list_add(struct rt6_info *rt) 132 132 { 133 133 struct uncached_list *ul = raw_cpu_ptr(&rt6_uncached_list); 134 134 ··· 139 139 spin_unlock_bh(&ul->lock); 140 140 } 141 141 142 - static void rt6_uncached_list_del(struct rt6_info *rt) 142 + void rt6_uncached_list_del(struct rt6_info *rt) 143 143 { 144 144 if (!list_empty(&rt->rt6i_uncached)) { 145 145 struct uncached_list *ul = rt->rt6i_uncached_list;
+2 -1
net/ipv6/xfrm6_mode_tunnel.c
··· 92 92 93 93 skb_reset_network_header(skb); 94 94 skb_mac_header_rebuild(skb); 95 - eth_hdr(skb)->h_proto = skb->protocol; 95 + if (skb->mac_len) 96 + eth_hdr(skb)->h_proto = skb->protocol; 96 97 97 98 err = 0; 98 99
+5
net/ipv6/xfrm6_policy.c
··· 113 113 xdst->u.rt6.rt6i_gateway = rt->rt6i_gateway; 114 114 xdst->u.rt6.rt6i_dst = rt->rt6i_dst; 115 115 xdst->u.rt6.rt6i_src = rt->rt6i_src; 116 + INIT_LIST_HEAD(&xdst->u.rt6.rt6i_uncached); 117 + rt6_uncached_list_add(&xdst->u.rt6); 118 + atomic_inc(&dev_net(dev)->ipv6.rt6_stats->fib_rt_uncache); 116 119 117 120 return 0; 118 121 } ··· 247 244 if (likely(xdst->u.rt6.rt6i_idev)) 248 245 in6_dev_put(xdst->u.rt6.rt6i_idev); 249 246 dst_destroy_metrics_generic(dst); 247 + if (xdst->u.rt6.rt6i_uncached_list) 248 + rt6_uncached_list_del(&xdst->u.rt6); 250 249 xfrm_dst_destroy(xdst); 251 250 } 252 251
+1 -1
net/xfrm/xfrm_ipcomp.c
··· 283 283 struct crypto_comp *tfm; 284 284 285 285 /* This can be any valid CPU ID so we don't need locking. */ 286 - tfm = __this_cpu_read(*pos->tfms); 286 + tfm = this_cpu_read(*pos->tfms); 287 287 288 288 if (!strcmp(crypto_comp_name(tfm), alg_name)) { 289 289 pos->users++;
+8 -5
net/xfrm/xfrm_policy.c
··· 1458 1458 static int xfrm_get_tos(const struct flowi *fl, int family) 1459 1459 { 1460 1460 const struct xfrm_policy_afinfo *afinfo; 1461 - int tos = 0; 1461 + int tos; 1462 1462 1463 1463 afinfo = xfrm_policy_get_afinfo(family); 1464 - tos = afinfo ? afinfo->get_tos(fl) : 0; 1464 + if (!afinfo) 1465 + return 0; 1466 + 1467 + tos = afinfo->get_tos(fl); 1465 1468 1466 1469 rcu_read_unlock(); 1467 1470 ··· 1894 1891 spin_unlock(&pq->hold_queue.lock); 1895 1892 1896 1893 dst_hold(xfrm_dst_path(dst)); 1897 - dst = xfrm_lookup(net, xfrm_dst_path(dst), &fl, sk, 0); 1894 + dst = xfrm_lookup(net, xfrm_dst_path(dst), &fl, sk, XFRM_LOOKUP_QUEUE); 1898 1895 if (IS_ERR(dst)) 1899 1896 goto purge_queue; 1900 1897 ··· 2732 2729 while (dst->xfrm) { 2733 2730 const struct xfrm_state *xfrm = dst->xfrm; 2734 2731 2732 + dst = xfrm_dst_child(dst); 2733 + 2735 2734 if (xfrm->props.mode == XFRM_MODE_TRANSPORT) 2736 2735 continue; 2737 2736 if (xfrm->type->flags & XFRM_TYPE_REMOTE_COADDR) 2738 2737 daddr = xfrm->coaddr; 2739 2738 else if (!(xfrm->type->flags & XFRM_TYPE_LOCAL_COADDR)) 2740 2739 daddr = &xfrm->id.daddr; 2741 - 2742 - dst = xfrm_dst_child(dst); 2743 2740 } 2744 2741 return daddr; 2745 2742 }
+1 -1
net/xfrm/xfrm_replay.c
··· 660 660 } else { 661 661 XFRM_SKB_CB(skb)->seq.output.low = oseq + 1; 662 662 XFRM_SKB_CB(skb)->seq.output.hi = oseq_hi; 663 - xo->seq.low = oseq = oseq + 1; 663 + xo->seq.low = oseq + 1; 664 664 xo->seq.hi = oseq_hi; 665 665 oseq += skb_shinfo(skb)->gso_segs; 666 666 }
+5
net/xfrm/xfrm_state.c
··· 2056 2056 struct xfrm_mgr *km; 2057 2057 struct xfrm_policy *pol = NULL; 2058 2058 2059 + #ifdef CONFIG_COMPAT 2060 + if (in_compat_syscall()) 2061 + return -EOPNOTSUPP; 2062 + #endif 2063 + 2059 2064 if (!optval && !optlen) { 2060 2065 xfrm_sk_policy_insert(sk, XFRM_POLICY_IN, NULL); 2061 2066 xfrm_sk_policy_insert(sk, XFRM_POLICY_OUT, NULL);
+10 -15
net/xfrm/xfrm_user.c
··· 121 121 struct nlattr *rt = attrs[XFRMA_REPLAY_ESN_VAL]; 122 122 struct xfrm_replay_state_esn *rs; 123 123 124 - if (p->flags & XFRM_STATE_ESN) { 125 - if (!rt) 126 - return -EINVAL; 127 - 128 - rs = nla_data(rt); 129 - 130 - if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8) 131 - return -EINVAL; 132 - 133 - if (nla_len(rt) < (int)xfrm_replay_state_esn_len(rs) && 134 - nla_len(rt) != sizeof(*rs)) 135 - return -EINVAL; 136 - } 137 - 138 124 if (!rt) 139 - return 0; 125 + return (p->flags & XFRM_STATE_ESN) ? -EINVAL : 0; 126 + 127 + rs = nla_data(rt); 128 + 129 + if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8) 130 + return -EINVAL; 131 + 132 + if (nla_len(rt) < (int)xfrm_replay_state_esn_len(rs) && 133 + nla_len(rt) != sizeof(*rs)) 134 + return -EINVAL; 140 135 141 136 /* As only ESP and AH support ESN feature. */ 142 137 if ((p->id.proto != IPPROTO_ESP) && (p->id.proto != IPPROTO_AH))