96 lines
3.6 KiB
Diff
96 lines
3.6 KiB
Diff
From 16e7e2732879ab53d3620705807f5cbd0aace43e Mon Sep 17 00:00:00 2001
|
|
From: Mark Andrews <marka@isc.org>
|
|
Date: Fri, 21 Aug 2020 15:50:57 +1000
|
|
Subject: [PATCH] Address data races between socket bitfields
|
|
|
|
* address data race between sock->pending_recv and sock->connected
|
|
* address data race between sock->bound and sock->pending_recv
|
|
|
|
==================
|
|
WARNING: ThreadSanitizer: data race (pid=1985)
|
|
Read of size 2 at 0x7b54000c07c0 by thread T6:
|
|
#0 isc__socket_sendto /builds/isc-projects/bind9/lib/isc/unix/socket.c:5291:2 (libisc.so.1107+0x65a00)
|
|
#1 isc__socket_send /builds/isc-projects/bind9/lib/isc/unix/socket.c:5270:10 (libisc.so.1107+0x65944)
|
|
#2 isc_socket_send /builds/isc-projects/bind9/lib/isc/unix/./../socket_api.c:329:10 (libisc.so.1107+0x6b3c9)
|
|
#3 sendstream /builds/isc-projects/bind9/bin/named/xfrout.c:1548:3 (named+0x555038)
|
|
#4 ns_xfr_start /builds/isc-projects/bind9/bin/named/xfrout.c:1132:2 (named+0x553147)
|
|
#5 ns_query_start /builds/isc-projects/bind9/bin/named/query.c:9572:4 (named+0x4f3329)
|
|
#6 client_request /builds/isc-projects/bind9/bin/named/client.c:3115:3 (named+0x4de6af)
|
|
#7 dispatch /builds/isc-projects/bind9/lib/isc/task.c:1157:7 (libisc.so.1107+0x50845)
|
|
#8 run /builds/isc-projects/bind9/lib/isc/task.c:1331:2 (libisc.so.1107+0x4d799)
|
|
|
|
Previous write of size 2 at 0x7b54000c07c0 by thread T14 (mutexes: write M57, write M855819529908651432):
|
|
#0 dispatch_recv /builds/isc-projects/bind9/lib/isc/unix/socket.c:3353:21 (libisc.so.1107+0x6c601)
|
|
#1 process_fd /builds/isc-projects/bind9/lib/isc/unix/socket.c:4048:5 (libisc.so.1107+0x6c1be)
|
|
#2 process_fds /builds/isc-projects/bind9/lib/isc/unix/socket.c:4161:3 (libisc.so.1107+0x6bfc0)
|
|
#3 watcher /builds/isc-projects/bind9/lib/isc/unix/socket.c:4407:10 (libisc.so.1107+0x64398)
|
|
Conflict: NA
|
|
Reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/16e7e2732879ab53d3620705807f5cbd0aace43e
|
|
---
|
|
lib/isc/unix/socket.c | 19 ++++++-------------
|
|
1 file changed, 6 insertions(+), 13 deletions(-)
|
|
|
|
diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c
|
|
index 2b034d1762..0ebdf4c345 100644
|
|
--- a/lib/isc/unix/socket.c
|
|
+++ b/lib/isc/unix/socket.c
|
|
@@ -5175,7 +5175,6 @@ socket_send(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
|
|
unsigned int flags)
|
|
{
|
|
int io_state;
|
|
- bool have_lock = false;
|
|
isc_task_t *ntask = NULL;
|
|
isc_result_t result = ISC_R_SUCCESS;
|
|
|
|
@@ -5201,12 +5200,10 @@ socket_send(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
|
|
}
|
|
}
|
|
|
|
- if (sock->type == isc_sockettype_udp)
|
|
+ LOCK(&sock->lock);
|
|
+ if (sock->type == isc_sockettype_udp) {
|
|
io_state = doio_send(sock, dev);
|
|
- else {
|
|
- LOCK(&sock->lock);
|
|
- have_lock = true;
|
|
-
|
|
+ } else {
|
|
if (ISC_LIST_EMPTY(sock->send_list))
|
|
io_state = doio_send(sock, dev);
|
|
else
|
|
@@ -5223,11 +5220,6 @@ socket_send(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
|
|
isc_task_attach(task, &ntask);
|
|
dev->attributes |= ISC_SOCKEVENTATTR_ATTACHED;
|
|
|
|
- if (!have_lock) {
|
|
- LOCK(&sock->lock);
|
|
- have_lock = true;
|
|
- }
|
|
-
|
|
/*
|
|
* Enqueue the request. If the socket was previously
|
|
* not being watched, poke the watcher to start
|
|
@@ -5257,8 +5249,7 @@ socket_send(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
|
|
break;
|
|
}
|
|
|
|
- if (have_lock)
|
|
- UNLOCK(&sock->lock);
|
|
+ UNLOCK(&sock->lock);
|
|
|
|
return (result);
|
|
}
|
|
@@ -5291,7 +5282,9 @@ isc__socket_sendto(isc_socket_t *sock0, isc_region_t *region,
|
|
manager = sock->manager;
|
|
REQUIRE(VALID_MANAGER(manager));
|
|
|
|
+ LOCK(&sock->lock);
|
|
INSIST(sock->bound);
|
|
+ UNLOCK(&sock->lock);
|
|
|
|
dev = allocate_socketevent(manager->mctx, sock,
|
|
ISC_SOCKEVENT_SENDDONE, action, arg);
|
|
--
|
|
2.23.0
|
|
|