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:
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
|
2503. [port] linux: improve compatibility with Linux Standard
|
||||||
Base. [RT #18793]
|
Base. [RT #18793]
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* 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 */
|
/*! \file */
|
||||||
|
|
||||||
@@ -2360,18 +2360,15 @@ isc_socket_detach(isc_socket_t **socketp) {
|
|||||||
isc_result_t
|
isc_result_t
|
||||||
isc_socket_close(isc_socket_t *sock) {
|
isc_socket_close(isc_socket_t *sock) {
|
||||||
int fd;
|
int fd;
|
||||||
|
isc_socketmgr_t *manager;
|
||||||
|
isc_sockettype_t type;
|
||||||
|
|
||||||
REQUIRE(VALID_SOCKET(sock));
|
REQUIRE(VALID_SOCKET(sock));
|
||||||
|
|
||||||
LOCK(&sock->lock);
|
LOCK(&sock->lock);
|
||||||
|
|
||||||
REQUIRE(sock->references == 1);
|
REQUIRE(sock->references == 1);
|
||||||
REQUIRE(sock->type != isc_sockettype_fdwatch);
|
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);
|
REQUIRE(sock->fd >= 0 && sock->fd < (int)sock->manager->maxsocks);
|
||||||
|
|
||||||
INSIST(!sock->connecting);
|
INSIST(!sock->connecting);
|
||||||
@@ -2383,6 +2380,8 @@ isc_socket_close(isc_socket_t *sock) {
|
|||||||
INSIST(ISC_LIST_EMPTY(sock->accept_list));
|
INSIST(ISC_LIST_EMPTY(sock->accept_list));
|
||||||
INSIST(sock->connect_ev == NULL);
|
INSIST(sock->connect_ev == NULL);
|
||||||
|
|
||||||
|
manager = sock->manager;
|
||||||
|
type = sock->type;
|
||||||
fd = sock->fd;
|
fd = sock->fd;
|
||||||
sock->fd = -1;
|
sock->fd = -1;
|
||||||
sock->listener = 0;
|
sock->listener = 0;
|
||||||
@@ -2390,8 +2389,9 @@ isc_socket_close(isc_socket_t *sock) {
|
|||||||
sock->connecting = 0;
|
sock->connecting = 0;
|
||||||
sock->bound = 0;
|
sock->bound = 0;
|
||||||
isc_sockaddr_any(&sock->peer_address);
|
isc_sockaddr_any(&sock->peer_address);
|
||||||
|
UNLOCK(&sock->lock);
|
||||||
|
|
||||||
closesocket(sock->manager, sock->type, fd);
|
closesocket(manager, type, fd);
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
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_socket_t *sock;
|
||||||
isc_boolean_t unlock_sock;
|
isc_boolean_t unlock_sock;
|
||||||
|
isc_boolean_t unwatch_read = ISC_FALSE, unwatch_write = ISC_FALSE;
|
||||||
int lockid = FDLOCK_ID(fd);
|
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];
|
sock = manager->fds[fd];
|
||||||
UNLOCK(&manager->fdlock[lockid]);
|
|
||||||
unlock_sock = ISC_FALSE;
|
unlock_sock = ISC_FALSE;
|
||||||
if (readable) {
|
if (readable) {
|
||||||
if (sock == NULL) {
|
if (sock == NULL) {
|
||||||
(void)unwatch_fd(manager, fd, SELECT_POKE_READ);
|
unwatch_read = ISC_TRUE;
|
||||||
goto check_write;
|
goto check_write;
|
||||||
}
|
}
|
||||||
unlock_sock = ISC_TRUE;
|
unlock_sock = ISC_TRUE;
|
||||||
LOCK(&sock->lock);
|
LOCK(&sock->lock); /* XXXMPA */
|
||||||
if (!SOCK_DEAD(sock)) {
|
if (!SOCK_DEAD(sock)) {
|
||||||
if (sock->listener)
|
if (sock->listener)
|
||||||
dispatch_accept(sock);
|
dispatch_accept(sock);
|
||||||
else
|
else
|
||||||
dispatch_recv(sock);
|
dispatch_recv(sock);
|
||||||
}
|
}
|
||||||
(void)unwatch_fd(manager, fd, SELECT_POKE_READ);
|
unwatch_read = ISC_TRUE;
|
||||||
}
|
}
|
||||||
check_write:
|
check_write:
|
||||||
if (writeable) {
|
if (writeable) {
|
||||||
if (sock == NULL) {
|
if (sock == NULL) {
|
||||||
(void)unwatch_fd(manager, fd, SELECT_POKE_WRITE);
|
unwatch_write = ISC_TRUE;
|
||||||
return;
|
goto unlock_fd;
|
||||||
}
|
}
|
||||||
if (!unlock_sock) {
|
if (!unlock_sock) {
|
||||||
unlock_sock = ISC_TRUE;
|
unlock_sock = ISC_TRUE;
|
||||||
@@ -3076,10 +3076,18 @@ check_write:
|
|||||||
else
|
else
|
||||||
dispatch_send(sock);
|
dispatch_send(sock);
|
||||||
}
|
}
|
||||||
(void)unwatch_fd(manager, fd, SELECT_POKE_WRITE);
|
unwatch_write = ISC_TRUE;
|
||||||
}
|
}
|
||||||
if (unlock_sock)
|
if (unlock_sock)
|
||||||
UNLOCK(&sock->lock);
|
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
|
#ifdef USE_KQUEUE
|
||||||
|
Reference in New Issue
Block a user