annotate FUZZER-NOTES.md @ 1788:1fc0012b9c38

Fix handling of replies to global requests (#112) The current code assumes that all global requests want / need a reply. This isn't always true and the request itself indicates if it wants a reply or not. It causes a specific problem with [email protected] messages. These are sent by OpenSSH after authentication to inform the client of potential other host keys for the host. This can be used to add a new type of host key or to rotate host keys. The initial information message from the server is sent as a global request, but with want_reply set to false. This means that the server doesn't expect an answer to this message. Instead the client needs to send a prove request as a reply if it wants to receive proof of ownership for the host keys. The bug doesn't cause any current problems with due to how OpenSSH treats receiving the failure message. It instead treats it as a keepalive message and further ignores it. Arguably this is a protocol violation though of Dropbear and it is only accidental that it doesn't cause a problem with OpenSSH. The bug was found when adding host keys support to libssh, which is more strict protocol wise and treats the unexpected failure message an error, also see https://gitlab.com/libssh/libssh-mirror/-/merge_requests/145 for more information. The fix here is to honor the want_reply flag in the global request and to only send a reply if the other side expects a reply.
author Dirkjan Bussink <d.bussink@gmail.com>
date Thu, 10 Dec 2020 16:13:13 +0100
parents d32bcb5c557d
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1590
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1 # Fuzzing Dropbear
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3 Dropbear is process-per-session so it assumes calling `dropbear_exit()`
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
4 is fine at any point to clean up. This makes fuzzing a bit trickier.
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
5 A few pieces of wrapping infrastructure are used to work around this.
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
6
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
7 The [libfuzzer](http://llvm.org/docs/LibFuzzer.html#fuzz-target) harness
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
8 expects a long running process to continually run a test function with
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
9 a string of crafted input. That process should not leak resources or exit.
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
10
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
11 ## longjmp
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
12
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
13 When dropbear runs in fuzz mode it sets up a
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
14 [`setjmp()`](http://man7.org/linux/man-pages/man3/setjmp.3.html) target prior
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
15 to launching the code to be fuzzed, and then [`dropbear_exit()`](dbutil.c#L125)
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
16 calls `longjmp()` back there. This avoids exiting though it doesn't free
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
17 memory or other resources.
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
18
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
19 ## malloc Wrapper
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
20
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
21 Dropbear normally uses a [`m_malloc()`](dbmalloc.c) function that is the same as `malloc()` but
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
22 exits if allocation fails. In fuzzing mode this is replaced with a tracking allocator
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
23 that stores all allocations in a linked list. After the `longjmp()` occurs the fuzzer target
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
24 calls [`m_malloc_free_epoch(1, 1)`](dbmalloc.c) to clean up any unreleased memory.
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
25
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
26 If the fuzz target runs to completion it calls `m_malloc_free_epoch(1, 0)` which will reset
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
27 the tracked allocations but will not free memory - that allows libfuzzer's leak checking
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
28 to detect leaks in normal operation.
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
29
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
30 ## File Descriptor Input
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
31
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
32 As a network process Dropbear reads and writes from a socket. The wrappers for
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
33 `read()`/`write()`/`select()` in [fuzz-wrapfd.c](fuzz-wrapfd.c) will read from the
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
34 fuzzer input that has been set up with `wrapfd_add()`. `write()` output is
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
35 currently discarded.
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
36 These also test error paths such as EINTR and short reads with certain probabilities.
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
37
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
38 This allows running the entire dropbear server process with network input provided by the
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
39 fuzzer, without many modifications to the main code. At the time of writing this
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
40 only runs the pre-authentication stages, though post-authentication could be run similarly.
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
41
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
42 ## Encryption and Randomness
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
43
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
44 When running in fuzzing mode Dropbear uses a [fixed seed](dbrandom.c#L185)
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
45 every time so that failures can be reproduced.
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
46
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
47 Since the fuzzer cannot generate valid encrypted input the packet decryption and
1591
b794d277c6da fix some links
Matt Johnston <matt@ucc.asn.au>
parents: 1590
diff changeset
48 message authentication calls are disabled, see [packet.c](packet.c).
1590
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
49 MAC failures are set to occur with a low probability to test that error path.
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
50
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
51 ## Fuzzers
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
52
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
53 Current fuzzers are
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
54
1591
b794d277c6da fix some links
Matt Johnston <matt@ucc.asn.au>
parents: 1590
diff changeset
55 - [fuzzer-preauth](fuzzer-preauth.c) - the fuzzer input is treated as a stream of session input. This will
1590
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
56 test key exchange, packet ordering, authentication attempts etc.
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
57
1591
b794d277c6da fix some links
Matt Johnston <matt@ucc.asn.au>
parents: 1590
diff changeset
58 - [fuzzer-preauth_nomaths](fuzzer-preauth_nomaths.c) - the same as fuzzer-preauth but with asymmetric crypto
1590
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
59 routines replaced with dummies for faster runtime. corpora are shared
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
60 between fuzzers by [oss-fuzz](https://github.com/google/oss-fuzz) so this
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
61 will help fuzzer-preauth too.
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
62
1591
b794d277c6da fix some links
Matt Johnston <matt@ucc.asn.au>
parents: 1590
diff changeset
63 - [fuzzer-verify](fuzzer-verify.c) - read a key and signature from fuzzer input and verify that signature.
1590
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
64 It would not be expected to pass, though some keys with bad parameters are
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
65 able to validate with a trivial signature - extra checks are added for that.
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
66
1591
b794d277c6da fix some links
Matt Johnston <matt@ucc.asn.au>
parents: 1590
diff changeset
67 - [fuzzer-pubkey](fuzzer-pubkey.c) - test parsing of an `authorized_keys` line.
1590
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
68
1591
b794d277c6da fix some links
Matt Johnston <matt@ucc.asn.au>
parents: 1590
diff changeset
69 - [fuzzer-kexdh](fuzzer-kexdh.c) - test Diffie-Hellman key exchange where the fuzz input is the
b794d277c6da fix some links
Matt Johnston <matt@ucc.asn.au>
parents: 1590
diff changeset
70 ephemeral public key that would be received over the network. This is testing `mp_expt_mod()`
b794d277c6da fix some links
Matt Johnston <matt@ucc.asn.au>
parents: 1590
diff changeset
71 and and other libtommath routines.
1590
68d5d8e84a92 notes on the fuzzer
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
72
1591
b794d277c6da fix some links
Matt Johnston <matt@ucc.asn.au>
parents: 1590
diff changeset
73 - [fuzzer-kexecdh](fuzzer-kexecdh.c) - test Elliptic Curve Diffie-Hellman key exchange like fuzzer-kexdh.
b794d277c6da fix some links
Matt Johnston <matt@ucc.asn.au>
parents: 1590
diff changeset
74 This is testing libtommath ECC routines.
1659
d32bcb5c557d Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents: 1591
diff changeset
75
d32bcb5c557d Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents: 1591
diff changeset
76 - [fuzzer-kexcurve25519](fuzzer-kexcurve25519.c) - test Curve25519 Elliptic Curve Diffie-Hellman key exchange
d32bcb5c557d Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents: 1591
diff changeset
77 like fuzzer-kexecdh. This is testing `dropbear_curve25519_scalarmult()` and other libtommath routines.