History

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

Steffen Klassert says: ==================== pull request (net): ipsec 2020-03-27 1) Handle NETDEV_UNREGISTER for xfrm device to handle asynchronous unregister events cleanly. From Raed Salem. 2) Fix vti6 tunnel inter address family TX through bpf_redirect(). From Nicolas Dichtel. 3) Fix lenght check in verify_sec_ctx_len() to avoid a slab-out-of-bounds. From Xin Long. 4) Add a missing verify_sec_ctx_len check in xfrm_add_acquire to avoid a possible out-of-bounds to access. From Xin Long. 5) Use built-in RCU list checking of hlist_for_each_entry_rcu to silence false lockdep warning in __xfrm6_tunnel_spi_lookup when CONFIG_PROVE_RCU_LIST is enabled. From Madhuparna Bhowmik. 6) Fix a panic on esp offload when crypto is done asynchronously. From Xin Long. 7) Fix a skb memory leak in an error path of vti6_rcv. From Torsten Hilbrich. 8) Fix a race that can lead to a doulbe free in xfrm_policy_timer. From Xin Long. ====================

David S. Miller committed 6 years ago

Commit e00dd942 parents 8262e6f 4c594067 files · +70 −22Browse files

Unified · Split

7 files
  1. net/ipv4/Kconfig +1 −0
  2. net/ipv4/ip_vti.c +30 −8
  3. net/ipv6/ip6_vti.c +26 −8
  4. net/ipv6/xfrm6_tunnel.c +1 −1
  5. net/xfrm/xfrm_device.c +5 −4
  6. net/xfrm/xfrm_policy.c +2 −0
  7. net/xfrm/xfrm_user.c +5 −1
net/ipv4/Kconfig+1−0
@@ -303,6 +303,7 @@ config SYN_COOKIES · 302 unmodified lines
303 303
304config NET_IPVTI304config NET_IPVTI
305 tristate "Virtual (secure) IP: tunneling"305 tristate "Virtual (secure) IP: tunneling"
306 depends on IPV6 || IPV6=n
306 select INET_TUNNEL307 select INET_TUNNEL
307 select NET_IP_TUNNEL308 select NET_IP_TUNNEL
308 select XFRM309 select XFRM
net/ipv4/ip_vti.c+30−8
@@ -187,17 +187,39 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev, · 186 unmodified lines
187 int mtu;187 int mtu;
188 188
189 if (!dst) {189 if (!dst) {
190 struct rtable *rt;190 switch (skb->protocol) {
191 191 case htons(ETH_P_IP): {
192 fl->u.ip4.flowi4_oif = dev->ifindex;192 struct rtable *rt;
193 fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC;193
194 rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4);194 fl->u.ip4.flowi4_oif = dev->ifindex;
195 if (IS_ERR(rt)) {195 fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC;
196 rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4);
197 if (IS_ERR(rt)) {
198 dev->stats.tx_carrier_errors++;
199 goto tx_error_icmp;
200 }
201 dst = &rt->dst;
202 skb_dst_set(skb, dst);
203 break;
204 }
205#if IS_ENABLED(CONFIG_IPV6)
206 case htons(ETH_P_IPV6):
207 fl->u.ip6.flowi6_oif = dev->ifindex;
208 fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC;
209 dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6);
210 if (dst->error) {
211 dst_release(dst);
212 dst = NULL;
213 dev->stats.tx_carrier_errors++;
214 goto tx_error_icmp;
215 }
216 skb_dst_set(skb, dst);
217 break;
218#endif
219 default:
196 dev->stats.tx_carrier_errors++;220 dev->stats.tx_carrier_errors++;
197 goto tx_error_icmp;221 goto tx_error_icmp;
198 }222 }
199 dst = &rt->dst;
200 skb_dst_set(skb, dst);
201 }223 }
202 224
203 dst_hold(dst);225 dst_hold(dst);
net/ipv6/ip6_vti.c+26−8
@@ -311,7 +311,7 @@ static int vti6_rcv(struct sk_buff *skb) · 310 unmodified lines
311 311
312 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {312 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
313 rcu_read_unlock();313 rcu_read_unlock();
314 return 0;314 goto discard;
315 }315 }
316 316
317 ipv6h = ipv6_hdr(skb);317 ipv6h = ipv6_hdr(skb);
@@ -450,15 +450,33 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) · 132 unmodified lines
450 int mtu;450 int mtu;
451 451
452 if (!dst) {452 if (!dst) {
453 fl->u.ip6.flowi6_oif = dev->ifindex;453 switch (skb->protocol) {
454 fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC;454 case htons(ETH_P_IP): {
455 dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6);455 struct rtable *rt;
456 if (dst->error) {456
457 dst_release(dst);457 fl->u.ip4.flowi4_oif = dev->ifindex;
458 dst = NULL;458 fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC;
459 rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4);
460 if (IS_ERR(rt))
461 goto tx_err_link_failure;
462 dst = &rt->dst;
463 skb_dst_set(skb, dst);
464 break;
465 }
466 case htons(ETH_P_IPV6):
467 fl->u.ip6.flowi6_oif = dev->ifindex;
468 fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC;
469 dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6);
470 if (dst->error) {
471 dst_release(dst);
472 dst = NULL;
473 goto tx_err_link_failure;
474 }
475 skb_dst_set(skb, dst);
476 break;
477 default:
459 goto tx_err_link_failure;478 goto tx_err_link_failure;
460 }479 }
461 skb_dst_set(skb, dst);
462 }480 }
463 481
464 dst_hold(dst);482 dst_hold(dst);
net/ipv6/xfrm6_tunnel.c+1−1
@@ -78,7 +78,7 @@ static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(struct net *net, const · 77 unmodified lines
78 78
79 hlist_for_each_entry_rcu(x6spi,79 hlist_for_each_entry_rcu(x6spi,
80 &xfrm6_tn->spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],80 &xfrm6_tn->spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
81 list_byaddr) {81 list_byaddr, lockdep_is_held(&xfrm6_tunnel_spi_lock)) {
82 if (xfrm6_addr_equal(&x6spi->addr, saddr))82 if (xfrm6_addr_equal(&x6spi->addr, saddr))
83 return x6spi;83 return x6spi;
84 }84 }
net/xfrm/xfrm_device.c+5−4
@@ -78,8 +78,8 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur · 77 unmodified lines
78 int err;78 int err;
79 unsigned long flags;79 unsigned long flags;
80 struct xfrm_state *x;80 struct xfrm_state *x;
81 struct sk_buff *skb2, *nskb;
82 struct softnet_data *sd;81 struct softnet_data *sd;
82 struct sk_buff *skb2, *nskb, *pskb = NULL;
83 netdev_features_t esp_features = features;83 netdev_features_t esp_features = features;
84 struct xfrm_offload *xo = xfrm_offload(skb);84 struct xfrm_offload *xo = xfrm_offload(skb);
85 struct sec_path *sp;85 struct sec_path *sp;
@@ -168,14 +168,14 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur · 82 unmodified lines
168 } else {168 } else {
169 if (skb == skb2)169 if (skb == skb2)
170 skb = nskb;170 skb = nskb;
171 171 else
172 if (!skb)172 pskb->next = nskb;
173 return NULL;
174 173
175 continue;174 continue;
176 }175 }
177 176
178 skb_push(skb2, skb2->data - skb_mac_header(skb2));177 skb_push(skb2, skb2->data - skb_mac_header(skb2));
178 pskb = skb2;
179 }179 }
180 180
181 return skb;181 return skb;
@@ -383,6 +383,7 @@ static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void · 201 unmodified lines
383 return xfrm_dev_feat_change(dev);383 return xfrm_dev_feat_change(dev);
384 384
385 case NETDEV_DOWN:385 case NETDEV_DOWN:
386 case NETDEV_UNREGISTER:
386 return xfrm_dev_down(dev);387 return xfrm_dev_down(dev);
387 }388 }
388 return NOTIFY_DONE;389 return NOTIFY_DONE;
net/xfrm/xfrm_policy.c+2−0
@@ -434,7 +434,9 @@ EXPORT_SYMBOL(xfrm_policy_destroy); · 433 unmodified lines
434 434
435static void xfrm_policy_kill(struct xfrm_policy *policy)435static void xfrm_policy_kill(struct xfrm_policy *policy)
436{436{
437 write_lock_bh(&policy->lock);
437 policy->walk.dead = 1;438 policy->walk.dead = 1;
439 write_unlock_bh(&policy->lock);
438 440
439 atomic_inc(&policy->genid);441 atomic_inc(&policy->genid);
440 442
net/xfrm/xfrm_user.c+5−1
@@ -110,7 +110,8 @@ static inline int verify_sec_ctx_len(struct nlattr **attrs) · 109 unmodified lines
110 return 0;110 return 0;
111 111
112 uctx = nla_data(rt);112 uctx = nla_data(rt);
113 if (uctx->len != (sizeof(struct xfrm_user_sec_ctx) + uctx->ctx_len))113 if (uctx->len > nla_len(rt) ||
114 uctx->len != (sizeof(struct xfrm_user_sec_ctx) + uctx->ctx_len))
114 return -EINVAL;115 return -EINVAL;
115 116
116 return 0;117 return 0;
@@ -2273,6 +2274,9 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, · 2156 unmodified lines
2273 xfrm_mark_get(attrs, &mark);2274 xfrm_mark_get(attrs, &mark);
2274 2275
2275 err = verify_newpolicy_info(&ua->policy);2276 err = verify_newpolicy_info(&ua->policy);
2277 if (err)
2278 goto free_state;
2279 err = verify_sec_ctx_len(attrs);
2276 if (err)2280 if (err)
2277 goto free_state;2281 goto free_state;
2278 2282