2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-28 21:17:54 +00:00

4917 Commits

Author SHA1 Message Date
Mark Andrews
4f790b6c58 Clear OpenSSL errors on TSL error paths 2023-09-01 12:01:20 +10:00
Mark Andrews
247422c69f Clear OpenSSL errors on SHA failures 2023-09-01 12:01:20 +10:00
Mark Andrews
4ea926934a Clear OpenSSL errors on EVP failures 2023-09-01 12:01:19 +10:00
Mark Andrews
6df53cdb87 Clear OpenSSL errors on EVP_PKEY_new failures 2023-09-01 12:01:19 +10:00
Ondřej Surý
d9048b3db1
Remove ISC_MEM_ZERO and isc_mem_*x() API
Use the new isc_mem_c*() calloc-like API for allocations that are
zeroed.

In turn, this also fixes couple of incorrect usage of the ISC_MEM_ZERO
for structures that need to be zeroed explicitly.

There are few places where isc_mem_cput() is used on structures with a
flexible member (or similar).
2023-08-31 22:08:35 +02:00
Ondřej Surý
8ac679a980
Remove ISC_MEM_ALIGN() memory flag
The ISC_MEM_ALIGN() was not used anywhere (except mem.c itself), so just
remove the unused flag.
2023-08-31 22:08:35 +02:00
Ondřej Surý
55c29b8d83
Do extra manual isc_mem_cget() conversions
Some of the cases weren't caught by the coccinelle and there were some
places where cget+memmove() could get converted to simple creget().
2023-08-31 22:08:35 +02:00
Ondřej Surý
89fcb6f897
Apply the isc_mem_cget semantic patch 2023-08-31 22:08:35 +02:00
Ondřej Surý
6272482113
Checked array allocation arithmetic with isc_mem_get and friends
Add new isc_mem_cget(), isc_mem_creget(), and isc_mem_cput() macros to
complement the isc_mem_callocate() (which works like calloc()).

The overflow checks are implemented as macros in the <isc/mem.h>, so
that the compiler can see that the element size is constant: it should
always be `sizeof(something)`.
2023-08-31 22:08:35 +02:00
Aram Sargsyan
a33dc921dc Fix a condition in isc_dnsstream_assembler_incoming()
Before calling isc_buffer_putmem(), there is a condition to check
that 'buf_size' is greater than 0. At this point 'buf_size' is
guaranteed to be greater than zero, so either the condition is
redundant, or 'unprocessed_size' should be checked instead, which
seems more logical, because calling isc_buffer_putmem() with
'unprocessed_size' being zero is not useful, although harmless.
2023-08-24 11:59:57 +00:00
Aram Sargsyan
9a271371d3 Handle cases when buf_size is zero
The isc_dnsstream_assembler_incoming() inline function expects that
when 'buf_size' is zero, then 'buf' must be NULL. The expectation is
not correct, because those values come from the libuv read callback,
and its documentation notes[1] that 'nread' ('buf_size' here) might
be 0, which does not indicate an error or EOF, but is equivalent to
EAGAIN or EWOULDBLOCK under read(2).

Change the isc_dnsstream_assembler_incoming() inline function to
remove the invalid expectation.

[1] https://docs.libuv.org/en/v1.x/stream.html#c.uv_read_cb
2023-08-24 11:59:57 +00:00
Tony Finch
52fcc9fc0f
Remove some unnecessary token pasting macrology
There used to be an extra layer of indirection in the memory functions
for certain dynamic linking scenarios. This involved variant spellings
like isc__mem and isc___mem. The isc___mem variants were removed in
commit 7de846977b2a4fd3 so the token pasting is no longer needed and
only serves to obfuscate.
2023-08-23 14:49:15 +02:00
Ondřej Surý
2484a3702a
Add tracing probes to the isc_job unit
Add tracing probes to isc_job unit:

 * libisc:job_cb_before - before the job callback is called
 * libisc:job_cb_after - after the job callback is called
2023-08-21 18:39:53 +02:00
Ondřej Surý
dcd60215ac
Add tracing probes to the custom isc_rwlock implementation
Add tracing probes to ISC own isc_rwlock implementation to allow
fine-grained tracing.  The pthread rwlock already has probes inside
glibc, and it's difficult to add probes to headers included from the
other libraries.
2023-08-21 18:39:53 +02:00
Ondřej Surý
784d055809
Add support for User Statically Defined Tracing (USDT) probes
This adds support for User Statically Defined Tracing (USDT).  On
Linux, this uses the header from SystemTap and dtrace utility, but the
support is universal as long as dtrace is available.

Also add the required infrastructure to add probes to libisc, libdns and
libns libraries, where most of the probes will be.
2023-08-21 18:39:53 +02:00
Ondřej Surý
0c9cf8fabb
Limit the memory pool for the uvreqs
Set the number of maximum free items for the uvreq memory pool to 64.
2023-08-21 16:34:30 +02:00
Ondřej Surý
f36e118b9a
Limit the number of inactive handles kept for reuse
Instead of growing and never shrinking the list of the inactive
handles (to be reused mostly on the UDP connections), limit the number
of maximum number of inactive handles kept to 64.  Instead of caching
the inactive handles for all listening sockets, enable the caching on on
UDP listening sockets.  For TCP, the handles were cached for each
accepted socket thus reusing the handles only for long-standing TCP
connections, but not reusing the handles across different TCP streams.
2023-08-21 16:34:30 +02:00
Tony Finch
26e10e8fb5
Parse statschannel Content-Length: more carefully
A negative or excessively large Content-Length could cause a crash
by making `INSIST(httpd->consume != 0)` fail.
2023-08-21 14:14:18 +02:00
Tony Finch
c622b349e4
Apply the SET_IF_NOT_NULL() semantic patch
spatch --sp-file cocci/set_if_not_null.spatch --use-gitgrep --dir "." --include-headers --in-place
2023-08-15 12:21:41 +02:00
Tony Finch
0d6dcd217d
A SET_IF_NOT_NULL() macro for optional return values
The SET_IF_NOT_NULL() macro avoids a fair amount of tedious boilerplate,
checking pointer parameters to see if they're non-NULL and updating
them if they are.  The macro was already in the dns_zone unit, and this
commit moves it to the <isc/util.h> header.

I have included a Coccinelle semantic patch to use SET_IF_NOT_NULL()
where appropriate. The patch needs an #include in `openssl_shim.c`
in order to work.
2023-08-15 12:04:29 +02:00
Tony Finch
b22c87ca61
Fix a stack buffer overflow in the statistics channel
A long timestamp in an If-Modified-Since header could overflow a
fixed-size buffer.
2023-08-14 11:30:24 +02:00
Ondřej Surý
c1821ccf92
Call rcu_barrier() five times in the isc__mem_destroy()
Because rcu_barrier() needs to be called as many times as the number of
nested call_rcu() calls (call_rcu() calls made from call_rcu thread),
and currently there's no mechanism to detect whether there are more
call_rcu callbacks scheduled, we simply call the rcu_barrier() multiple
times.  The overhead is negligible and it prevents rare assertion
failures caused by the check for memory leaks in isc__mem_destroy().
2023-07-31 15:51:15 +02:00
Ondřej Surý
4ca64c1799
Pin dns_request to the associated loop
When dns_request was canceled via dns_requestmgr_shutdown() the cancel
event would be propagated on different loop (loop 0) than the loop where
request was created on.  In turn this would propagate down to isc_netmgr
where we require all the events to be called from the matching isc_loop.

Pin the dns_requests to the loops and ensure that all the events are
called on the associated loop.  This in turn allows us to remove the
hashed locks on the requests and change the single .requests list to be
a per-loop list for the request accounting.

Additionally, do some extra cleanup because some race condititions are
now not possible as all events on the dns_request are serialized.
2023-07-28 09:01:22 +02:00
Ondřej Surý
b6b0d81a36
Cleanup the __tsan_acquire/__tsan_release
With ThreadSanitizer support added to the Userspace RCU, we no longer
need to wrap the call_rcu and caa_container_of with
__tsan_{acquire,release} hints.  Remove the direct calls to
__tsan_{acquire,release} and the isc_urcu_{container,cleanup} macros.
2023-07-28 08:59:08 +02:00
Ondřej Surý
dc3e07572b
Workaround AddressSanitizer overzealous check
The cds_lfht_for_each_entry and cds_lfht_for_each_entry_duplicate macros
had a code that operated on the NULL pointer, at the end of the list it
was calling caa_container_of() on the NULL pointer in the init-clause
and iteration-expression, but the result wasn't actually used anywhere
because the cond-expression in the for loop has prevented executing
loop-statement.  This made AddressSanitizer notice the invalid operation
and rightfully complain.

This was reported to the upstream and fixed there.  Pull the upstream
fix into our <isc/urcu.h> header, so our CI checks pass.
2023-07-27 15:21:39 +02:00
Ondřej Surý
5321c474ea Refactor isc_stats_create() and its downstream users to return void
The isc_stats_create() can no longer return anything else than
ISC_R_SUCCESS.  Refactor isc_stats_create() and its variants in libdns,
libns and named to just return void.
2023-07-27 11:37:44 +02:00
Evan Hunt
e37d02905c
add isc_loop_now() to get consistent time
isc_loop_now() is a front-end to uv_now(), returning the start
time of the current event loop tick.
2023-07-19 15:32:21 +02:00
Evan Hunt
4db150437e
clean up unused dns_db methods
to reduce the amount of common code that will need to be shared
between the separated cache and zone database implementations,
clean up unused portions of dns_db.

the methods dns_db_dump(), dns_db_isdnssec(), dns_db_printnode(),
dns_db_resigned(), dns_db_expirenode() and dns_db_overmem() were
either never called or were only implemented as nonoperational stub
functions: they have now been removed.

dns_db_nodefullname() was only used in one place, which turned out
to be unnecessary, so it has also been removed.

dns_db_ispersistent() and dns_db_transfernode() are used, but only
the default implementation in db.c was ever actually called. since
they were never overridden by database methods, there's no need to
retain methods for them.

in rbtdb.c, beginload() and endload() methods are no longer defined for
the cache database, because that was never used (except in a few unit
tests which can easily be modified to use the zone implementation
instead).  issecure() is also no longer defined for the cache database,
as the cache is always insecure and the default implementation of
dns_db_issecure() returns false.

for similar reasons, hashsize() is no longer defined for zone databases.

implementation functions that are shared between zone and cache are now
prepended with 'dns__rbtdb_' so they can become nonstatic.

serve_stale_ttl is now a common member of dns_db.
2023-07-17 14:50:25 +02:00
Tony Finch
e2eaefbf7a
Check for overflow when resizing a heap
Ensure that the heap size calculations produce the correct answers,
and use `isc_mem_reget()` instead of calling `get` and `put`.

Closes #4122
2023-06-27 12:38:09 +02:00
Tony Finch
14f5b79c74
Check for overflow in jemalloc_shim
When compiled using a malloc that lacks an equivalent to sallocx(),
the jemalloc_shim adds a size prefix to each allocation. We must check
that this does not overflow.

Closes #4121
2023-06-27 12:38:09 +02:00
Tony Finch
92fcb7457c
Use isc_mem_callocate() in http_calloc()
Closes #4120
2023-06-27 12:38:09 +02:00
Tony Finch
81d73600c1
Add isc_mem_callocate() for safer array allocation
As well as clearing the fresh memory, `calloc()`-like functions must
ensure that the count and size do not overflow when multiplied.

Use `isc_mem_callocate()` in `isc__uv_calloc()`.
2023-06-27 12:38:09 +02:00
Tony Finch
7474cad4ad
Add <isc/overflow.h> for checked mul, add, and sub
The `ISC_OVERFLOW_XXX()` macros are usually wrappers around
`__builtin_xxx_overflow()`, with alternative implementations
for compilers that lack the builtins.

Replace the overflow checks in `isc/time.c` with the new macros.
2023-06-27 12:38:09 +02:00
Ondřej Surý
5bd9343c4e
Remove the explicit call_rcu thread creating and destruction
The free_all_cpu_call_rcu_data() call can consume hundreds of
milliseconds on shutdown.  Don't try to be smart and let the RCU library
handle this internally.
2023-06-27 07:59:00 +02:00
Tony Finch
e18ca83a3b Improve statschannel HTTP Connection: header protocol conformance
In HTTP/1.0 and HTTP/1.1, RFC 9112 section 9.6 says the last response
in a connection should include a `Connection: close` header, but the
statschannel server omitted it.

In an HTTP/1.0 response, the statschannel server can sometimes send a
`Connection: keep-alive` header when it is about to close the
connection. There are two ways:

If the first request on a connection is keep-alive and the second
request is not, then _both_ responses have `Connection: keep-alive`
but the connection is (correctly) closed after the second response.

If a single request contains

	Connection: close
	Connection: keep-alive

then RFC 9112 section 9.3 says the keep-alive header is ignored, but
the statschannel sends a spurious keep-alive in its response, though
it correctly closes the connection.

To fix these bugs, make it more clear that the `httpd->flags` are part
of the per-request-response state. The Connection: flags are now
described in terms of the effect they have instead of what causes them
to be set.
2023-06-15 17:03:09 +01:00
Ondřej Surý
a8e6c3b8f7
Make isc_result tables smaller
The isc_result_t enum was to sparse when each library code would skip to
next << 16 as a base.  Remove the huge holes in the isc_result_t enum to
make the isc_result tables more compact.

This change required a rewrite how we map dns_rcode_t to isc_result_t
and back, so we don't ever return neither isc_result_t value nor
dns_rcode_t out of defined range.
2023-06-15 15:32:04 +02:00
Midnight Veil
dd6acc1cac Translate POSIX errorcode EROFS to ISC_R_NOPERM
Report "permission denied" instead of "unexpected error"
when trying to update a zone file on a read-only file system.
2023-06-14 13:12:45 +01:00
Mark Andrews
e6e4ac05b8 Fix typo in synchronize_rcu macro (add h)
synchronize_rcu has not been used until now in BIND9 and there
was a typo in the define (a 'h' was missing).
2023-06-06 08:10:09 +10:00
Ondřej Surý
f760ee3f8c
Disable URCU inlining if inlined rcu_dereference() fails to compile
In some cases, the inlined version rcu_dereference() would not compile
when working on pointer to opaque struct (namely Ubuntu Jammy).  Detect
such condition in the autoconf and disable the inlining of the small
functions if it breaks the build.
2023-06-01 16:51:38 +02:00
Mark Andrews
ac2e0bc3ff Move isc_mem_put to after node is checked for equality
isc_mem_put NULL's the pointer to the memory being freed.  The
equality test 'parent->r == node' was accidentally being turned
into a test against NULL.
2023-05-29 01:40:57 +00:00
Evan Hunt
512e5e786b don't set SHUTTINGDOWN until after calling the request callbacks
if we set ISC_HTTPDMGR_SHUTTINGDOWN in the http manager before
calling the pending request callbacks, it can trigger an assertion.
2023-05-27 00:41:37 +00:00
Michal Nowak
1fe5c008d6
Ensure "wrap" variable is non-NULL
RUNTIME_CHECK on the "wrap" variable avoids possible NULL dereference:

    thread.c: In function 'thread_wrap':
    thread.c:60:15: error: dereference of possibly-NULL 'wrap' [CWE-690] [-Werror=analyzer-possible-null-dereference]
       60 |         *wrap = (struct thread_wrap){

The RUNTIME_CHECK was there before
7d1ceaf35dbc25dfbca32deffa7f6ff8f452e75f.
2023-05-19 11:02:59 +02:00
Michał Kępień
6029010dd2
Remove <isc/cmocka.h>
The last use of the cmocka_add_test_byname() helper macro was removed in
commit 63fe9312ff8f54bc79e399bdbd5aaa15cd3e5459.  Remove the
<isc/cmocka.h> header that defines it.
2023-05-18 15:12:23 +02:00
Tony Finch
c319ccd4c9 Fixes for liburcu-qsbr
Move registration and deregistration of the main thread from
`isc_loopmgr_run()` into `isc__initialize()` / `isc__shutdown()`:
liburcu-qsbr fails an assertion if we try to use it from an
unregistered thread, and we need to be able to use it when the
event loops are not running.

Use `rcu_assign_pointer()` and `rcu_dereference()` in qp-trie
transactions so that they properly mark threads as online. The
RCU-protected pointer is no longer declared atomic because
liburcu does not (yet) use standard C atomics.

Fix the definition of `isc_qsbr_rcu_dereference()` to return
the referenced value, and to call the right function inside
liburcu.

Change the thread sanitizer suppressions to match any variant of
`rcu_*_barrier()`
2023-05-15 20:49:42 +00:00
Tony Finch
afae41aa40
Check the return value from uv_async_send()
An omission pointed out by the following report from Coverity:

    /lib/isc/loop.c: 483 in isc_loopmgr_pause()
    >>>     CID 455002:  Error handling issues  (CHECKED_RETURN)
    >>>     Calling "uv_async_send" without checking return value (as is done elsewhere 5 out of 6 times).
    483     		uv_async_send(&loop->pause_trigger);
2023-05-15 18:52:04 +01:00
Evan Hunt
b4ac7faee9 allow streamdns read to resume after timeout
when reading on a streamdns socket failed due to timeout, but
the dispatch was still waiting for other responses, it would
resume reading by calling isc_nm_read() again. this caused
an assertion because the socket was already reading.

we now check that either the socket is reading, or that it was
already reading on the same handle.
2023-05-13 23:31:45 -07:00
Tony Finch
fc770a8bd0
Remove the now-unused ISC_STACK
We are using the liburcu concurrent data structures instead.
2023-05-12 20:49:43 +01:00
Tony Finch
f11cc83142
Use per-CPU RCU helper threads
Create and free per-CPU helper threads from the main thread and tell
thread sanitizer to suppress leaking threads. (We are not leaking
threads ourselves and we can safely ignore the Userspace-RCU thread
leaks.)
2023-05-12 20:48:31 +01:00
Tony Finch
c377e0a9e3
Help thread sanitizer to cope with liburcu
All the places the qp-trie code was using `call_rcu()` needed
`__tsan_release()` and `__tsan_acquire()` annotations, so
add a couple of wrappers to encapsulate this pattern.

With these wrappers, the tests run almost clean under thread
sanitizer. The remaining problems are due to `rcu_barrier()`
which can be suppressed using `.tsan-suppress`. It does not
suppress the whole of `liburcu`, because we would like thread
sanitizer to detect problems in `call_rcu()` callbacks, which
are called from `liburcu`.

The CI jobs have been updated to use `.tsan-suppress` by
default, except for a special-case job that needs the
additional suppressions in `.tsan-suppress-extra`.

We might be able to get rid of some of this after liburcu gains
support for thread sanitizer.

Note: the `rcu_barrier()` suppression is not entirely effective:
tsan sometimes reports races that originate inside `rcu_barrier()`
but tsan has discarded the stack so it does not have the
information required to suppress the report. These "races" can
be made much easier to reproduce by adding `atexit_sleep_ms=1000`
to `TSAN_OPTIONS`. The problem with tsan's short memory can be
addressed by increasing `history_size`: when it is large enough
(6 or 7) the `rcu_barrier()` stack usually survives long enough
for suppression to work.
2023-05-12 20:48:31 +01:00
Tony Finch
05ca11e122
Remove isc_qsbr (we are using liburcu instead)
This commit breaks the qp-trie code.
2023-05-12 20:48:31 +01:00