mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
2504. [bug] Address race condition in the socket code. [RT #18899]
This commit is contained in:
2
CHANGES
2
CHANGES
@@ -1,3 +1,5 @@
|
||||
2504. [bug] Address race condition in the socket code. [RT #18899]
|
||||
|
||||
2503. [port] linux: improve compatibility with Linux Standard
|
||||
Base. [RT #18793]
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: socket.c,v 1.309 2008/12/01 00:15:37 marka Exp $ */
|
||||
/* $Id: socket.c,v 1.310 2008/12/03 02:03:47 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@@ -2360,18 +2360,15 @@ isc_socket_detach(isc_socket_t **socketp) {
|
||||
isc_result_t
|
||||
isc_socket_close(isc_socket_t *sock) {
|
||||
int fd;
|
||||
isc_socketmgr_t *manager;
|
||||
isc_sockettype_t type;
|
||||
|
||||
REQUIRE(VALID_SOCKET(sock));
|
||||
|
||||
LOCK(&sock->lock);
|
||||
|
||||
REQUIRE(sock->references == 1);
|
||||
REQUIRE(sock->type != isc_sockettype_fdwatch);
|
||||
UNLOCK(&sock->lock);
|
||||
/*
|
||||
* We don't need to retain the lock hereafter, since no one else has
|
||||
* this socket.
|
||||
*/
|
||||
|
||||
REQUIRE(sock->fd >= 0 && sock->fd < (int)sock->manager->maxsocks);
|
||||
|
||||
INSIST(!sock->connecting);
|
||||
@@ -2383,6 +2380,8 @@ isc_socket_close(isc_socket_t *sock) {
|
||||
INSIST(ISC_LIST_EMPTY(sock->accept_list));
|
||||
INSIST(sock->connect_ev == NULL);
|
||||
|
||||
manager = sock->manager;
|
||||
type = sock->type;
|
||||
fd = sock->fd;
|
||||
sock->fd = -1;
|
||||
sock->listener = 0;
|
||||
@@ -2390,8 +2389,9 @@ isc_socket_close(isc_socket_t *sock) {
|
||||
sock->connecting = 0;
|
||||
sock->bound = 0;
|
||||
isc_sockaddr_any(&sock->peer_address);
|
||||
UNLOCK(&sock->lock);
|
||||
|
||||
closesocket(sock->manager, sock->type, fd);
|
||||
closesocket(manager, type, fd);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
@@ -3028,6 +3028,7 @@ process_fd(isc_socketmgr_t *manager, int fd, isc_boolean_t readable,
|
||||
{
|
||||
isc_socket_t *sock;
|
||||
isc_boolean_t unlock_sock;
|
||||
isc_boolean_t unwatch_read = ISC_FALSE, unwatch_write = ISC_FALSE;
|
||||
int lockid = FDLOCK_ID(fd);
|
||||
|
||||
/*
|
||||
@@ -3043,28 +3044,27 @@ process_fd(isc_socketmgr_t *manager, int fd, isc_boolean_t readable,
|
||||
}
|
||||
|
||||
sock = manager->fds[fd];
|
||||
UNLOCK(&manager->fdlock[lockid]);
|
||||
unlock_sock = ISC_FALSE;
|
||||
if (readable) {
|
||||
if (sock == NULL) {
|
||||
(void)unwatch_fd(manager, fd, SELECT_POKE_READ);
|
||||
unwatch_read = ISC_TRUE;
|
||||
goto check_write;
|
||||
}
|
||||
unlock_sock = ISC_TRUE;
|
||||
LOCK(&sock->lock);
|
||||
LOCK(&sock->lock); /* XXXMPA */
|
||||
if (!SOCK_DEAD(sock)) {
|
||||
if (sock->listener)
|
||||
dispatch_accept(sock);
|
||||
else
|
||||
dispatch_recv(sock);
|
||||
}
|
||||
(void)unwatch_fd(manager, fd, SELECT_POKE_READ);
|
||||
unwatch_read = ISC_TRUE;
|
||||
}
|
||||
check_write:
|
||||
if (writeable) {
|
||||
if (sock == NULL) {
|
||||
(void)unwatch_fd(manager, fd, SELECT_POKE_WRITE);
|
||||
return;
|
||||
unwatch_write = ISC_TRUE;
|
||||
goto unlock_fd;
|
||||
}
|
||||
if (!unlock_sock) {
|
||||
unlock_sock = ISC_TRUE;
|
||||
@@ -3076,10 +3076,18 @@ check_write:
|
||||
else
|
||||
dispatch_send(sock);
|
||||
}
|
||||
(void)unwatch_fd(manager, fd, SELECT_POKE_WRITE);
|
||||
unwatch_write = ISC_TRUE;
|
||||
}
|
||||
if (unlock_sock)
|
||||
UNLOCK(&sock->lock);
|
||||
|
||||
unlock_fd:
|
||||
UNLOCK(&manager->fdlock[lockid]);
|
||||
if (unwatch_read)
|
||||
(void)unwatch_fd(manager, fd, SELECT_POKE_READ);
|
||||
if (unwatch_write)
|
||||
(void)unwatch_fd(manager, fd, SELECT_POKE_WRITE);
|
||||
|
||||
}
|
||||
|
||||
#ifdef USE_KQUEUE
|
||||
|
Reference in New Issue
Block a user