udplite: fix NULL pointer dereference
authorPaolo Abeni <pabeni@redhat.com>
Tue, 15 Nov 2016 15:37:53 +0000 (16:37 +0100)
committerDavid S. Miller <davem@davemloft.net>
Tue, 15 Nov 2016 16:59:38 +0000 (11:59 -0500)
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>
include/net/udp.h
include/net/udplite.h
net/ipv4/udp.c
net/ipv4/udplite.c
net/ipv6/udplite.c

index e6e4e19be387cb14b4afe06e2ab717d1e7a9d0b7..1661791e8ca19bbc8f59e5c19263486b24f24b45 100644 (file)
@@ -246,6 +246,7 @@ static inline __be16 udp_flow_src_port(struct net *net, struct sk_buff *skb,
 }
 
 /* net/ipv4/udp.c */
+void udp_destruct_sock(struct sock *sk);
 void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len);
 int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb);
 void udp_skb_destructor(struct sock *sk, struct sk_buff *skb);
index 80761938b9a78081822a4b82b4bd3fb30b5f6625..36097d388219ed1e205e607a756697c3eb4e00c6 100644 (file)
@@ -27,6 +27,7 @@ static __inline__ int udplite_getfrag(void *from, char *to, int  offset,
 static inline int udplite_sk_init(struct sock *sk)
 {
        udp_sk(sk)->pcflag = UDPLITE_BIT;
+       sk->sk_destruct = udp_destruct_sock;
        return 0;
 }
 
index c827e4ea509efde4d5ef81d6b2a9c211d259767f..9ae7c63a8b131f56a3c05e00a8f7d106a0362c54 100644 (file)
@@ -1253,7 +1253,7 @@ drop:
 }
 EXPORT_SYMBOL_GPL(__udp_enqueue_schedule_skb);
 
-static void udp_destruct_sock(struct sock *sk)
+void udp_destruct_sock(struct sock *sk)
 {
        /* reclaim completely the forward allocated memory */
        unsigned int total = 0;
@@ -1267,6 +1267,7 @@ static void udp_destruct_sock(struct sock *sk)
 
        inet_sock_destruct(sk);
 }
+EXPORT_SYMBOL_GPL(udp_destruct_sock);
 
 int udp_init_sock(struct sock *sk)
 {
index af817158d830c0da080935ba29e012dffbb89112..59f10fe9782e57b9d40facc369f412195639b84b 100644 (file)
@@ -50,10 +50,11 @@ struct proto        udplite_prot = {
        .sendmsg           = udp_sendmsg,
        .recvmsg           = udp_recvmsg,
        .sendpage          = udp_sendpage,
-       .backlog_rcv       = udp_queue_rcv_skb,
        .hash              = udp_lib_hash,
        .unhash            = udp_lib_unhash,
        .get_port          = udp_v4_get_port,
+       .memory_allocated  = &udp_memory_allocated,
+       .sysctl_mem        = sysctl_udp_mem,
        .obj_size          = sizeof(struct udp_sock),
        .h.udp_table       = &udplite_table,
 #ifdef CONFIG_COMPAT
index 47d0d2b87106558fece3496479198005c55b99e7..2784cc363f2b533df16effcec35ffcdc2b528885 100644 (file)
@@ -45,10 +45,11 @@ struct proto udplitev6_prot = {
        .getsockopt        = udpv6_getsockopt,
        .sendmsg           = udpv6_sendmsg,
        .recvmsg           = udpv6_recvmsg,
-       .backlog_rcv       = udpv6_queue_rcv_skb,
        .hash              = udp_lib_hash,
        .unhash            = udp_lib_unhash,
        .get_port          = udp_v6_get_port,
+       .memory_allocated  = &udp_memory_allocated,
+       .sysctl_mem        = sysctl_udp_mem,
        .obj_size          = sizeof(struct udp6_sock),
        .h.udp_table       = &udplite_table,
 #ifdef CONFIG_COMPAT