History

udpv6: fix possible user after free in error handler

Before derefencing the encap pointer, commit e7cc082455cb ("udp: Support for error handlers of tunnels with arbitrary destination port") checks for a NULL value, but the two fetch operation can race with removal. Fix the above using a single access. Also fix a couple of type annotations, to make sparse happy.

Paolo Abeni committed 7 years ago

Commit 424a7cd1 parent 5de362d1 file · +6 −4Browse files

Unified · Split

net/ipv6/udp.c+6−4
@@ -420,17 +420,19 @@ EXPORT_SYMBOL(udpv6_encap_enable); · 419 unmodified lines
420420 */
421421 static int __udp6_lib_err_encap_no_sk(struct sk_buff *skb,
422422 struct inet6_skb_parm *opt,
423− u8 type, u8 code, int offset, u32 info)
423+ u8 type, u8 code, int offset, __be32 info)
424424 {
425425 int i;
426426
427427 for (i = 0; i < MAX_IPTUN_ENCAP_OPS; i++) {
428428 int (*handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
429− u8 type, u8 code, int offset, u32 info);
429+ u8 type, u8 code, int offset, __be32 info);
430+ const struct ip6_tnl_encap_ops *encap;
430431
431− if (!ip6tun_encaps[i])
432+ encap = rcu_dereference(ip6tun_encaps[i]);
433+ if (!encap)
432434 continue;
433− handler = rcu_dereference(ip6tun_encaps[i]->err_handler);
435+ handler = encap->err_handler;
434436 if (handler && !handler(skb, opt, type, code, offset, info))
435437 return 0;
436438 }