udpv6: fix possible user after free in error handler
Before derefencing the encap pointer, commite7cc082455
("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:e7cc082455
("udp: Support for error handlers of tunnels with arbitrary destination port") Signed-off-by: Paolo Abeni <pabeni@redhat.com> Acked-by: Stefano Brivio <sbrivio@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
5de362df44
Коммит
424a7cd078
|
@ -420,17 +420,19 @@ EXPORT_SYMBOL(udpv6_encap_enable);
|
||||||
*/
|
*/
|
||||||
static int __udp6_lib_err_encap_no_sk(struct sk_buff *skb,
|
static int __udp6_lib_err_encap_no_sk(struct sk_buff *skb,
|
||||||
struct inet6_skb_parm *opt,
|
struct inet6_skb_parm *opt,
|
||||||
u8 type, u8 code, int offset, u32 info)
|
u8 type, u8 code, int offset, __be32 info)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < MAX_IPTUN_ENCAP_OPS; i++) {
|
for (i = 0; i < MAX_IPTUN_ENCAP_OPS; i++) {
|
||||||
int (*handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
|
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;
|
continue;
|
||||||
handler = rcu_dereference(ip6tun_encaps[i]->err_handler);
|
handler = encap->err_handler;
|
||||||
if (handler && !handler(skb, opt, type, code, offset, info))
|
if (handler && !handler(skb, opt, type, code, offset, info))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче