Skip to content

Commit 1f1d120

Browse files
author
Chandra Pratap
committed
fuzz-tests: Add a test for the onion message handler
`handle_onion_message()` in `connectd/onion_message.c` is responsible for handling incoming onion messages from a peer. Since it deals with external input, add a test for it.
1 parent 77b8a42 commit 1f1d120

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed

tests/fuzz/Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ tests/fuzz/fuzz-hmac-sha256: LDLIBS += -lcrypto
99
tests/fuzz/fuzz-wire-*.o: tests/fuzz/wire.h
1010
tests/fuzz/fuzz-bolt12-*.o: tests/fuzz/bolt12.h
1111

12+
tests/fuzz/fuzz-handle_onion_message: common/sphinx.o \
13+
common/blindedpath.o \
14+
common/hmac.o \
15+
common/blinding.o \
16+
common/onionreply.o \
17+
common/dev_disconnect.o \
18+
common/onion_message_parse.o \
19+
connectd/onion_message.o \
20+
connectd/connectd_wiregen.o
21+
1222
FUZZ_TARGETS_SRC := $(wildcard tests/fuzz/fuzz-*.c)
1323
FUZZ_TARGETS_OBJS := $(FUZZ_TARGETS_SRC:.c=.o)
1424
FUZZ_TARGETS_BIN := $(FUZZ_TARGETS_SRC:.c=)
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#include "config.h"
2+
#include <fcntl.h>
3+
#include <setjmp.h>
4+
#include <common/daemon_conn.h>
5+
#include <common/dev_disconnect.h>
6+
#include <connectd/connectd.h>
7+
#include <connectd/connectd_wiregen.h>
8+
#include <connectd/connectd.h>
9+
#include <connectd/onion_message.h>
10+
#include <connectd/multiplex.h>
11+
#include <common/ecdh.h>
12+
#include <common/setup.h>
13+
#include <common/status.h>
14+
#include <common/wire_error.h>
15+
#include <secp256k1_ecdh.h>
16+
#include <wire/peer_wiregen.h>
17+
#include <tests/fuzz/libfuzz.h>
18+
19+
static int lightningd_fd;
20+
static struct privkey priv;
21+
static struct siphash_seed siphashseed;
22+
jmp_buf fuzz_env;
23+
24+
/* MOCKS START */
25+
void inject_peer_msg(struct peer *peer UNNEEDED, const u8 *msg TAKES UNNEEDED)
26+
{ longjmp(fuzz_env, 1); }
27+
28+
u8 *towire_warningfmt(const tal_t *ctx UNNEEDED,
29+
const struct channel_id *channel UNNEEDED,
30+
const char *fmt UNNEEDED, ...)
31+
{ longjmp(fuzz_env, 1); }
32+
33+
const struct siphash_seed *siphash_seed(void)
34+
{ return &siphashseed; }
35+
/* MOCKS END */
36+
37+
void ecdh(const struct pubkey *point, struct secret *ss)
38+
{
39+
assert(secp256k1_ecdh(secp256k1_ctx, ss->data, &point->pubkey,
40+
priv.secret.data, NULL, NULL) == 1);
41+
}
42+
43+
static struct daemon *new_daemon(const tal_t *ctx)
44+
{
45+
struct daemon *daemon = talz(ctx, struct daemon);
46+
47+
daemon->our_features = tal(ctx, struct feature_set);
48+
daemon->our_features->bits[NODE_ANNOUNCE_FEATURE] = tal_arr(ctx, u8, 0);
49+
set_feature_bit(&daemon->our_features->bits[NODE_ANNOUNCE_FEATURE], OPT_ONION_MESSAGES);
50+
51+
daemon->scid_htable = tal(ctx, struct scid_htable);
52+
scid_htable_init(daemon->scid_htable);
53+
54+
daemon->peers = tal(ctx, struct peer_htable);
55+
peer_htable_init(daemon->peers);
56+
57+
memset(&daemon->mykey, 'a', sizeof(daemon->mykey));
58+
node_id_from_pubkey(&daemon->id, &daemon->mykey);
59+
60+
daemon->master = daemon_conn_new(ctx, lightningd_fd, NULL, NULL, daemon);
61+
62+
return daemon;
63+
}
64+
65+
void init(int *argc, char ***argv)
66+
{
67+
common_setup("fuzzer");
68+
lightningd_fd = open("/dev/null", O_WRONLY);
69+
status_setup_sync(lightningd_fd);
70+
chainparams = chainparams_for_network("bitcoin");
71+
72+
memset(&priv, 'b', sizeof(priv));
73+
memset(&siphashseed, 1, sizeof(siphashseed));
74+
}
75+
76+
void run(const uint8_t *data, size_t size)
77+
{
78+
if (setjmp(fuzz_env) != 0)
79+
goto cleanup;
80+
81+
struct daemon *daemon;
82+
struct peer *peer;
83+
struct pubkey dummy_key;
84+
85+
memset(&dummy_key, 'c', sizeof(dummy_key));
86+
87+
daemon = new_daemon(tmpctx);
88+
if (!daemon)
89+
goto cleanup;
90+
91+
peer = talz(tmpctx, struct peer);
92+
93+
peer->daemon = daemon;
94+
node_id_from_pubkey(&peer->id, &dummy_key);
95+
peer->onionmsg_incoming_tokens = ONION_MSG_MSEC;
96+
97+
/* Use fuzzer data as payload of the onion message. */
98+
const u8 *onion_msg = towire_onion_message(tmpctx, &dummy_key,
99+
tal_dup_arr(tmpctx, u8, data, size, 0));
100+
101+
handle_onion_message(daemon, peer, onion_msg);
102+
103+
cleanup:
104+
if (daemon)
105+
tal_free(daemon->master);
106+
clean_tmpctx();
107+
}

0 commit comments

Comments
 (0)