Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 424a7cd0 authored by Paolo Abeni's avatar Paolo Abeni Committed by David S. Miller
Browse files

udpv6: fix possible user after free in error handler



Before derefencing the encap pointer, commit e7cc0824 ("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.

Fixes: e7cc0824 ("udp: Support for error handlers of tunnels with arbitrary destination port")
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Acked-by: default avatarStefano Brivio <sbrivio@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5de362df
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -420,17 +420,19 @@ EXPORT_SYMBOL(udpv6_encap_enable);
 */
static int __udp6_lib_err_encap_no_sk(struct sk_buff *skb,
				      struct inet6_skb_parm *opt,
				      u8 type, u8 code, int offset, u32 info)
				      u8 type, u8 code, int offset, __be32 info)
{
	int i;

	for (i = 0; i < MAX_IPTUN_ENCAP_OPS; i++) {
		int (*handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
			       u8 type, u8 code, int offset, u32 info);
			       u8 type, u8 code, int offset, __be32 info);
		const struct ip6_tnl_encap_ops *encap;

		if (!ip6tun_encaps[i])
		encap = rcu_dereference(ip6tun_encaps[i]);
		if (!encap)
			continue;
		handler = rcu_dereference(ip6tun_encaps[i]->err_handler);
		handler = encap->err_handler;
		if (handler && !handler(skb, opt, type, code, offset, info))
			return 0;
	}