Commit Graph

12395 Commits

Author SHA1 Message Date
Evan Hunt
0002377dca adjust the clang-format penalties to reduce string breaking
this corrects some style glitches such as:
```
        long_function_call(arg, arg2, arg3, arg4, arg5, "str"
                                                        "ing");
```
...by adjusting the penalties for breaking strings and call
parameter lists.
2020-02-17 14:23:58 -08:00
Ondřej Surý
4cf275ba8a Replace non-loop usage of atomic_compare_exchange_weak with strong variant
While testing BIND 9 on arm64 8+ core machine, it was discovered that
the weak variants in fact does spuriously fail, we haven't observed that
on other architectures.

This commit replaces all non-loop usage of atomic_compare_exchange_weak
with atomic_compare_exchange_strong.
2020-02-16 18:09:19 +01:00
Diego Fronza
fa68a0d869 Added atomic_compare_exchange_strong_acq_rel macro
It is much better to read than:
atomic_compare_exchange_strong_explicit() with 5 arguments.
2020-02-16 18:09:19 +01:00
Ondřej Surý
3832e3ecc9 Fixup the missing clang-format bits 2020-02-16 17:34:24 +01:00
Diego Fronza
45543da802 Fixed disposing of resolver->references in destroy() function 2020-02-14 14:28:31 -03:00
Diego Fronza
e7b36924e2 Fixed potential-lock-inversion
This commit simplifies a bit the lock management within dns_resolver_prime()
and prime_done() functions by means of turning resolver's attribute
"priming" into an atomic_bool and by creating only one dependent object on the
lock "primelock", namely the "primefetch" attribute.

By having the attribute "priming" as an atomic type, it save us from having to
use a lock just to test if priming is on or off for the given resolver context
object, within "dns_resolver_prime" function.

The "primelock" lock is still necessary, since dns_resolver_prime() function
internally calls dns_resolver_createfetch(), and whenever this function
succeeds it registers an event in the task manager which could be called by
another thread, namely the "prime_done" function, and this function is
responsible for disposing the "primefetch" attribute in the resolver object,
also for resetting "priming" attribute to false.

It is important that the invariant "priming == false AND primefetch == NULL"
remains constant, so that any thread calling "dns_resolver_prime" knows for sure
that if the "priming" attribute is false, "primefetch" attribute should also be
NULL, so a new fetch context could be created to fulfill this purpose, and
assigned to "primefetch" attribute under the lock protection.

To honor the explanation above, dns_resolver_prime is implemented as follow:
	1. Atomically checks the attribute "priming" for the given resolver context.
	2. If "priming" is false, assumes that "primefetch" is NULL (this is
           ensured by the "prime_done" implementation), acquire "primelock"
	   lock and create a new fetch context, update "primefetch" pointer to
	   point to the newly allocated fetch context.
	3. If "priming" is true, assumes that the job is already in progress,
	   no locks are acquired, nothing else to do.

To keep the previous invariant consistent, "prime_done" is implemented as follow:
	1. Acquire "primefetch" lock.
	2. Keep a reference to the current "primefetch" object;
	3. Reset "primefetch" attribute to NULL.
	4. Release "primefetch" lock.
	5. Atomically update "priming" attribute to false.
	6. Destroy the "primefetch" object by using the temporary reference.

This ensures that if "priming" is false, "primefetch" was already reset to NULL.

It doesn't make any difference in having the "priming" attribute not protected
by a lock, since the visible state of this variable would depend on the calling
order of the functions "dns_resolver_prime" and "prime_done".

As an example, suppose that instead of using an atomic for the "priming" attribute
we employed a lock to protect it.
Now suppose that "prime_done" function is called by Thread A, it is then preempted
before acquiring the lock, thus not reseting "priming" to false.
In parallel to that suppose that a Thread B is scheduled and that it calls
"dns_resolver_prime()", it then acquires the lock and check that "priming" is true,
thus it will consider that this resolver object is already priming and it won't do
any more job.
Conversely if the lock order was acquired in the other direction, Thread B would check
that "priming" is false (since prime_done acquired the lock first and set "priming" to false)
and it would initiate a priming fetch for this resolver.

An atomic variable wouldn't change this behavior, since it would behave exactly the
same, depending on the function call order, with the exception that it would avoid
having to use a lock.

There should be no side effects resulting from this change, since the previous
implementation employed use of the more general resolver's "lock" mutex, which
is used in far more contexts, but in the specifics of the "dns_resolver_prime"
and "prime_done" it was only used to protect "primefetch" and "priming" attributes,
which are not used in any of the other critical sections protected by the same lock,
thus having zero dependency on those variables.
2020-02-14 14:28:31 -03:00
Diego Fronza
c210413a8a Added atomic_compare_exchange_strong_acq_rel macro
It is much better to read than:
atomic_compare_exchange_strong_explicit() with 5 arguments.
2020-02-14 11:41:36 -03:00
Ondřej Surý
5777c44ad0 Reformat using the new rules 2020-02-14 09:31:05 +01:00
Ondřej Surý
654927c871 Add separate .clang-format files for headers 2020-02-14 09:31:05 +01:00
Evan Hunt
e851ed0bb5 apply the modified style 2020-02-13 15:05:06 -08:00
Ondřej Surý
056e133c4c Use clang-tidy to add curly braces around one-line statements
The command used to reformat the files in this commit was:

./util/run-clang-tidy \
	-clang-tidy-binary clang-tidy-11
	-clang-apply-replacements-binary clang-apply-replacements-11 \
	-checks=-*,readability-braces-around-statements \
	-j 9 \
	-fix \
	-format \
	-style=file \
	-quiet
clang-format -i --style=format $(git ls-files '*.c' '*.h')
uncrustify -c .uncrustify.cfg --replace --no-backup $(git ls-files '*.c' '*.h')
clang-format -i --style=format $(git ls-files '*.c' '*.h')
2020-02-13 22:07:21 +01:00
Ondřej Surý
36c6105e4f Use coccinelle to add braces to nested single line statement
Both clang-tidy and uncrustify chokes on statement like this:

for (...)
	if (...)
		break;

This commit uses a very simple semantic patch (below) to add braces around such
statements.

Semantic patch used:

@@
statement S;
expression E;
@@

while (...)
- if (E) S
+ { if (E) { S } }

@@
statement S;
expression E;
@@

for (...;...;...)
- if (E) S
+ { if (E) { S } }

@@
statement S;
expression E;
@@

if (...)
- if (E) S
+ { if (E) { S } }
2020-02-13 21:58:55 +01:00
Ondřej Surý
df6c1f76ad Remove tkey_test (which is no-op anyway) 2020-02-12 15:04:17 +01:00
Ondřej Surý
11341c7688 Update the definition files for Windows 2020-02-12 15:04:17 +01:00
Ondřej Surý
f50b1e0685 Use clang-format to reformat the source files 2020-02-12 15:04:17 +01:00
Witold Kręcicki
a133239698 Don't limit the size of uvreq/nmhandle pool artificially.
There was a hard limit set on number of uvreq and nmhandles
that can be allocated by a pool, but we don't handle a situation
where we can't get an uvreq. Don't limit the number at all,
let the OS deal with it.
2020-02-11 12:10:57 +00:00
Ondřej Surý
b43f5e0238 Convert all atomic operations in isc_rwlock to release-acquire memory ordering
The memory ordering in the rwlock was all wrong, I am copying excerpts
from the https://en.cppreference.com/w/c/atomic/memory_order#Relaxed_ordering
for the convenience of the reader:

  Relaxed ordering

  Atomic operations tagged memory_order_relaxed are not synchronization
  operations; they do not impose an order among concurrent memory
  accesses. They only guarantee atomicity and modification order
  consistency.

  Release-Acquire ordering

  If an atomic store in thread A is tagged memory_order_release and an
  atomic load in thread B from the same variable is tagged
  memory_order_acquire, all memory writes (non-atomic and relaxed atomic)
  that happened-before the atomic store from the point of view of thread
  A, become visible side-effects in thread B. That is, once the atomic
  load is completed, thread B is guaranteed to see everything thread A
  wrote to memory.

  The synchronization is established only between the threads releasing
  and acquiring the same atomic variable. Other threads can see different
  order of memory accesses than either or both of the synchronized
  threads.

Which basically means that we had no or weak synchronization between
threads using the same variables in the rwlock structure.  There should
not be a significant performance drop because the critical sections were
already protected by:

  while(1) {
    if (relaxed_atomic_operation) {
      break;
    }
    LOCK(lock);
    if (!relaxed_atomic_operation) {
      WAIT(sem, lock);
    }
    UNLOCK(lock)l
  }

I would add one more thing to "Don't do your own crypto, folks.":

  - Also don't do your own locking, folks.
2020-02-11 11:10:55 +01:00
Ondřej Surý
a5c87d9d18 Cleanup support for specifying PKCS#11 engine as part of the label
The code for specifying OpenSSL PKCS#11 engine as part of the label
(e.g. -l "pkcs11:token=..." instead of -E pkcs11 -l "token=...")
was non-functional.  This commit just cleans the related code.
2020-02-10 07:30:19 -08:00
Ondřej Surý
bc1d4c9cb4 Clear the pointer to destroyed object early using the semantic patch
Also disable the semantic patch as the code needs tweaks here and there because
some destroy functions might not destroy the object and return early if the
object is still in use.
2020-02-09 18:00:17 -08:00
Witold Kręcicki
d708370db4 Fix atomics usage for mutexatomics 2020-02-08 12:34:19 -08:00
Ondřej Surý
41fe9b7a14 Formatting issues found by local coccinelle run 2020-02-08 03:12:09 -08:00
Ondřej Surý
0dfec4eef7 Remove #include <config.h> from netmgr.h 2020-02-08 03:12:09 -08:00
Evan Hunt
09e061aef7 make ISO8601 duration parsing case-insensitive for robustness 2020-02-07 19:17:05 +01:00
Evan Hunt
6504e7da95 various style cleanups 2020-02-07 19:17:05 +01:00
Evan Hunt
58aa084edc add support for key algorithm mnemonics in dnssec-policy 2020-02-07 19:17:05 +01:00
Matthijs Mekking
8c0db909ee Warn if key lengths are out of range/predefined 2020-02-07 09:30:26 -08:00
Matthijs Mekking
ae6bf1979d Make key-directory optional
The key-directory keyword actually does nothing right now but may
be useful in the future if we want to differentiate between key
directories or HSM keys, or if we want to speficy different
directories for different keys or policies.  Make it optional for
the time being.
2020-02-07 09:30:26 -08:00
Matthijs Mekking
2733edb2a6 Allow for key lifetime unlimited
The keyword 'unlimited' can be used instead of PT0S which means the
same but is more comprehensible for users.

Also fix some redundant "none" parameters in the kasp test.
2020-02-07 09:30:26 -08:00
Evan Hunt
9dc630016e rename 'zone-max-ttl' to 'max-zone-ttl' for consistency 2020-02-07 09:24:06 -08:00
Witold Kręcicki
9371bad268 Disable OpenSSL siphash.
Creation of EVP_MD_CTX and EVP_PKEY is quite expensive, until
we fix the code to reuse the context and key we'll use our own
implementation of siphash.
2020-02-07 11:55:17 +00:00
Mark Andrews
e8bf82efc6 Silence unchecked return of dns_db_find()
190        dns_rdataset_init(&rdataset);
   	3. Condition r == 0, taking true branch.
   	4. Condition result, taking false branch.

	CID 1452691 (#1 of 1): Unchecked return value (CHECKED_RETURN)
	5. check_return: Calling dns_db_find without checking return
	value (as is done elsewhere 39 out of 45 times).

191        check_assertion(dns_db_find(db1, dns_rootname, v2,
192                                    dns_rdatatype_soa, 0, 0, NULL,
193                                    name, &rdataset, NULL));
2020-02-07 08:56:52 +00:00
Mark Andrews
98d5109e82 Fix indenting. 2020-02-07 08:56:52 +00:00
Matthijs Mekking
e6c5ecd698 Update kasp test with CDNSKEY checks
Add checks to the kasp system test to verify CDNSKEY publication.
This test is not entirely complete, because when there is a CDNSKEY
available but there should not be one for KEY N, it is hard to tell
whether the existing CDNSKEY actually belongs to KEY N or another
key.

The check works if we expect a CDNSKEY although we cannot guarantee
that the CDNSKEY is correct: The test verifies existence, not
correctness of the record.
2020-02-06 11:02:22 +01:00
Matthijs Mekking
a9a9aa7fd8 Add parentheses around return values 2020-02-06 10:17:22 +01:00
Matthijs Mekking
b378d0371f Fix kasp bug new KSK on restart [#1593]
When you do a restart or reconfig of named, or rndc loadkeys, this
triggers the key manager to run.  The key manager will check if new
keys need to be created. If there is an active key, and key rollover
is scheduled far enough away, no new key needs to be created.

However, there was a bug that when you just start to sign your zone,
it takes a while before the KSK becomes an active key. An active KSK
has its DS submitted or published, but before the key manager allows
that, the DNSKEY needs to be omnipresent. If you restart named
or rndc loadkeys in quick succession when you just started to sign
your zone, new keys will be created because the KSK is not yet
considered active.

Fix is to check for introducing as well as active keys. These keys
all have in common that their goal is to become omnipresent.
2020-02-06 10:17:22 +01:00
Michal Nowak
7f0fcb8a3e Windows: Prevent tools from clashing with named in system tests
In system tests on Windows tool's local port can sometimes clash with
'named'. On Unix the system is poked for the minimal local port,
otherwise is set to 32768 as a sane minimum. For Windows we don't
poke but set a hardcoded limit; this change aligns the limit with
Unix and changes it to 32768.
2020-02-05 10:03:09 +00:00
Mark Andrews
fccf65a585 'dctx' must be non NULL, remove test.
1549 cleanup:
1550        if (dctx->dbiter != NULL)
1551                dns_dbiterator_destroy(&dctx->dbiter);
1552        if (dctx->db != NULL)
1553                dns_db_detach(&dctx->db);

	CID 1452686 (#1 of 1): Dereference before null check (REVERSE_INULL)
	check_after_deref: Null-checking dctx suggests that it may
	be null, but it has already been dereferenced on all paths
	leading to the check.

1554        if (dctx != NULL)
1555                isc_mem_put(mctx, dctx, sizeof(*dctx));
2020-02-05 18:37:17 +11:00
Mark Andrews
7ba1af0280 'lcfg' must be non NULL, remove test.
389        else

	CID 1452695 (#1 of 1): Dereference before null check (REVERSE_INULL)
	check_after_deref: Null-checking lcfg suggests that it may
	be null, but it has already been dereferenced on all paths
	leading to the check.

390                if (lcfg != NULL)
391                        isc_logconfig_destroy(&lcfg);
2020-02-05 18:37:17 +11:00
Mark Andrews
0312e73e16 'closest' must be non NULL, remove test.
6412 cleanup:
6413        dns_rdataset_disassociate(&neg);
6414        dns_rdataset_disassociate(&negsig);

	CID 1452700 (#1 of 1): Dereference before null check (REVERSE_INULL)
	check_after_deref: Null-checking closest suggests that it
	may be null, but it has already been dereferenced on all
	paths leading to the check.

6415        if (closest != NULL)
6416                free_noqname(mctx, &closest);
2020-02-05 18:37:17 +11:00
Mark Andrews
2e189bb053 'stub' cannot be non NULL, remove test.
13429 cleanup:
13430        cancel_refresh(zone);

	CID 1452702 (#1 of 1): Dereference before null check (REVERSE_INULL)
	check_after_deref: Null-checking stub suggests that it may
	be null, but it has already been dereferenced on all paths
	leading to the check.

13431        if (stub != NULL) {
13432                stub->magic = 0;
2020-02-05 18:37:17 +11:00
Mark Andrews
1b1a94ea6d 'noqname' must be non NULL, remove test.
6367cleanup:
6368        dns_rdataset_disassociate(&neg);
6369        dns_rdataset_disassociate(&negsig);

	CID 1452704 (#1 of 1): Dereference before null check
	(REVERSE_INULL) check_after_deref: Null-checking noqname
	suggests that it may be null, but it has already been
	dereferenced on all paths leading to the check.

6370        if (noqname != NULL)
6371                free_noqname(mctx, &noqname);
2020-02-05 18:37:17 +11:00
Mark Andrews
e4d08c0232 'event' must be non NULL, remove test.
1401        }

	CID 1453455 (#1 of 1): Dereference before null check (REVERSE_INULL)
	check_after_deref: Null-checking event suggests that it may be null,
	but it has already been dereferenced on all paths leading to the check.

1402        if (event != NULL)
1403                isc_event_free(ISC_EVENT_PTR(&event));
2020-02-05 18:37:17 +11:00
Mark Andrews
1efc7550a3 keymgr_keyrole couldn't emit "NOSIGN".
92        } else {
 93                return ("ZSK");
 94        }

	CID 1455900 (#1 of 1): Structurally dead code (UNREACHABLE)
	unreachable: This code cannot be reached: return "NOSIGN";.

 95        return ("NOSIGN");
2020-02-05 18:37:17 +11:00
Mark Andrews
5fc9efba30 Remove dead error code.
128        return (ISC_R_SUCCESS);
129

	CID 1456146 (#1 of 1): Structurally dead code (UNREACHABLE)
	unreachable: This code cannot be reached: {
	   if (dst->labels[i] != N....

130        do {
2020-02-05 18:37:17 +11:00
Mark Andrews
aa101260d9 'indentctx' is always defined. Just use it.
402        ctx->serve_stale_ttl = 0;

	notnull: At condition indentctx, the value of indentctx
	cannot be NULL.  dead_error_condition: The condition indentctx
	must be true.

	CID 1456147 (#1 of 1): Logically dead code (DEADCODE)
	dead_error_line: Execution cannot reach the expression
	default_indent inside this statement: ctx->indent = (indentctx
	? ....

403        ctx->indent = indentctx ? *indentctx : default_indent;
2020-02-05 18:37:17 +11:00
Mark Andrews
0be2dc9f22 break was on wrong line.
959                break;

	CID 1457872 (#1 of 1): Structurally dead code (UNREACHABLE)
	unreachable: This code cannot be reached:
	isc__nm_incstats(sock->mgr,....

 960                isc__nm_incstats(sock->mgr, sock->statsindex[STATID_ACTIVE]);
 961        default:
2020-02-05 18:37:17 +11:00
Mark Andrews
331b74d6bf dstkey is no longer used 2020-02-05 18:37:17 +11:00
Mark Andrews
a038f77d92 'buffer' must be non-NULL as isc_buffer_allocate can no longer fail.
1636 cleanup:

CID 1458130 (#1 of 1): Dereference before null check (REVERSE_INULL)
check_after_deref: Null-checking buffer suggests that it may be
null, but it has already been dereferenced on all paths leading to
the check.

1637        if (buffer != NULL)
1638                isc_buffer_free(&buffer);
2020-02-05 18:37:17 +11:00
Ondřej Surý
a9bd6f6ea6 Fix comparison between type uint16_t and wider type size_t in a loop
Found by LGTM.com (see below for description), and while it should not
happen as EDNS OPT RDLEN is uint16_t, the fix is easy.  A little bit
of cleanup is included too.

> In a loop condition, comparison of a value of a narrow type with a value
> of a wide type may result in unexpected behavior if the wider value is
> sufficiently large (or small). This is because the narrower value may
> overflow. This can lead to an infinite loop.
2020-02-05 01:41:13 +00:00
Matthijs Mekking
37b41ff693 Simplify cachedb rrset statistic counters
This commit simplifies the cachedb rrset statistics in two ways:
- Introduce new rdtypecounter arithmetics, allowing bitwise
  operations.
- Remove the special DLV statistic counter.

New rdtypecounter arithmetics
-----------------------------
"The rdtypecounter arithmetics is a brain twister".  Replace the
enum counters with some defines.  A rdtypecounter is now 8 bits for
RRtypes and 3 bits for flags:

      0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |  |  |  |  |  |  S  |NX|         RRType        |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

If the 8 bits for RRtype are all zero, this is an Other RRtype.

Bit 7 is the NXRRSET (NX) flag and indicates whether this is a
positive (0) or a negative (1) RRset.

Then bit 5 and 6 mostly tell you if this counter is for an active,
stale, or ancient RRtype:

    S = 0x00 means Active
    S = 0x01 means Stale
    S = 0x10 means Ancient

Since a counter cannot be stale and ancient at the same time, we
treat S = 0x11 as a special case to deal with NXDOMAIN counters.

S = 0x11 indicates an NXDOMAIN counter and in this case the RRtype
field signals the expiry of this cached item:

    RRType = 0 means Active
    RRType = 1 means Stale
    RRType = 2 means Ancient
2020-02-04 11:58:34 +01:00