summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaolo Abeni <pabeni@redhat.com>2016-11-15 10:37:53 -0500
committerDavid S. Miller <davem@davemloft.net>2016-11-15 11:59:38 -0500
commitc915fe13cbaae5c7aa7b44f367d05addd60c9008 (patch)
treeb887552a905b9a209b9f800977027b9b8219f37e
parente6ca4f16a6950537132d0752581c967df2d911c4 (diff)
udplite: fix NULL pointer dereference
The commit 850cbaddb52d ("udp: use it's own memory accounting schema") assumes that the socket proto has memory accounting enabled, but this is not the case for UDPLITE. Fix it enabling memory accounting for UDPLITE and performing fwd allocated memory reclaiming on socket shutdown. UDP and UDPLITE share now the same memory accounting limits. Also drop the backlog receive operation, since is no more needed. Fixes: 850cbaddb52d ("udp: use it's own memory accounting schema") Reported-by: Andrei Vagin <avagin@gmail.com> Suggested-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/udp.h1
-rw-r--r--include/net/udplite.h1
-rw-r--r--net/ipv4/udp.c3
-rw-r--r--net/ipv4/udplite.c3
-rw-r--r--net/ipv6/udplite.c3
5 files changed, 8 insertions, 3 deletions
diff --git a/include/net/udp.h b/include/net/udp.h
index e6e4e19be387..1661791e8ca1 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -246,6 +246,7 @@ static inline __be16 udp_flow_src_port(struct net *net, struct sk_buff *skb,
246} 246}
247 247
248/* net/ipv4/udp.c */ 248/* net/ipv4/udp.c */
249void udp_destruct_sock(struct sock *sk);
249void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len); 250void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len);
250int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb); 251int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb);
251void udp_skb_destructor(struct sock *sk, struct sk_buff *skb); 252void udp_skb_destructor(struct sock *sk, struct sk_buff *skb);
diff --git a/include/net/udplite.h b/include/net/udplite.h
index 80761938b9a7..36097d388219 100644
--- a/include/net/udplite.h
+++ b/include/net/udplite.h
@@ -27,6 +27,7 @@ static __inline__ int udplite_getfrag(void *from, char *to, int offset,
27static inline int udplite_sk_init(struct sock *sk) 27static inline int udplite_sk_init(struct sock *sk)
28{ 28{
29 udp_sk(sk)->pcflag = UDPLITE_BIT; 29 udp_sk(sk)->pcflag = UDPLITE_BIT;
30 sk->sk_destruct = udp_destruct_sock;
30 return 0; 31 return 0;
31} 32}
32 33
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index c827e4ea509e..9ae7c63a8b13 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1253,7 +1253,7 @@ drop:
1253} 1253}
1254EXPORT_SYMBOL_GPL(__udp_enqueue_schedule_skb); 1254EXPORT_SYMBOL_GPL(__udp_enqueue_schedule_skb);
1255 1255
1256static void udp_destruct_sock(struct sock *sk) 1256void udp_destruct_sock(struct sock *sk)
1257{ 1257{
1258 /* reclaim completely the forward allocated memory */ 1258 /* reclaim completely the forward allocated memory */
1259 unsigned int total = 0; 1259 unsigned int total = 0;
@@ -1267,6 +1267,7 @@ static void udp_destruct_sock(struct sock *sk)
1267 1267
1268 inet_sock_destruct(sk); 1268 inet_sock_destruct(sk);
1269} 1269}
1270EXPORT_SYMBOL_GPL(udp_destruct_sock);
1270 1271
1271int udp_init_sock(struct sock *sk) 1272int udp_init_sock(struct sock *sk)
1272{ 1273{
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c
index af817158d830..59f10fe9782e 100644
--- a/net/ipv4/udplite.c
+++ b/net/ipv4/udplite.c
@@ -50,10 +50,11 @@ struct proto udplite_prot = {
50 .sendmsg = udp_sendmsg, 50 .sendmsg = udp_sendmsg,
51 .recvmsg = udp_recvmsg, 51 .recvmsg = udp_recvmsg,
52 .sendpage = udp_sendpage, 52 .sendpage = udp_sendpage,
53 .backlog_rcv = udp_queue_rcv_skb,
54 .hash = udp_lib_hash, 53 .hash = udp_lib_hash,
55 .unhash = udp_lib_unhash, 54 .unhash = udp_lib_unhash,
56 .get_port = udp_v4_get_port, 55 .get_port = udp_v4_get_port,
56 .memory_allocated = &udp_memory_allocated,
57 .sysctl_mem = sysctl_udp_mem,
57 .obj_size = sizeof(struct udp_sock), 58 .obj_size = sizeof(struct udp_sock),
58 .h.udp_table = &udplite_table, 59 .h.udp_table = &udplite_table,
59#ifdef CONFIG_COMPAT 60#ifdef CONFIG_COMPAT
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index 47d0d2b87106..2784cc363f2b 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -45,10 +45,11 @@ struct proto udplitev6_prot = {
45 .getsockopt = udpv6_getsockopt, 45 .getsockopt = udpv6_getsockopt,
46 .sendmsg = udpv6_sendmsg, 46 .sendmsg = udpv6_sendmsg,
47 .recvmsg = udpv6_recvmsg, 47 .recvmsg = udpv6_recvmsg,
48 .backlog_rcv = udpv6_queue_rcv_skb,
49 .hash = udp_lib_hash, 48 .hash = udp_lib_hash,
50 .unhash = udp_lib_unhash, 49 .unhash = udp_lib_unhash,
51 .get_port = udp_v6_get_port, 50 .get_port = udp_v6_get_port,
51 .memory_allocated = &udp_memory_allocated,
52 .sysctl_mem = sysctl_udp_mem,
52 .obj_size = sizeof(struct udp6_sock), 53 .obj_size = sizeof(struct udp6_sock),
53 .h.udp_table = &udplite_table, 54 .h.udp_table = &udplite_table,
54#ifdef CONFIG_COMPAT 55#ifdef CONFIG_COMPAT