Commit Graph

14085 Commits

Author SHA1 Message Date
Aram Sargsyan
83395f4cfb Set the extended DNS error code for RPZ-modified queries
When enabled through a configuration option, set the configured EDE code
for the modified queries.
2022-08-31 08:56:03 +00:00
Aram Sargsyan
77f12ecba7 Add extended DNS error configuration option for RPZ zones
Implement the configuration option with its checking and parsing parts.

The option should be later used by BIND to set an extended error
code (EDE) for the queries modified in the result of RPZ processing.
2022-08-31 08:56:03 +00:00
Ondřej Surý
718e92c31a Clear the callbacks when isc_nm_stoplistening() is called
When we are closing the listening sockets, there's a time window in
which the TCP connection could be accepted although the respective
stoplistening function has already returned to control to the caller.
Clear the accept callback function early, so it doesn't get called when
we are not interested in the incoming connections anymore.
2022-08-26 09:09:25 +02:00
Ondřej Surý
4d07768a09 Remove the isc_app API
The isc_app API is no longer used and has been removed.
2022-08-26 09:09:25 +02:00
Ondřej Surý
b69e783164 Update netmgr, tasks, and applications to use isc_loopmgr
Previously:

* applications were using isc_app as the base unit for running the
  application and signal handling.

* networking was handled in the netmgr layer, which would start a
  number of threads, each with a uv_loop event loop.

* task/event handling was done in the isc_task unit, which used
  netmgr event loops to run the isc_event calls.

In this refactoring:

* the network manager now uses isc_loop instead of maintaining its
  own worker threads and event loops.

* the taskmgr that manages isc_task instances now also uses isc_loopmgr,
  and every isc_task runs on a specific isc_loop bound to the specific
  thread.

* applications have been updated as necessary to use the new API.

* new ISC_LOOP_TEST macros have been added to enable unit tests to
  run isc_loop event loops. unit tests have been updated to use this
  where needed.
2022-08-26 09:09:24 +02:00
Ondřej Surý
49b149f5fd Update isc_timer to use isc_loopmgr
* isc_timer was rewritten using the uv_timer, and isc_timermgr_t was
  completely removed; isc_timer objects are now directly created on the
  isc_loop event loops.

* the isc_timer API has been simplified. the "inactive" timer type has
  been removed; timers are now stopped by calling isc_timer_stop()
  instead of resetting to inactive.

* isc_manager now creates a loop manager rather than a timer manager.

* modules and applications using isc_timer have been updated to use the
  new API.
2022-08-25 17:17:07 +02:00
Ondřej Surý
84c90e223f New event loop handling API
This commit introduces new APIs for applications and signal handling,
intended to replace isc_app for applications built on top of libisc.

* isc_app will be replaced with isc_loopmgr, which handles the
  starting and stopping of applications. In isc_loopmgr, the main
  thread is not blocked, but is part of the working thread set.
  The loop manager will start a number of threads, each with a
  uv_loop event loop running. Setup and teardown functions can be
  assigned which will run when the loop starts and stops, and
  jobs can be scheduled to run in the meantime. When
  isc_loopmgr_shutdown() is run from any the loops, all loops
  will shut down and the application can terminate.

* signal handling will now be handled with a separate isc_signal unit.
  isc_loopmgr only handles SIGTERM and SIGINT for application
  termination, but the application may install additional signal
  handlers, such as SIGHUP as a signal to reload configuration.

* new job running primitives, isc_job and isc_async, have been added.
  Both units schedule callbacks (specifying a callback function and
  argument) on an event loop. The difference is that isc_job unit is
  unlocked and not thread-safe, so it can be used to efficiently
  run jobs in the same thread, while isc_async is thread-safe and
  uses locking, so it can be used to pass jobs from one thread to
  another.

* isc_tid will be used to track the thread ID in isc_loop worker
  threads.

* unit tests have been added for the new APIs.
2022-08-25 12:24:29 +02:00
Ondřej Surý
a26862e653 Simplify the isc_event API
The ev_tag field was never used, and has now been removed.
2022-08-25 12:24:25 +02:00
Matthijs Mekking
e633398010 nsec3.c: Add a missing dns_db_detachnode() call
There is one case in 'dns_nsec3_activex()' where it returns but forgets
to detach the db node. Add the missing 'dns_db_detachnode()' call.

This case only triggers if 'sig-signing-type' (privatetype) is set to 0
(which by default is not), or if the function is called with 'complete'
is set to 'true' (which at this moment do not exist).
2022-08-23 11:01:31 +02:00
Matthijs Mekking
501dc87d75 Wait with NSEC3 during a DNSSEC policy change
When doing a dnssec-policy reconfiguration from a zone with NSEC only
keys to a zone that uses NSEC3, figure out to wait with building the
NSEC3 chain.

Previously, BIND 9 would attempt to sign such a zone, but failed to
do so because the NSEC3 chain conflicted with existing DNSKEY records
in the zone that were not compatible with NSEC3.

There exists logic for detecting such a case in the functions
dnskey_sane() (in lib/dns/zone.c) and check_dnssec() (in
lib/ns/update.c). Both functions look very similar so refactor them
to use the same code and call the new function (called
dns_zone_check_dnskey_nsec3()).

Also update the dns_nsec_nseconly() function to take an additional
parameter 'diff' that, if provided, will be checked whether an
offending NSEC only DNSKEY will be deleted from the zone. If so,
this key will not be considered when checking the zone for NSEC only
DNSKEYs. This is needed to allow a transition from an NSEC zone with
NSEC only DNSKEYs to an NSEC3 zone.
2022-08-22 15:55:46 +02:00
Aram Sargsyan
8c4cdd9b21 Fix statistics channel multiple request processing with non-empty bodies
When the HTTP request has a body part after the HTTP headers, it is
not getting processed and is being prepended to the next request's data,
which results in an error when trying to parse it.

Improve the httpd.c:process_request() function with the following
additions:

1. Require that HTTP POST requests must have Content-Length header.
2. When Content-Length header is set, extract its value, and make sure
   that it is valid and that the whole request's body is received before
   processing the request.
3. Discard the request's body by consuming Content-Length worth of data
   in the buffer.
2022-08-19 08:10:54 +00:00
Aram Sargsyan
86b8e62106 Enhance the have_header() function to find the HTTP header's value
Add a new `const char **fvalue` parameter to the httpd.c:have_header()
function which, when set, will point to the found header's value.
2022-08-19 08:10:54 +00:00
Mark Andrews
ea13820023 Silence negative array index warning with toupper
Cast to (unsigned char).
2022-08-19 11:16:00 +10:00
Aram Sargsyan
2e01162258 Refactor tkey.c:buildquery() error handling
After an earlier code cleanup, `dns_rdatalist_tordataset()` always
succeeds, so the `RETERR` error handling macro below the function
call was removed. After that change the `dynbuf` variable can never
be `NULL` in the error handling code path under the `failure` label.

    *** CID 355779:  Null pointer dereferences  (REVERSE_INULL)
    /lib/dns/tkey.c: 997 in buildquery()
    991                 dns_message_puttempname(msg, &aname);
    992         }
    993         if (question != NULL) {
    994                 dns_rdataset_disassociate(question);
    995                 dns_message_puttemprdataset(msg, &question);
    996         }
    >>>     CID 355779:  Null pointer dereferences  (REVERSE_INULL)
    >>>     Null-checking "dynbuf" suggests that it may be null, but it has already been dereferenced on all paths leading to the check.
    997         if (dynbuf != NULL) {
    998                 isc_buffer_free(&dynbuf);
    999         }
    1000        return (result);
    1001     }
    1002

Refactor the `buildquery()` function to simplify its error handling.
2022-08-16 07:36:12 +00:00
Aram Sargsyan
d38931f397 Fix tkey.c:buildquery() function's error handling
Add the missing cleanup code.
2022-08-15 11:44:53 +00:00
Matthijs Mekking
fa1d24c03a dnssec-policy now requires inline-signing
Having implicit inline-signing set for dnssec-policy when there is no
update policy is confusing, so lets make this explicit.
2022-08-15 10:05:39 +02:00
Evan Hunt
e79be4bd8a Lock the address entry bucket when dumping ADB namehook
When dumping an ADB address entry associated with a name,
the name bucket lock was held, but the entry bucket lock was
not; this could cause data races when other threads were updating
address entry info. (These races are probably not operationally
harmful, but they triggered TSAN error reports.)
2022-08-12 14:47:50 -07:00
Evan Hunt
9d9bd3ace2 fix overflow error in mem_putstats()
an integer overflow could cause an assertion failure when
freeing memory.
2022-08-09 10:59:43 -07:00
Aram Sargsyan
c51b052827 dns_rdatalist_tordataset() and dns_rdatalist_fromrdataset() can not fail
Clean up dns_rdatalist_tordataset() and dns_rdatalist_fromrdataset()
functions by making them return void, because they cannot fail.

Clean up other functions that subsequently cannot fail.
2022-08-09 08:19:51 +00:00
Matthijs Mekking
c5b71e2472 Don't enable serve-stale on duplicate queries
When checking if we should enable serve-stale, add an early out case
when the result is an error signalling a duplicate query or a query
that would be dropped.
2022-08-09 09:13:53 +02:00
Artem Boldariev
32565d0d65 TLS: do not ignore readpaused flag in certain circumstances
In some circumstances generic TLS code could have resumed data reading
unexpectedly on the TCP layer code. Due to this, the behaviour of
isc_nm_pauseread() and isc_nm_resumeread() might have been
unexpected. This commit fixes that.

The bug does not seems to have real consequences in the existing code
due to the way the code is used. However, the bug could have lead to
unexpected behaviour and, at any rate, makes the TLS code behave
differently from the TCP code, with which it attempts to be as
compatible as possible.
2022-08-02 14:02:01 +03:00
Aram Sargsyan
1690af761b Differentiate between initial and cumulative fetch limit logging
Cumulative fetch limit logging happens on an event of a dropped
fetch if 60 seconds have been passed since the previous log message.
This change makes the log message different for the initial event
and for the later cumulative events to provide more useful information
to the system administrator.
2022-08-01 14:42:27 +00:00
Aram Sargsyan
8cfacc6fe1 Improve fetch limit logging
When initially hitting the `fetches-per-zone` value, a log message
is being generated for the event of dropping the first fetch, then
any further log events occur only when another fetch is being dropped
and 60 seconds have been passed since the last logged message.

That logic isn't ideal because when the counter of the outstanding
fetches reaches zero, the structure holding the counters' values will
get deleted, and the information about the dropped fetches accumulated
during the last minute will not be logged.

Improve the fcount_logspill() function to makie sure that the final
values are getting logged before the counter object gets destroyed.
2022-08-01 13:46:41 +00:00
Artem Boldariev
c52c691b18 TLS: fix double resumption in isc__nm_tls_resumeread()
This commit fixes an obvious error in isc__nm_tls_resumeread() so that
read cannot be resumed twice.
2022-07-26 14:25:59 +03:00
Artem Boldariev
5d450cd0ba TLS: clear 'errno' when handling SSL status
Sometimes tls_do_bio() might be called when there is no new data to
process (most notably, when resuming reads), in such a case internal
TLS session state will remain untouched and old value in 'errno' will
alter the result of SSL_get_error() call, possibly making it to return
SSL_ERROR_SYSCALL. This value will be treated as an error, and will
lead to closing the connection, which is not what expected.
2022-07-26 14:25:59 +03:00
Mark Andrews
edfbe5c30f Check that we can verify a signature at initialisation time
Fedora 33 doesn't support RSASHA1 in future mode.  There is no easy
check for this other than by attempting to perform a verification
using known good signatures.  We don't attempt to sign with RSASHA1
as that would not work in FIPS mode.  RSASHA1 is verify only.

The test vectors were generated using OpenSSL 3.0 and
util/gen-rsa-sha-vectors.c.  Rerunning will generate a new set of
test vectors as the private key is not preserved.

e.g.
	cc util/gen-rsa-sha-vectors.c -I /opt/local/include \
		-L /opt/local/lib -lcrypto
2022-07-25 10:32:13 -04:00
Matthijs Mekking
f8d866c6ef Fix rndc dumpdb -expired for stuck cache contents
The command 'rndc dumpdb -expired' will include expired RRsets in the
output, but only for the RBTDB_VIRTUAL time (of 5 minutes). This means
that if there is a cache cleaning problem and contents are not cleaned
up, the rndc command has little diagnostic value. Fix this by including
all RRsets in the dumpdb output if the '-expired' flag is set.
2022-07-25 16:05:21 +02:00
Evan Hunt
b1d0cac280 Forbid zones with both dnssec-policy and max-zone-ttl
Since max-zone-ttl in zone/view/options is a no-op if dnssec-policy
is in use, let's make that a fatal error.
2022-07-20 11:57:37 -07:00
Evan Hunt
19352dd187 mark max-zone-ttl deprecated in options and zone
The "max-zone-ttl" option should now be configured as part of
"dnssec-policy". The option with the same name in "zone" and
"options" is hereby flagged as deprecated, and its functionality
will be removed in a future release.
2022-07-20 11:55:03 -07:00
David Benjamin
e507ea2c85 Remove DH_clear_flags call
These calls have not been needed since OpenSSL 0.9.7h.

This dates to commit 704d6eeab1, "Work
around non-reentrancy in openssl by disabling precomputation in keys".
This was in the bundled OpenSSL 0.9.3a era and made two changes. First,
it registered a locking callback because, in those days, OpenSSL needed
a callback to support locks. Second, it set flags to disable various
bits of cached state on DH, DSA, and RSA objects.

Looking back in OpenSSL 0.9.3a, that cached state was not protected by a
lock:
https://github.com/openssl/openssl/blob/OpenSSL_0_9_3a/crypto/rsa/rsa_eay.c#L137-L142

However, this was fixed in OpenSSL 0.9.7h:
6ec8e63af6

The other flags (DSA and RSA) have since fallen away, DSA with the
removal of DSA altogether (3994b1f9c2) and
RSA with 3a8d4a316e, "openssl 0.9.6a and
higher don't have the RSA locking bug [...] other algorithms still don't
do locking when performing precomputation [...]".

That seems to be referring to this OpenSSL change, which indeed fixed it
for RSA but not others:
bb617a9646

The 0.9.7h change above fixed it across the board, but there was never a
similar update to the workaround for DSA and DH. With such OpenSSL
versions long since out of support, the last remains of this workaround
can finally be removed.
2022-07-18 13:38:47 +02:00
David Benjamin
723f5a0769 Simplify BN_GENCB handling
When callback was NULL, bind9 would use BN_GENCB_set_old to set a NULL
callback because OpenSSL happened to allow a NULL "old" callback, but
not a NULL "new" callback. Instead, the way to turn off the callback is
to pass a NULL BN_GENCB itself.

Switch to doing that.
2022-07-18 13:38:44 +02:00
Ondřej Surý
b35861f1eb Increase the BUFSIZ-long buffers
The BUFSIZ value varies between platforms, it could be 8K on Linux and
512 bytes on mingw.  Make sure the buffers are always big enough for the
output data to prevent truncation of the output by appropriately
enlarging or sizing the buffers.
2022-07-15 10:33:46 +00:00
Evan Hunt
e1c81f9b1b remove unnecessary assertion in dns_dispatch_connect()
When a thread calls dns_dispatch_connect() on an unconnected TCP socket
it sets `tcpstate` from `DNS_DISPATCHSTATE_NONE` to `_CONNECTING`.
Previously, it then INSISTed that there were no pending connections
before calling isc_nm_tcpdnsconnect().

If a second thread called dns_dispatch_connect() during that window
of time, it could add a pending connection to the list, and trigger
an assertion failure.

This commit removes the INSIST since the condition is actually
harmless.
2022-07-14 16:31:01 -07:00
Ondřej Surý
3e10d3b45f Cleanup the STATID_CONNECT and STATID_CONNECTFAIL stat counters
The STATID_CONNECT and STATID_CONNECTFAIL statistics were used
incorrectly. The STATID_CONNECT was incremented twice (once in
the *_connect_direct() and once in the callback) and STATID_CONNECTFAIL
would not be incremented at all if the failure happened in the callback.

Closes: #3452
2022-07-14 14:34:53 +02:00
Ondřej Surý
a280855f7b Handle the transient TCP connect() failures on FreeBSD
On FreeBSD (and perhaps other *BSD) systems, the TCP connect() call (via
uv_tcp_connect()) can fail with transient UV_EADDRINUSE error.  The UDP
code already handles this by trying three times (is a charm) before
giving up.  Add a code for the TCP, TCPDNS and TLSDNS layers to also try
three times before giving up by calling uv_tcp_connect() from the
callback two more time on UV_EADDRINUSE error.

Additionally, stop the timer only if we succeed or on hard error via
isc__nm_failed_connect_cb().
2022-07-14 14:20:10 +02:00
Mark Andrews
b38a5d895f disassociate rdatasets when cleaning up
free_namelist could be passed names with associated rdatasets
when handling errors.  These need to be disassociated before
calling dns_message_puttemprdataset.
2022-07-13 23:43:39 +00:00
Michał Kępień
b67ff4728f Improve reporting for barrier errors
uv_barrier_init() errors are currently ignored.  Use UV_RUNTIME_CHECK()
to catch them and to improve error reporting for any uv_barrier_init()
run-time failures (by augmenting error messages with file/line
information and the error string corresponding to the value returned).
2022-07-13 13:19:32 +02:00
Michał Kępień
7009f9d270 Improve reporting for read-write lock errors
Replace direct uses of implementation-specific rwlock functions in
lib/isc/include/isc/rwlock.h with preprocessor macros that use
ERRNO_CHECK(), in order to augment rwlock-related error messages with
file/line/caller information and the error string corresponding to
errno.  Adjust the implementation-specific functions for pthreads-based
rwlocks so that they return any errors encountered to the caller instead
of aborting execution immediately using RUNTIME_CHECK().

To keep code modifications simple, make the non-pthreads-based
implementation-specific rwlock functions always return 0; these
functions continue to handle errors using less verbose run-time
assertions as they do not set errno anyway.
2022-07-13 13:19:32 +02:00
Michał Kępień
badeeff0ac Improve reporting for condition variable errors
Replace all uses of RUNTIME_CHECK() in lib/isc/include/isc/condition.h
with ERRNO_CHECK(), in order to improve error reporting for any
condition-variable-related run-time failures (by augmenting error
messages with file/line/caller information and the error string
corresponding to errno).
2022-07-13 13:19:32 +02:00
Michał Kępień
f352a834a7 Improve reporting for mutex errors
Replace all uses of RUNTIME_CHECK() in lib/isc/include/isc/mutex.h with
ERRNO_CHECK(), in order to improve error reporting for any mutex-related
run-time failures (by augmenting error messages with file/line/caller
information and the error string corresponding to errno).
2022-07-13 13:19:32 +02:00
Michał Kępień
77aead5ab6 Enable tracking of pthreads barriers
Some POSIX threads implementations (e.g. FreeBSD's libthr) allocate
memory on the heap when pthread_barrier_init() is called.  Every call to
that function must be accompanied by a corresponding call to
pthread_barrier_destroy() or else the memory allocated for the barrier
will leak.

jemalloc can be used for detecting memory allocations which are not
released by a process when it exits.  Unfortunately, since jemalloc is
also the system allocator on FreeBSD and a special (profiling-enabled)
build of jemalloc is required for memory leak detection, this method
cannot be used for detecting leaked memory allocated by libthr on a
stock FreeBSD installation.

However, libthr's behavior can be emulated on any platform by
implementing alternative versions of libisc functions for creating and
destroying barriers that allocate memory using malloc() and release it
using free().  This enables using jemalloc for detecting missing
pthread_barrier_destroy() calls on any platform on which it works
reliably.

When the newly introduced ISC_TRACK_PTHREADS_OBJECTS preprocessor macro
is set, allocate isc_barrier_t structures on the heap in
isc_barrier_init() and free them in isc_barrier_destroy().  Reuse
existing barrier macros (after renaming them appropriately) for other
operations.
2022-07-13 13:19:32 +02:00
Ondřej Surý
e4606da2c6 Enable tracking of pthreads rwlocks
Some POSIX threads implementations (e.g. FreeBSD's libthr) allocate
memory on the heap when pthread_rwlock_init() is called.  Every call to
that function must be accompanied by a corresponding call to
pthread_rwlock_destroy() or else the memory allocated for the rwlock
will leak.

jemalloc can be used for detecting memory allocations which are not
released by a process when it exits.  Unfortunately, since jemalloc is
also the system allocator on FreeBSD and a special (profiling-enabled)
build of jemalloc is required for memory leak detection, this method
cannot be used for detecting leaked memory allocated by libthr on a
stock FreeBSD installation.

However, libthr's behavior can be emulated on any platform by
implementing alternative versions of libisc functions for creating and
destroying rwlocks that allocate memory using malloc() and release it
using free().  This enables using jemalloc for detecting missing
pthread_rwlock_destroy() calls on any platform on which it works
reliably.

When the newly introduced ISC_TRACK_PTHREADS_OBJECTS preprocessor macro
is set (and --enable-pthread-rwlock is used), allocate isc_rwlock_t
structures on the heap in isc_rwlock_init() and free them in
isc_rwlock_destroy().  Reuse existing functions defined in
lib/isc/rwlock.c for other operations, but rename them first, so that
they contain triple underscores (to indicate that these functions are
implementation-specific, unlike their mutex and condition variable
counterparts, which always use the pthreads implementation).  Define the
isc__rwlock_init() macro so that it is a logical counterpart of
isc__mutex_init() and isc__condition_init(); adjust isc___rwlock_init()
accordingly.  Remove a redundant function prototype for
isc__rwlock_lock() and rename that (static) function to rwlock_lock() in
order to avoid having to use quadruple underscores.
2022-07-13 13:19:32 +02:00
Ondřej Surý
8dfdb95a20 Enable tracking of pthreads condition variables
Some POSIX threads implementations (e.g. FreeBSD's libthr) allocate
memory on the heap when pthread_cond_init() is called.  Every call to
that function must be accompanied by a corresponding call to
pthread_cond_destroy() or else the memory allocated for the condition
variable will leak.

jemalloc can be used for detecting memory allocations which are not
released by a process when it exits.  Unfortunately, since jemalloc is
also the system allocator on FreeBSD and a special (profiling-enabled)
build of jemalloc is required for memory leak detection, this method
cannot be used for detecting leaked memory allocated by libthr on a
stock FreeBSD installation.

However, libthr's behavior can be emulated on any platform by
implementing alternative versions of libisc functions for creating and
destroying condition variables that allocate memory using malloc() and
release it using free().  This enables using jemalloc for detecting
missing pthread_cond_destroy() calls on any platform on which it works
reliably.

When the newly introduced ISC_TRACK_PTHREADS_OBJECTS preprocessor macro
is set, allocate isc_condition_t structures on the heap in
isc_condition_init() and free them in isc_condition_destroy().  Reuse
existing condition variable macros (after renaming them appropriately)
for other operations.
2022-07-13 13:19:32 +02:00
Ondřej Surý
ebcfb16576 Enable tracking of pthreads mutexes
Some POSIX threads implementations (e.g. FreeBSD's libthr) allocate
memory on the heap when pthread_mutex_init() is called.  Every call to
that function must be accompanied by a corresponding call to
pthread_mutex_destroy() or else the memory allocated for the mutex will
leak.

jemalloc can be used for detecting memory allocations which are not
released by a process when it exits.  Unfortunately, since jemalloc is
also the system allocator on FreeBSD and a special (profiling-enabled)
build of jemalloc is required for memory leak detection, this method
cannot be used for detecting leaked memory allocated by libthr on a
stock FreeBSD installation.

However, libthr's behavior can be emulated on any platform by
implementing alternative versions of libisc functions for creating and
destroying mutexes that allocate memory using malloc() and release it
using free().  This enables using jemalloc for detecting missing
pthread_mutex_destroy() calls on any platform on which it works
reliably.

Introduce a new ISC_TRACK_PTHREADS_OBJECTS preprocessor macro, which
causes isc_mutex_t structures to be allocated on the heap by
isc_mutex_init() and freed by isc_mutex_destroy().  Reuse existing mutex
macros (after renaming them appropriately) for other operations.
2022-07-13 13:19:32 +02:00
Ondřej Surý
deae974366 Directly cause assertion failure on pthreads primitives failure
Instead of returning error values from isc_rwlock_*(), isc_mutex_*(),
and isc_condition_*() macros/functions and subsequently carrying out
runtime assertion checks on the return values in the calling code,
trigger assertion failures directly in those macros/functions whenever
any pthread function returns an error, as there is no point in
continuing execution in such a case anyway.
2022-07-13 13:19:32 +02:00
Ondřej Surý
8e5e0fa522 Use library constructor to create default mutex attr once
Instead of using isc_once_do() on every isc_mutex_init() call, use the
global library constructor to initialize the default mutex attr
object (optionally with PTHREAD_MUTEX_ADAPTIVE_NP if supported) just
once when the library is loaded.
2022-07-13 13:19:32 +02:00
Michał Kępień
5759ace07f Handle pthread_*_init() failures consistently
isc_rwlock_init() currently detects pthread_rwlock_init() failures using
a REQUIRE() assertion.  Use the ERRNO_CHECK() macro for that purpose
instead, so that read-write lock initialization failures are handled
identically as condition variable (pthread_cond_init()) and mutex
(pthread_mutex_init()) initialization failures.
2022-07-13 13:19:32 +02:00
Michał Kępień
365b47caee Add an ERRNO_CHECK() preprocessor macro
In a number of situations in pthreads-related code, a common sequence of
steps is taken: if the value returned by a library function is not 0,
pass errno to strerror_r(), log the string returned by the latter, and
immediately abort execution.  Add an ERRNO_CHECK() preprocessor macro
which takes those exact steps and use it wherever (conveniently)
possible.

Notes:

 1. The "log the return value of strerror_r() and abort" pattern is used
    in a number of other places that this commit does not touch; only
    "!= 0" checks followed by isc_error_fatal() calls with
    non-customized error messages are replaced here.

 2. This change temporarily breaks file name & line number reporting for
    isc__mutex_init() errors, to prevent breaking the build.  This issue
    will be rectified in a subsequent change.
2022-07-13 13:19:32 +02:00
Michał Kępień
1a79aeab44 Stop resolving invalid names in resume_dslookup()
Commit 7b2ea97e46 introduced a logic bug
in resume_dslookup(): that function now only conditionally checks
whether DS chasing can still make progress.  Specifically, that check is
only performed when the previous resume_dslookup() call invokes
dns_resolver_createfetch() with the 'nameservers' argument set to
something else than NULL, which may not always be the case.  Failing to
perform that check may trigger assertion failures as a result of
dns_resolver_createfetch() attempting to resolve an invalid name.

Example scenario that leads to such outcome:

 1. A validating resolver is configured to forward all queries to
    another resolver.  The latter returns broken DS responses that
    trigger DS chasing.

 2. rctx_chaseds() calls dns_resolver_createfetch() with the
    'nameservers' argument set to NULL.

 3. The fetch fails, so resume_dslookup() is called.  Due to
    fevent->result being set to e.g. DNS_R_SERVFAIL, the default branch
    is taken in the switch statement.

 4. Since 'nameservers' was set to NULL for the fetch which caused the
    resume_dslookup() callback to be invoked
    (fctx->nsfetch->private->nameservers), resume_dslookup() chops off
    one label off fctx->nsname and calls dns_resolver_createfetch()
    again, for a name containing one label less than before.

 5. Steps 3-4 are repeated (i.e. all attempts to find the name servers
    authoritative for the DS RRset being chased fail) until fctx->nsname
    becomes stripped down the the root name.

 6. Since resume_dslookup() does not check whether DS chasing can still
    make progress, it strips off a label off the root name and continues
    its attempts at finding the name servers authoritative for the DS
    RRset being chased, passing an invalid name to
    dns_resolver_createfetch().

Fix by ensuring resume_dslookup() always checks whether DS chasing can
still make progress when a name server fetch fails.  Update code
comments to ensure the purpose of the relevant dns_name_equal() check is
clear.
2022-07-13 10:31:16 +02:00
Mark Andrews
5b51610174 Update libdns_la_LIBADD rather than libdns_la_LDFLAGS
the wrong macro was being update with MAXMINDDB_LIBS making
it difficult to adjust link order.
2022-07-13 00:14:13 +00:00