[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20101208210100.46c894dd@chocolatine.cbg.collabora.co.uk>
Date: Wed, 8 Dec 2010 21:01:00 +0000
From: Alban Crequy <alban.crequy@...labora.co.uk>
To: netdev@...r.kernel.org
Subject: refcounting on dgram Unix sockets for poll(POLLOUT)
Hi,
When a connected datagram Unix socket is polled for POLLOUT events, the
poller is added in the wait_queue_head_t of the "server" socket:
net/unix/af_unix.c::unix_dgram_poll()
other = unix_peer_get(sk);
if (other) {
if (unix_peer(other) != sk) {
sock_poll_wait(file, &unix_sk(other)->peer_wait,
wait);
...
I wonder what prevent the "server" socket ("other") to be released
while the poller is still waiting for POLLOUT events.
There is a reference taken on the "server" socket when the client
connects:
net/unix/af_unix.c::unix_dgram_connect()
other = unix_find_other(net, sunaddr, alen, sock->type,
hash, &err);
But that reference could be released when the client socket
disconnects from another thread in one of the 3 possible locations:
1. unix_dgram_connect() when connecting to a different socket
if (other != old_peer)
unix_dgram_disconnected(sk, old_peer);
sock_put(old_peer);
2. unix_dgram_sendmsg() when the server socket is SOCK_DEAD:
unix_dgram_disconnected(sk, other);
sock_put(other);
3. unix_release_sock() when the client socket is released:
skpair = unix_peer(sk);
if (skpair != NULL) {
sock_put(skpair); /* It may now die */
I tried to release all the references to server_sockfd with
close(server_sockfd) on the server thread and with
connect(client_sockfd) to a different socket while client_sockfd is
being polled for POLLOUT events in a different thread, hoping to crash
the poller with the stack:
free_poll_entry()->remove_wait_queue()->spin_lock_irqsave()
But I didn't manage to crash the kernel.
Am I missing something? Is there another reference taken on
server_sockfd to protect the kernel from this scenario?
And btw, what is the test (unix_peer(other) != sk) in unix_dgram_poll()?
Alban
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists