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

3708. [bug] Address a portentry locking issue in dispatch.c.

[RT #35128]
This commit is contained in:
Mark Andrews
2014-01-15 15:55:35 +11:00
parent cd7f8d18f8
commit 702958d202
2 changed files with 14 additions and 6 deletions

View File

@@ -1,3 +1,6 @@
3708. [bug] Address a portentry locking issue in dispatch.c.
[RT #35128]
3707. [bug] irs_resconf_load now returns ISC_R_FILENOTFOUND 3707. [bug] irs_resconf_load now returns ISC_R_FILENOTFOUND
on a missing resolv.conf file and initializes the on a missing resolv.conf file and initializes the
structure as if it had been configured with: structure as if it had been configured with:

View File

@@ -755,6 +755,7 @@ port_search(dns_dispatch_t *disp, in_port_t port) {
static dispportentry_t * static dispportentry_t *
new_portentry(dns_dispatch_t *disp, in_port_t port) { new_portentry(dns_dispatch_t *disp, in_port_t port) {
dispportentry_t *portentry; dispportentry_t *portentry;
dns_qid_t *qid;
REQUIRE(disp->port_table != NULL); REQUIRE(disp->port_table != NULL);
@@ -763,10 +764,13 @@ new_portentry(dns_dispatch_t *disp, in_port_t port) {
return (portentry); return (portentry);
portentry->port = port; portentry->port = port;
portentry->refs = 0; portentry->refs = 1;
ISC_LINK_INIT(portentry, link); ISC_LINK_INIT(portentry, link);
qid = DNS_QID(disp);
LOCK(&qid->lock);
ISC_LIST_APPEND(disp->port_table[port % DNS_DISPATCH_PORTTABLESIZE], ISC_LIST_APPEND(disp->port_table[port % DNS_DISPATCH_PORTTABLESIZE],
portentry, link); portentry, link);
UNLOCK(&qid->lock);
return (portentry); return (portentry);
} }
@@ -777,7 +781,6 @@ new_portentry(dns_dispatch_t *disp, in_port_t port) {
static void static void
deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) { deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) {
dispportentry_t *portentry = *portentryp; dispportentry_t *portentry = *portentryp;
isc_boolean_t unlink = ISC_FALSE;
dns_qid_t *qid; dns_qid_t *qid;
REQUIRE(disp->port_table != NULL); REQUIRE(disp->port_table != NULL);
@@ -786,15 +789,14 @@ deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) {
qid = DNS_QID(disp); qid = DNS_QID(disp);
LOCK(&qid->lock); LOCK(&qid->lock);
portentry->refs--; portentry->refs--;
unlink = ISC_TF(portentry->refs == 0);
UNLOCK(&qid->lock);
if (unlink) { if (portentry->refs == 0) {
ISC_LIST_UNLINK(disp->port_table[portentry->port % ISC_LIST_UNLINK(disp->port_table[portentry->port %
DNS_DISPATCH_PORTTABLESIZE], DNS_DISPATCH_PORTTABLESIZE],
portentry, link); portentry, link);
isc_mempool_put(disp->portpool, portentry); isc_mempool_put(disp->portpool, portentry);
} }
UNLOCK(&qid->lock);
*portentryp = NULL; *portentryp = NULL;
} }
@@ -916,8 +918,11 @@ get_dispsocket(dns_dispatch_t *disp, isc_sockaddr_t *dest,
result = ISC_R_NOMEMORY; result = ISC_R_NOMEMORY;
break; break;
} }
} else {
LOCK(&qid->lock);
portentry->refs++;
UNLOCK(&qid->lock);
} }
portentry->refs++;
break; break;
} else if (result == ISC_R_NOPERM) { } else if (result == ISC_R_NOPERM) {
char buf[ISC_SOCKADDR_FORMATSIZE]; char buf[ISC_SOCKADDR_FORMATSIZE];