]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Address lock-order-inversion
authorMark Andrews <marka@isc.org>
Tue, 22 Sep 2020 06:24:06 +0000 (16:24 +1000)
committerMark Andrews <marka@isc.org>
Tue, 22 Sep 2020 12:29:09 +0000 (22:29 +1000)
    WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock)
    Cycle in lock order graph: M1 (0x000000000001) => M2 (0x000000000002) => M1

    Mutex M2 acquired here while holding mutex M1 in thread T1:
    #0 pthread_rwlock_wrlock <null>
    #1 isc_rwlock_lock lib/isc/rwlock.c:52:4
    #2 zone_postload lib/dns/zone.c:5101:2
    #3 receive_secure_db lib/dns/zone.c:16206:11
    #4 dispatch lib/isc/task.c:1152:7
    #5 run lib/isc/task.c:1344:2

    Mutex M1 previously acquired by the same thread here:
    #0 pthread_mutex_lock <null>
    #1 receive_secure_db lib/dns/zone.c:16204:2
    #2 dispatch lib/isc/task.c:1152:7
    #3 run lib/isc/task.c:1344:2

    Mutex M1 acquired here while holding mutex M2 in thread T1:
    #0 pthread_mutex_lock <null>
    #1 get_raw_serial lib/dns/zone.c:2518:2
    #2 zone_gotwritehandle lib/dns/zone.c:2559:4
    #3 dispatch lib/isc/task.c:1152:7
    #4 run lib/isc/task.c:1344:2

    Mutex M2 previously acquired by the same thread here:
    #0 pthread_rwlock_rdlock <null>
    #1 isc_rwlock_lock lib/isc/rwlock.c:48:3
    #2 zone_gotwritehandle lib/dns/zone.c:2552:2
    #3 dispatch lib/isc/task.c:1152:7
    #4 run lib/isc/task.c:1344:2

    Thread T1 (running) created by main thread at:
    #0 pthread_create <null>
    #1 isc_thread_create lib/isc/pthreads/thread.c:73:8
    #2 isc_taskmgr_create lib/isc/task.c:1434:3
    #3 create_managers bin/named/main.c:915:11
    #4 setup bin/named/main.c:1223:11
    #5 main bin/named/main.c:1523:2

    SUMMARY: ThreadSanitizer: lock-order-inversion (potential deadlock) in pthread_rwlock_wrlock

(cherry picked from commit 1090876693470eedf69211d0fe71ba2c88160f45)

lib/dns/zone.c

index 096ff82f34bb82126b4d42dbd994b4951f87ef5e..fd634af65f572f97a2fb22b295807875b2475c86 100644 (file)
@@ -2468,6 +2468,7 @@ zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
        isc_result_t result = ISC_R_SUCCESS;
        dns_dbversion_t *version = NULL;
        dns_masterrawheader_t rawdata;
+       dns_db_t *db = NULL;
 
        REQUIRE(DNS_ZONE_VALID(zone));
        INSIST(task == zone->task);
@@ -2483,9 +2484,12 @@ zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
        INSIST(zone != zone->raw);
        ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
        if (zone->db != NULL) {
+               dns_db_attach(zone->db, &db);
+       }
+       ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
+       if (db != NULL) {
                const dns_master_style_t *output_style;
-
-               dns_db_currentversion(zone->db, &version);
+               dns_db_currentversion(db, &version);
                dns_master_initrawheader(&rawdata);
                if (inline_secure(zone))
                        get_raw_serial(zone->raw, &rawdata);
@@ -2495,15 +2499,18 @@ zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
                        output_style = zone->masterstyle;
                else
                        output_style = &dns_master_style_default;
-               result = dns_master_dumpinc3(zone->mctx, zone->db, version,
+               result = dns_master_dumpinc3(zone->mctx, db, version,
                                             output_style, zone->masterfile,
                                             zone->task, dump_done, zone,
                                             &zone->dctx, zone->masterformat,
                                             &rawdata);
-               dns_db_closeversion(zone->db, &version, false);
-       } else
+               dns_db_closeversion(db, &version, false);
+       } else {
                result = ISC_R_CANCELED;
-       ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
+       }
+       if (db != NULL) {
+               dns_db_detach(&db);
+       }
        UNLOCK_ZONE(zone);
        if (result != DNS_R_CONTINUE)
                goto fail;