2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 14:35:26 +00:00

2504. [bug] Address race condition in the socket code. [RT #18899]

This commit is contained in:
Mark Andrews
2008-12-03 02:03:47 +00:00
parent fc8e82904a
commit d8fc8514b1
2 changed files with 25 additions and 15 deletions

View File

@@ -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]

View File

@@ -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