Commit graph

80 commits

Author SHA1 Message Date
Tony Finch
a8b29f0365 Improve qp-trie refcount debugging
Add some qp-trie tracing macros which can be enabled by a
developer. These print a message when a leaf is attached or
detached, indicating which part of the qp-trie implementation
did so. The refcount methods must now return the refcount value
so it can be printed by the trace macros.
2023-02-27 13:47:57 +00:00
Tony Finch
4b5ec07bb7 Refactor qp-trie to use QSBR
The first working multi-threaded qp-trie was stuck with an unpleasant
trade-off:

  * Use `isc_rwlock`, which has acceptable write performance, but
    terrible read scalability because the qp-trie made all accesses
    through a single lock.

  * Use `liburcu`, which has great read scalability, but terrible
    write performance, because I was relying on `rcu_synchronize()`
    which is rather slow. And `liburcu` is LGPL.

To get the best of both worlds, we need our own scalable read side,
which we now have with `isc_qsbr`. And we need to modify the write
side so that it is not blocked by readers.

Better write performance requires an async cleanup function like
`call_rcu()`, instead of the blocking `rcu_synchronize()`. (There
is no blocking cleanup in `isc_qsbr`, because I have concluded
that it would be an attractive nuisance.)

Until now, all my multithreading qp-trie designs have been based
around two versions, read-only and mutable. This is too few to
work with asynchronous cleanup. The bare minimum (as in epoch
based reclamation) is three, but it makes more sense to support an
arbitrary number. Doing multi-version support "properly" makes
fewer assumptions about how safe memory reclamation works, and it
makes snapshots and rollbacks simpler.

To avoid making the memory management even more complicated, I
have introduced a new kind of "packed reader node" to anchor the
root of a version of the trie. This is simpler because it re-uses
the existing chunk lifetime logic - see the discussion under
"packed reader nodes" in `qp_p.h`.

I have also made the chunk lifetime logic simpler. The idea of a
"generation" is gone; instead, chunks are either mutable or
immutable. And the QSBR phase number is used to indicate when a
chunk can be reclaimed.

Instead of the `shared_base` flag (which was basically a one-bit
reference count, with a two version limit) the base array now has a
refcount, which replaces the confusing ad-hoc lifetime logic with
something more familiar and systematic.
2023-02-27 13:47:55 +00:00
Tony Finch
b06f6ef75a Fuzz testing the qp-trie
Ensure dns_qpkey_fromname() and dns_qpkey_toname() are inverses.

Excercise a single-threaded dns_qp_t with a fixed set of random keys
and a small chunk size. Use the table of names to ensure that the trie
is behaving as expected. This is (in effect) randomized testing like
the `qpmulti` unit test, but making use of coverage-guided fuzzing
and (in principle) test case minimization.
2023-02-27 13:47:25 +00:00
Tony Finch
6927a30926 Remove do-nothing header <isc/print.h>
This one really truly did nothing. No lines added!
2023-02-15 16:44:47 +00:00
Tony Finch
50ab648f8a Remove unused support for fromwire(DNS_NAME_DOWNCASE)
Most of this change is fixing dns_rdata_fromwire() so
it does not propagate the unused options variable.
2023-02-06 13:26:36 +00:00
Mark Andrews
897e0cd6f4 Call dst_lib_destroy if we have called dst_lib_init
This returns BIGNUMs to OpenSSL allowing libcrypto to fully clean up.
2023-02-01 00:34:33 +11:00
Ondřej Surý
0c62c0bdb7
Mark setting operating system limits from named.conf as ancient
After deprecating the operating system limits settings (coresize,
datasize, files and stacksize), mark them as ancient and remove the code
that sets the values from config.
2022-12-07 19:40:00 +01:00
Tony Finch
04f3000dfc Fuzzing and benchmarking for dns_name_fromwire()
Since this is very sensitive code which has often had security
problems in many DNS implementations, it needs a decent amount of
validation. This fuzzer ensures that the new code has the same output
as the old code, and that it doesn't take longer than a second.

The benchmark uses the fuzzer's copy of the old dns_name_fromwire()
code to compare a number of scenarios: many compression pointers, many
labels, long labels, random data, with/without downcasing.
2022-11-17 08:45:17 +00:00
Evan Hunt
428eac45ba fix build error in fuzz tests
a missing include file caused dns_message_checksig.c to fail
to build on some platforms. this has been fixed.
2022-10-31 04:28:01 -07:00
Ondřej Surý
6ba0a22627
Change the return type of isc_lex_create() to void
The isc_lex_create() cannot fail, so cleanup the return type from
isc_result_t to void.
2022-10-26 12:55:06 +02:00
Tony Finch
45b2d8938b
Simplify and speed up DNS name compression
All we need for compression is a very small hash set of compression
offsets, because most of the information we need (the previously added
names) can be found in the message using the compression offsets.

This change combines dns_compress_find() and dns_compress_add() into
one function dns_compress_name() that both finds any existing suffix,
and adds any new prefix to the table. The old split led to performance
problems caused by duplicate names in the compression context.

Compression contexts are now either small or large, which the caller
chooses depending on the expected size of the message. There is no
dynamic resizing.

There is a behaviour change: compression now acts on all the labels in
each name, instead of just the last few.

A small benchmark suggests this is about 2x faster.
2022-10-17 08:45:44 +02:00
Mark Andrews
033057ba9d Create a key directory in /tmp
Access to the source tree is not available with oss_fuzz.  Have
fuzz/dns_message_checksig build and populate a key directory for
the fuzzer to use.  This contains a key pair and a zone file which
has the public key from the key pair.  Clean it up on shutdown.
2022-09-30 02:19:52 +00:00
Ondřej Surý
16377100ae
Fix stack-use-after-scope in dns_message_checksig test
Previously stack with buffer for test dns message went out of scope
before the message was processed. For fuzz testing its better to avoid
allocation, so let's avoid allocations completely and use simplest
possible static buffer.

Fixes: #3565
2022-09-27 13:06:01 +02:00
Petr Špaček
4108d79c9a
Fix dns_message_checksig in out-of-tree setup
Hardcoded path was missing FUZZDIR prefix.

Related: !5923
2022-09-27 11:21:42 +02:00
Petr Špaček
d102c59b96
Detect errors in fuzzer initialization
Incomplete initialization typically causes mysterious failures later on,
so let's err out early.
2022-09-27 11:21:38 +02:00
Petr Špaček
983822abcf
Add seed to reproduce issue memory leak in dns_message_checktsig
Related: #3547
2022-09-26 16:29:36 +02:00
Mark Andrews
c127a2aefc
Add a SIG(0) request seed 2022-09-26 16:28:23 +02:00
Mark Andrews
3c28608c9f
Add TSIG reply seed 2022-09-26 16:28:23 +02:00
Mark Andrews
f3d47bc8e0
Add TSIG request seed 2022-09-26 16:28:23 +02:00
Ondřej Surý
4da0180ba2
Add dns_message_checksig() fuzzer
dns_message_checksig is called in a number of scenarios

	* on requests and responses
	* on multiple opcodes
	* with and without signatures
	* with TSIG signatures
	* with SIG(0) signatures
	* with and without configured TSIG keys
	* with and without KEY records being present
	* signing performed now, in the future and in the past

we use the first two octets of the seed to configure the calling
environment with the remainder of the seed being the rdata of the
TSIG/SIG(0) record.
2022-09-26 16:28:23 +02:00
Tony Finch
1d807d84f1 Shrink decompression contexts
It's wasteful to use 20 bytes and a pointer indirection to represent
two bits of information, so turn the struct into an enum. And change
the names of the enumeration constants to make the intent more clear.

This change introduces some inline functions into another header,
which confuses `gcovr` when it is trying to collect code coverage
statistics. So, in the CI job, copy more header files into a directory
where `gcovr` looks for them.
2022-06-01 13:00:40 +01:00
Tony Finch
e37b782c1a DNS name compression does not depend on the EDNS version
There was a proposal in the late 1990s that it might, but it turned
out to be unworkable. See RFC 6891, Extension Mechanisms for
DNS (EDNS(0)), section 5, Extended Label Types.

The remnants of the code that supported this in BIND are redundant.
2022-06-01 13:00:40 +01:00
Mark Andrews
9039aad0f8 Add test case for issue-45178 2022-04-01 07:56:52 +00:00
Tony Finch
599c1d2a6b Avoid using C99 variable length arrays
From an attacker's point of view, a VLA declaration is essentially a
primitive for performing arbitrary arithmetic on the stack pointer. If
the attacker can control the size of a VLA they have a very powerful
tool for causing memory corruption.

To mitigate this kind of attack, and the more general class of stack
clash vulnerabilities, C compilers insert extra code when allocating a
VLA to probe the growing stack one page at a time. If these probes hit
the stack guard page, the program will crash.

From the point of view of a C programmer, there are a few things to
consider about VLAs:

  * If it is important to handle allocation failures in a controlled
    manner, don't use VLAs. You can use VLAs if it is OK for
    unreasonable inputs to cause an uncontrolled crash.

  * If the VLA is known to be smaller than some known fixed size,
    use a fixed size array and a run-time check to ensure it is large
    enough. This will be more efficient than the compiler's stack
    probes that need to cope with arbitrary-size VLAs.

  * If the VLA might be large, allocate it on the heap. The heap
    allocator can allocate multiple pages in one shot, whereas the
    stack clash probes work one page at a time.

Most of the existing uses of VLAs in BIND are in test code where they
are benign, but there was one instance in `named`, in the GSS-TSIG
verification code, which has now been removed.

This commit adjusts the style guide and the C compiler flags to allow
VLAs in test code but not elsewhere.
2022-03-18 15:11:48 +00:00
Mark Andrews
d36938321e Add seed that demonstrated INSIST triggered in isc_lex_gettoken
this is similar to the input found by ClusterFuzz Issue 45027 with
the 0xff characters replaced for readability.
2022-03-01 16:05:39 -08:00
Petr Špaček
dc9ba2d3ef
Add dns_rdata_fromtext() fuzzer
... along with dns_rdataclass_fromtext and dns_rdatatype_fromtext

Most of the test binary is modified named-rrchecker. Main differences:
- reads single RR and exists
- does not refuse meta classes and rr types
We actually do have some fromtext code for meta-things so erroring out
in named-rrchecker would prevent us from testing this code.

Corpus has examples of all currently supported RR types. I did not do
any minimization.

In future use command

    diff -U0 \
	<(sed -n -e 's/^.*fromtext_\(.*\)(.*$/\1/p' lib/dns/code.h | \
		sort) \
	<(ls fuzz/dns_rdata_fromtext.in/)

to check for missing RR types.
2022-02-24 11:12:06 +01:00
Petr Špaček
759ad04eb8
Fix configure options in FUZZING.md 2022-02-24 11:12:02 +01:00
Petr Špaček
5076355822
Add dns_master_loadbuffer() fuzzer
Corpus focuses on "extra" things in master files like $GENERATE etc.
Text encoding for RRs is thoroughly tested in dns_rdata_fromtext
fuzzer.
2022-02-24 10:02:56 +01:00
Ondřej Surý
58bd26b6cf Update the copyright information in all files in the repository
This commit converts the license handling to adhere to the REUSE
specification.  It specifically:

1. Adds used licnses to LICENSES/ directory

2. Add "isc" template for adding the copyright boilerplate

3. Changes all source files to include copyright and SPDX license
   header, this includes all the C sources, documentation, zone files,
   configuration files.  There are notes in the doc/dev/copyrights file
   on how to add correct headers to the new files.

4. Handle the rest that can't be modified via .reuse/dep5 file.  The
   binary (or otherwise unmodifiable) files could have license places
   next to them in <foo>.license file, but this would lead to cluttered
   repository and most of the files handled in the .reuse/dep5 file are
   system test files.
2022-01-11 09:05:02 +01:00
Ondřej Surý
f3635bcc14 Use #pragma once as header guards
Unify the header guard style and replace the inconsistent include guards
with #pragma once.

The #pragma once is widely and very well supported in all compilers that
BIND 9 supports, and #pragma once was already in use in several new or
refactored headers.

Using simpler method will also allow us to automate header guard checks
as this is simpler to programatically check.

For reference, here are the reasons for the change taken from
Wikipedia[1]:

> In the C and C++ programming languages, #pragma once is a non-standard
> but widely supported preprocessor directive designed to cause the
> current source file to be included only once in a single compilation.
>
> Thus, #pragma once serves the same purpose as include guards, but with
> several advantages, including: less code, avoidance of name clashes,
> and sometimes improvement in compilation speed. On the other hand,
> #pragma once is not necessarily available in all compilers and its
> implementation is tricky and might not always be reliable.

1. https://en.wikipedia.org/wiki/Pragma_once
2021-10-13 00:49:15 -07:00
Matthijs Mekking
71b92d4d19 Replace "master/slave" terms in code comments
Replace those terms with the preferred "primary/secondary" keywords.
2021-10-12 13:09:00 -07:00
Matthijs Mekking
f3d3a4ff6e Replace "master/slave" terminology in tests
Replace most "master/slave" terminology in tests with the preferred
"primary/secondary", with the following exceptions:

- When testing the old syntax
- When master is used in master file and master file format terms
- When master is used in hostmaster or postmaster terms
- When master used in legacy domain names (for example in dig.batch)
- When there is no replacement (for example default-masters)
2021-10-12 13:04:00 -07:00
Ondřej Surý
2e3a2eecfe Make isc_result a static enum
Remove the dynamic registration of result codes.  Convert isc_result_t
from unsigned + #defines into 32-bit enum type in grand unified
<isc/result.h> header.  Keep the existing values of the result codes
even at the expense of the description and identifier tables being
unnecessary large.

Additionally, add couple of:

    switch (result) {
    [...]
    default:
        break;
    }

statements where compiler now complains about missing enum values in the
switch statement.
2021-10-06 11:22:20 +02:00
Mark Andrews
baaa5492ee add svcb fuzzing seed 2021-08-18 13:49:48 +10:00
Ondřej Surý
bf4a0e26dc Move NAME_MAX and PATH_MAX from isc/platform.h to isc/dir.h
The last remaining defines needed for platforms without NAME_MAX and
PATH_MAX (I'm looking at you, GNU Hurd) were moved to isc/dir.h where
it's prevalently used.
2021-07-06 05:33:48 +00:00
Ondřej Surý
e59a359929 Move the include Makefile.tests to the bottom of Makefile.am(s)
The Makefile.tests was modifying global AM_CFLAGS and LDADD and could
accidentally pull /usr/include to be listed before the internal
libraries, which is known to cause problems if the headers from the
previous version of BIND 9 has been installed on the build machine.
2021-06-24 15:33:52 +02:00
Mark Andrews
0d978878c5 invalidate cctx on error 2020-10-06 23:50:01 +11:00
Mark Andrews
8faf12eace render buf was too big
It was misdeclared as a array of pointers (uint8_t*[]) and there
where too many elements (64 * 1024) instead of (64 * 1024 - 1).
2020-10-06 09:49:28 +11:00
Mark Andrews
b736d86697 Have -d print out the message 2020-09-30 13:24:29 +00:00
Mark Andrews
fc5c9e6bce Add packet from issue #4189 2020-09-30 13:24:29 +00:00
Ondřej Surý
33eefe9f85 The dns_message_create() cannot fail, change the return to void
The dns_message_create() function cannot soft fail (as all memory
allocations either succeed or cause abort), so we change the function to
return void and cleanup the calls.
2020-09-29 08:22:08 +02:00
Diego Fronza
12d6d13100 Refactored dns_message_t for using attach/detach semantics
This commit will be used as a base for the next code updates in order
to have a better control of dns_message_t objects' lifetime.
2020-09-29 08:22:08 +02:00
Michał Kępień
b60d7345ed Fix function overrides in unit tests on macOS
Since Mac OS X 10.1, Mach-O object files are by default built with a
so-called two-level namespace which prevents symbol lookups in BIND unit
tests that attempt to override the implementations of certain library
functions from working as intended.  This feature can be disabled by
passing the "-flat_namespace" flag to the linker.  Fix unit tests
affected by this issue on macOS by adding "-flat_namespace" to LDFLAGS
used for building all object files on that operating system (it is not
enough to only set that flag for the unit test executables).
2020-09-28 09:09:21 +02:00
Evan Hunt
dcee985b7f update all copyright headers to eliminate the typo 2020-09-14 16:20:40 -07:00
Ondřej Surý
9d14522469 Add minimized (cmin-tmin-cmin) corpus for dns_message_parse fuzzer
The non-minimized corpus from https://github.com/CZ-NIC/dns-fuzzing was
used as input to afl-cmin, then every case were processed by afl-tmin
and then afl-cmin was used to further minimize the corpus again.
2020-08-25 16:40:24 +02:00
Ondřej Surý
01cc80376e Add dns_message_parse() fuzzer
Previously, the bin/system/wire_test.c was optionally used as a fuzzer,
this commit extracts the parts relevant to the fuzzing into a
specialized fuzzer that can be used in oss-fuzz project.

The fuzzer parses the input as UDP DNS message, then prints parsed DNS
message, then renders the DNS message and then prints the rendered DNS
message.  No part of the code should cause a assertion failure.
2020-08-25 16:40:24 +02:00
Evan Hunt
d7362ff16d BIND 9.17.4
-----BEGIN PGP SIGNATURE-----
 
 iQJDBAABCgAtFiEENKwGS3ftSQfs1TU17QVz/8hFYQUFAl8xHJ0PHG1pY2hhbEBp
 c2Mub3JnAAoJEO0Fc//IRWEFcAsQAIDxJLjMt5lMV3XnakCy+4TSW03QNbnqg/+f
 VLqDzzMBbuKWYVm8GkBFtKehWHfeYGytDDKReM88M7vHzdpi9jWGi0/OIr/nZmUn
 1oK6Kx5TxoIwtW0c1nGiLfOFlBXfzFblcUviaA0aW0v824GkHEEM0gYTp6VJqL3N
 NHtkJXXVNyRRK0ER6xQtSJaizGV2Zt3qYrfo3xUJsFIt5vRUcGipHcaRAQxvmYvw
 SM2heKe4J4qONvFbNlsHRlMdQ4QKIUzFO5XB9hL8kiO1Yyt5bXKi4JRdNb1YkIbk
 pOjm3uNrXrCe8t3r1WxiCY8+9XNDxShL4VirmGKVGAZ/BktJzlyaa1LgkdA+6ggz
 UOo3/wREojYlKtuepZzgz4G5SUl7f5CIMmotAhF9qxDYOAJ/wWCxGhfcFtHUKHrk
 aqFdpQgYcqcT+z479Gov9DTu4RAX+yCSBELOJBPaEE/n4WAFP0p8zWlyFSw4i4hw
 7SFU9yhjpJgrj3HEuKlkK3v3WKFMRgOfeQgMmYNprxT/6NfQiF7PRK3Xrc12OE1m
 hY6wNf8e3VfuMmXJeAE+Ypjwl0bbeHzBCgVqDTqMAYOaW4VvsRV3d52kzWzDz3w8
 xfXWM3RGYlg1QVVo3dCNaKUL9lqVWAX0EXHinNueaiiakeB0FVNDOBtHHxpOlSkT
 izv1V//F
 =JqeM
 -----END PGP SIGNATURE-----

Merge tag 'v9_17_4' into main

BIND 9.17.4
2020-08-20 12:05:01 -07:00
Ondřej Surý
df26656e4b Expand, but minimize (tmin, cmin) dns_rdata_fromwire_text corpus 2020-08-18 16:39:23 +02:00
Mark Andrews
3e743da1bd Disable compression in dns_rdata_fromwire_text() 2020-08-18 11:04:05 +02:00
Mark Andrews
aa811801cb dns_rdata_fromwire() only accepts input up to 2^16-1 octets. 2020-08-18 11:04:05 +02:00