Commit 5eafd1e3 authored by Eric Dumazet's avatar Eric Dumazet Committed by Kleber Sacilotto de Souza

udplite: call proper backlog handlers

BugLink: https://bugs.launchpad.net/bugs/1822271

commit 30c7be26 upstream.

In commits 93821778 ("udp: Fix rcv socket locking") and
f7ad74fe ("net/ipv6/udp: UDP encapsulation: break backlog_rcv into
__udpv6_queue_rcv_skb") UDP backlog handlers were renamed, but UDPlite
was forgotten.

This leads to crashes if UDPlite header is pulled twice, which happens
starting from commit e6afc8ac ("udp: remove headers from UDP packets
before queueing")

Bug found by syzkaller team, thanks a lot guys !

Note that backlog use in UDP/UDPlite is scheduled to be removed starting
from linux-4.10, so this patch is only needed up to linux-4.9

Fixes: 93821778 ("udp: Fix rcv socket locking")
Fixes: f7ad74fe ("net/ipv6/udp: UDP encapsulation: break backlog_rcv into __udpv6_queue_rcv_skb")
Fixes: e6afc8ac ("udp: remove headers from UDP packets before queueing")
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Reported-by: default avatarAndrey Konovalov <andreyknvl@google.com>
Cc: Benjamin LaHaise <bcrl@kvack.org>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Cc: Zubin Mithra <zsm@chromium.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarStefan Bader <stefan.bader@canonical.com>
Acked-by: default avatarJuerg Haefliger <juerg.haefliger@canonical.com>
Signed-off-by: default avatarKleber Sacilotto de Souza <kleber.souza@canonical.com>
parent 01dea34e
...@@ -1464,7 +1464,7 @@ static void udp_v4_rehash(struct sock *sk) ...@@ -1464,7 +1464,7 @@ static void udp_v4_rehash(struct sock *sk)
udp_lib_rehash(sk, new_hash); udp_lib_rehash(sk, new_hash);
} }
static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
{ {
int rc; int rc;
......
...@@ -25,7 +25,7 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock, ...@@ -25,7 +25,7 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
int flags, int *addr_len); int flags, int *addr_len);
int udp_sendpage(struct sock *sk, struct page *page, int offset, size_t size, int udp_sendpage(struct sock *sk, struct page *page, int offset, size_t size,
int flags); int flags);
int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
void udp_destroy_sock(struct sock *sk); void udp_destroy_sock(struct sock *sk);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
......
...@@ -50,7 +50,7 @@ struct proto udplite_prot = { ...@@ -50,7 +50,7 @@ struct proto udplite_prot = {
.sendmsg = udp_sendmsg, .sendmsg = udp_sendmsg,
.recvmsg = udp_recvmsg, .recvmsg = udp_recvmsg,
.sendpage = udp_sendpage, .sendpage = udp_sendpage,
.backlog_rcv = udp_queue_rcv_skb, .backlog_rcv = __udp_queue_rcv_skb,
.hash = udp_lib_hash, .hash = udp_lib_hash,
.unhash = udp_lib_unhash, .unhash = udp_lib_unhash,
.get_port = udp_v4_get_port, .get_port = udp_v4_get_port,
......
...@@ -585,7 +585,7 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -585,7 +585,7 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
sock_put(sk); sock_put(sk);
} }
static int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
{ {
int rc; int rc;
......
...@@ -26,7 +26,7 @@ int compat_udpv6_getsockopt(struct sock *sk, int level, int optname, ...@@ -26,7 +26,7 @@ int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,
int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len); int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len);
int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock, int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
int flags, int *addr_len); int flags, int *addr_len);
int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
void udpv6_destroy_sock(struct sock *sk); void udpv6_destroy_sock(struct sock *sk);
void udp_v6_clear_sk(struct sock *sk, int size); void udp_v6_clear_sk(struct sock *sk, int size);
......
...@@ -45,7 +45,7 @@ struct proto udplitev6_prot = { ...@@ -45,7 +45,7 @@ struct proto udplitev6_prot = {
.getsockopt = udpv6_getsockopt, .getsockopt = udpv6_getsockopt,
.sendmsg = udpv6_sendmsg, .sendmsg = udpv6_sendmsg,
.recvmsg = udpv6_recvmsg, .recvmsg = udpv6_recvmsg,
.backlog_rcv = udpv6_queue_rcv_skb, .backlog_rcv = __udpv6_queue_rcv_skb,
.hash = udp_lib_hash, .hash = udp_lib_hash,
.unhash = udp_lib_unhash, .unhash = udp_lib_unhash,
.get_port = udp_v6_get_port, .get_port = udp_v6_get_port,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment