Skip to content

Commit e4558a2

Browse files
committed
perf: Make time move a lot faster in fuzzing runs.
1 parent ae369dc commit e4558a2

5 files changed

Lines changed: 24 additions & 36 deletions

File tree

testing/fuzzing/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ cc_library(
1616
)
1717

1818
cc_fuzz_test(
19-
name = "bootstrap_fuzzer",
19+
name = "bootstrap_fuzz_test",
2020
srcs = ["bootstrap_harness.cc"],
2121
copts = ["-UNDEBUG"],
2222
corpus = ["//tools/toktok-fuzzer/corpus:bootstrap_fuzzer"],

testing/fuzzing/bootstrap_harness.cc

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <cstring>
33

44
#include "../../toxcore/tox.h"
5+
#include "../../toxcore/tox_struct.h"
56
#include "fuzz_adapter.h"
67

78
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
@@ -12,12 +13,18 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
1213
Tox_Err_New error_new;
1314
Tox *tox = tox_new(nullptr, &error_new);
1415

16+
uint64_t clock = 0;
17+
mono_time_set_current_time_callback(
18+
tox->mono_time,
19+
[](Mono_Time *mono_time, void *user_data) { return *static_cast<uint64_t *>(user_data); },
20+
&clock);
21+
1522
assert(tox != nullptr);
1623
assert(error_new == TOX_ERR_NEW_OK);
1724

1825
uint8_t pub_key[TOX_PUBLIC_KEY_SIZE] = {0};
1926

20-
bool success = tox_bootstrap(tox, "127.0.0.1", 12345, pub_key, nullptr);
27+
const bool success = tox_bootstrap(tox, "127.0.0.1", 12345, pub_key, nullptr);
2128
assert(success);
2229

2330
/*
@@ -26,8 +33,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
2633
* NOTE: This should be fine tuned after gathering some experience.
2734
*/
2835

29-
for (uint32_t i = 0; i < 100; ++i) {
36+
for (uint32_t i = 0; i < 50; ++i) {
3037
tox_iterate(tox, nullptr);
38+
// Move the clock forward a decent amount so all the time-based checks
39+
// trigger more quickly.
40+
clock += 200;
3141
}
3242

3343
tox_kill(tox);

testing/fuzzing/fuzz_adapter.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
#include "fuzz_adapter.h"
22

33
struct fuzz_buf {
4-
/* Monotonic counter for time replacement */
5-
uint64_t counter;
64
/* Fuzz data buffer */
75
const uint8_t *cur;
86
const uint8_t *end;
@@ -17,7 +15,6 @@ static struct fuzz_buf data;
1715

1816
void network_adapter_init(const uint8_t *buf, size_t length)
1917
{
20-
data.counter = 0;
2118
data.cur = buf;
2219
data.end = buf + length;
2320
}
@@ -90,8 +87,3 @@ void fuzz_random_bytes(uint8_t *rnd, size_t length)
9087
memcpy(rnd, data.cur, bytes_read);
9188
data.cur += bytes_read;
9289
}
93-
94-
uint64_t fuzz_get_count(void)
95-
{
96-
return data.counter++;
97-
}

testing/fuzzing/fuzz_adapter.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,6 @@ ssize_t fuzz_recv(int sockfd, void *buf, size_t len, int flags);
3737
/* The following functions intercept generation of random data */
3838
void fuzz_random_bytes(uint8_t *rnd, size_t length);
3939

40-
/* The following function replaces all time bases with a monotonic counter */
41-
42-
uint64_t fuzz_get_count(void);
43-
4440
#ifdef __cplusplus
4541
}
4642
#endif

toxcore/mono_time.c

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,6 @@
3232

3333
#include "ccompat.h"
3434

35-
//!TOKSTYLE-
36-
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
37-
#include "../testing/fuzzing/fuzz_adapter.h"
38-
#endif
39-
//!TOKSTYLE+
40-
4135
/** don't call into system billions of times for no reason */
4236
struct Mono_Time {
4337
uint64_t cur_time;
@@ -110,6 +104,11 @@ static uint64_t current_time_monotonic_default(Mono_Time *mono_time, void *user_
110104
non_null(1) nullable(2)
111105
static uint64_t current_time_monotonic_default(Mono_Time *mono_time, void *user_data)
112106
{
107+
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
108+
// This assert should always fail. If it does, the fuzzing harness didn't
109+
// override the mono time callback.
110+
assert(mono_time == nullptr);
111+
#endif
113112
struct timespec clock_mono;
114113
clock_gettime(CLOCK_MONOTONIC, &clock_mono);
115114
return timespec_to_u64(clock_mono);
@@ -118,14 +117,6 @@ static uint64_t current_time_monotonic_default(Mono_Time *mono_time, void *user_
118117
#endif // !OS_WIN32
119118

120119

121-
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
122-
non_null(1) nullable(2)
123-
static uint64_t current_time_monotonic_dummy(Mono_Time *mono_time, void *user_data)
124-
{
125-
return fuzz_get_count();
126-
}
127-
#endif
128-
129120
Mono_Time *mono_time_new(void)
130121
{
131122
Mono_Time *mono_time = (Mono_Time *)calloc(1, sizeof(Mono_Time));
@@ -147,11 +138,7 @@ Mono_Time *mono_time_new(void)
147138
return nullptr;
148139
}
149140

150-
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
151-
mono_time->current_time_callback = current_time_monotonic_dummy;
152-
#else
153141
mono_time->current_time_callback = current_time_monotonic_default;
154-
#endif
155142
mono_time->user_data = nullptr;
156143

157144
#ifdef OS_WIN32
@@ -169,12 +156,15 @@ Mono_Time *mono_time_new(void)
169156

170157
mono_time->cur_time = 0;
171158
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
172-
mono_time->base_time = 0; // Maximum reproducibility
159+
// Maximum reproducibility and don't update mono_time before the harness has
160+
// had a chance to set the callback.
161+
// TODO(iphydf): Put mono time callback into Tox_Options with accessors only
162+
// in tox_private.h.
163+
mono_time->base_time = 0;
173164
#else
174165
mono_time->base_time = (uint64_t)time(nullptr) - (current_time_monotonic(mono_time) / 1000ULL);
175-
#endif
176-
177166
mono_time_update(mono_time);
167+
#endif
178168

179169
return mono_time;
180170
}

0 commit comments

Comments
 (0)