From 8e6e3ac7d1c1ed85e1cbf6810e80d60fd14c1e4e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 9 May 2022 09:49:27 +0200 Subject: [PATCH] fuzz-calendarspec: increase coverage by calculating occurences Coverage data shows that we didn't test calendar_spec_next_usec() and associated functions at all. The input samples so far were only used until the first NUL. We take advantage of that by using the part until the second NUL as the starting timestamp, retaining backwards compatibility for how the first part is used. --- src/fuzz/fuzz-calendarspec.c | 43 ++++++++++++++++++++++++++--- test/fuzz/fuzz-calendarspec/input1 | Bin 0 -> 21 bytes 2 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 test/fuzz/fuzz-calendarspec/input1 diff --git a/src/fuzz/fuzz-calendarspec.c b/src/fuzz/fuzz-calendarspec.c index 07d3fbca7f0..ea027b8f66e 100644 --- a/src/fuzz/fuzz-calendarspec.c +++ b/src/fuzz/fuzz-calendarspec.c @@ -4,19 +4,54 @@ #include "calendarspec.h" #include "fd-util.h" #include "fuzz.h" +#include "string-util.h" +#include "time-util.h" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { _cleanup_(calendar_spec_freep) CalendarSpec *cspec = NULL; - _cleanup_free_ char *str = NULL, *p = NULL; + _cleanup_free_ char *str = NULL; + int r; if (!getenv("SYSTEMD_LOG_LEVEL")) log_set_max_level(LOG_CRIT); str = memdup_suffix0(data, size); - if (calendar_spec_from_string(str, &cspec) >= 0) { - (void) calendar_spec_valid(cspec); - (void) calendar_spec_to_string(cspec, &p); + size_t l1 = strlen(str); + const char* usecs = l1 < size ? str + l1 + 1 : ""; + + r = calendar_spec_from_string(str, &cspec); + if (r < 0) { + log_debug_errno(r, "Failed to parse \"%s\": %m", str); + return 0; + } + + _cleanup_free_ char *p = NULL; + assert_se(calendar_spec_valid(cspec)); + assert_se(calendar_spec_to_string(cspec, &p) == 0); + assert(p); + + log_debug("spec: %s → %s", str, p); + + _cleanup_(calendar_spec_freep) CalendarSpec *cspec2 = NULL; + assert_se(calendar_spec_from_string(p, &cspec2) >= 0); + assert_se(calendar_spec_valid(cspec2)); + + usec_t usec = 0; + (void) parse_time(usecs, &usec, 1); + + /* If timezone is set, calendar_spec_next_usec() would fork, bleh :( + * Let's not try that. */ + cspec->timezone = mfree(cspec->timezone); + + log_debug("00: %s", strna(FORMAT_TIMESTAMP(usec))); + for (unsigned i = 1; i <= 20; i++) { + r = calendar_spec_next_usec(cspec, usec, &usec); + if (r < 0) { + log_debug_errno(r, "%02u: %m", i); + break; + } + log_debug("%02u: %s", i, FORMAT_TIMESTAMP(usec)); } return 0; diff --git a/test/fuzz/fuzz-calendarspec/input1 b/test/fuzz/fuzz-calendarspec/input1 new file mode 100644 index 0000000000000000000000000000000000000000..00522a75b95e70a8703b53e2c70986192a6c6c65 GIT binary patch literal 21 cc-qs_)zZ~cFf_C>G_o=@W-v4|HZkP_04SdWp8x;= literal 0 Hc-jL100001 -- 2.47.3