memory leak in netlink user->kernel processing
Subsystems (2)
PATCH 1/1 memory leak in netlink user->kernel processing
netlink_kernel_create can be called with NULL as an input callback in several places, f.e. in kobject_uevent_init. This means that if one sends packet from user to kernel for such a socket, the packet will be leaked in the socket queue forever.
This patch adds a simple generic cleanup callback for these sockets.
net/netlink/af_netlink.c renamed from net/netlink/af_netlink.c.nlk4 +8 -2
@@ -1301,6 +1301,13 @@ out:return err ? : copied; } +static void netlink_rcv_drop (struct sock *sk,int len) +{ +struct sk_buff *skb; +while ((skb =skb_dequeue (&sk->sk_receive_queue)) !=NULL ) +kfree_skb (skb); +} +static void netlink_data_ready (struct sock *sk,int len) {struct netlink_sock *nlk =nlk_sk (sk);
@@ -1346,8 +1353,7 @@ netlink_kernel_create(struct net *net, i sk = sock->sk; sk->sk_data_ready = netlink_data_ready; -if (input) -nlk_sk (sk)->data_ready = input; +nlk_sk (sk)->data_ready = input !=NULL ? input : netlink_rcv_drop;if (netlink_insert (sk, net,0 )) goto out_sock_release;
Quoted 6 lines · Denis V. Lunev
netlink_kernel_createcan be called with NULL as an input callback in several places, f.e. inkobject_uevent_init. This means that if one sends packet from user to kernel for such a socket, the packet will be leaked in the socket queue forever.This patch adds a simple generic cleanup callback for these sockets.
This should already be handled by netlink_getsockbypid:
/* Don't bother queuing skb if kernel socket has no input
function */
nlk = nlk_sk(sock);
if ((nlk->pid == 0 && !nlk->data_ready) ||
(sock->sk_state == NETLINK_CONNECTED &&
nlk->dst_pid != nlk_sk(ssk)->pid)) {
sock_put(sock);
return ERR_PTR(-ECONNREFUSED);
}Quoted 20 lines · Patrick McHardy
Quoted 6 lines · Denis V. Lunev
netlink_kernel_createcan be called with NULL as an input callback in several places, f.e. inkobject_uevent_init. This means that if one sends packet from user to kernel for such a socket, the packet will be leaked in the socket queue forever.This patch adds a simple generic cleanup callback for these sockets.
This should already be handled by
netlink_getsockbypid:/* Don't bother queuing skb if kernel socket has no input function */ nlk = nlk_sk(sock); if ((nlk->pid == 0 && !nlk->data_ready) || (sock->sk_state == NETLINK_CONNECTED && nlk->dst_pid != nlk_sk(ssk)->pid)) { sock_put(sock); return ERR_PTR(-ECONNREFUSED); }
Quoted 5 lines
-
To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Looks so...
By the way, Patrick, this looks like nlk->pid == 0 if and only if this is a kernel socket. Right?
I have told with Alexey Kuznetsov and we have discrovered a way to get rid of
skb_queue_tail(&sk->sk_receive_queue, skb);
sk->sk_data_ready(sk, len);in netlink_sendskb/etc for kernel sockets and make user->kernel packets processing truly synchronous.
The idea is simple, we should queue/wakeup in kernel->user direction and simply call nlk->data_ready for user->kernel direction. This will remove all the crap we have now. But we need a mark to determine the direction. Which one will be better? (nlk->data_ready) or (nlk->pid == 0)
Regards,
Den
Quoted 3 lines · Denis V. Lunev
By the way, Patrick, this looks like
nlk->pid== 0 if and only if this is a kernel socket. Right?
Thats correct.
Quoted 11 lines
I have told with Alexey Kuznetsov and we have discrovered a way to get rid of
skb_queue_tail(&sk->sk_receive_queue, skb); sk->sk_data_ready(sk, len);in netlink_sendskb/etc for kernel sockets and make
user->kernelpackets processing truly synchronous.The idea is simple, we should queue/wakeup in
kernel->userdirection and simply callnlk->data_readyforuser->kerneldirection. This will remove all the crap we have now. But we need a mark to determine the direction. Which one will be better? (nlk->data_ready) or (nlk->pid== 0)
Both would work fine, but I think nlk->pid is better since its actually the "address".
Quoted 14 lines · Patrick McHardy
Quoted 3 lines · Denis V. Lunev
By the way, Patrick, this looks like
nlk->pid== 0 if and only if this is a kernel socket. Right?Thats correct.
Quoted 7 lines
I have told with Alexey Kuznetsov and we have discrovered a way to get rid of
skb_queue_tail(&sk->sk_receive_queue, skb); sk->sk_data_ready(sk, len);in netlink_sendskb/etc for kernel sockets and make
user->kernelpackets processing truly synchronous.
Quoted 8 lines
Quoted 4 lines
The idea is simple, we should queue/wakeup in
kernel->userdirection and simply callnlk->data_readyforuser->kerneldirection. This will remove all the crap we have now. But we need a mark to determine the direction. Which one will be better? (nlk->data_ready) or (nlk->pid== 0)Both would work fine, but I think
nlk->pidis better since its actually the "address".
Maybe. nlk->pid is also 0, before the socket is bound so it does not serve as a reliable indicator that you have a kernel socket.
My gut feel says the best test is:
(nlk->flags & NETLINK_KERNEL_SOCKET)
There is no confusion in that and it is dead obvious what we are testing for. Although we do still need to properly handle the case when netlink_kernel_create is called with a NULL input method. As long as get the proper -ECONNREFUSED the code path doesn't look like it matters.
Eric