]> git.ipfire.org Git - thirdparty/bind9.git/commit
Fix deadlock between rndc addzone/delzone/modzone
authorDiego Fronza <diego@isc.org>
Fri, 16 Apr 2021 15:21:31 +0000 (12:21 -0300)
committerDiego dos Santos Fronza <diego@isc.org>
Thu, 22 Apr 2021 15:45:55 +0000 (15:45 +0000)
commit9298dcebbdcf9f4915f1c8bbe85d8bd4bad1af40
treeca5f48a660ab94ff4f7510a9bac34aa3f00b7989
parentfa6b277b8dc388a294eab7a44153fc81911d1724
Fix deadlock between rndc addzone/delzone/modzone

It follows a description of the steps that were leading to the deadlock:

1. `do_addzone` calls `isc_task_beginexclusive`.

2. `isc_task_beginexclusive` waits for (N_WORKERS - 1) halted tasks,
   this blocks waiting for those (no. workers -1) workers to halt.
...
isc_task_beginexclusive(isc_task_t *task0) {
    ...
while (manager->halted + 1 < manager->workers) {
wake_all_queues(manager);
WAIT(&manager->halt_cond, &manager->halt_lock);
}
```

3. It is possible that in `task.c / dispatch()` a worker is running a
   task event, if that event blocks it will not allow this worker to
   halt.

4. `do_addzone` acquires `LOCK(&view->new_zone_lock);`,

5. `rmzone` event is called from some worker's `dispatch()`, `rmzone`
   blocks waiting for the same lock.

6. `do_addzone` calls `isc_task_beginexclusive`.

7. Deadlock triggered, since:
- `rmzone` is wating for the lock.
- `isc_task_beginexclusive` is waiting for (no. workers - 1) to
   be halted
- since `rmzone` event is blocked it won't allow the worker to halt.

To fix this, we updated do_addzone code to call isc_task_beginexclusive
before the lock is acquired, we postpone locking to the nearest required
place, same for isc_task_beginexclusive.

The same could happen with rndc modzone, so that was addressed as well.
bin/named/server.c