Some checks are pending
Fuzz Smoke / libFuzzer smoke (push) Waiting to run
Startup ordering defects were only observable by waiting minutes on a live daemon, and the one that aborted it took a live restart loop to find. Give the startup contracts a deterministic harness that runs in milliseconds. + startup_fuzz_support.h drives the real ServiceManagerFsm and the real DeferralGate with virtual time: legal phase advances, injected failure, shutdown and terminal reset, idle/busy, pressure/calm, starvation deadlines and cancellation + oracles fail closed on shutdown resurrection without reset, failure-to-ready, eligibility disagreeing with fsm.isReady(), admission outside the virtual deadline, and ineligible work touching the admission gate; fuzzed IEEE-754 components must never yield non-finite or out-of-range scores + catch2_startup_replay runs named regressions plus 1024 seeded traces per run and reports the root seed and action offset for replay + fuzz_startup builds the same harness for libFuzzer/AFL, with a seed generator that refuses to overwrite different existing files - the fuzzing lane no longer defaults to TSan: harnesses link -fsanitize=fuzzer,address,undefined and the two runtimes cannot share a process; combining them now fails with an explanation instead of producing a binary that cannot start - documented the lane invocation, target naming and the coverage limits, including that governor call ordering inside the poller is not covered Scope: contract-valid single-owner schedules. Executor interleavings, late callbacks, concurrent FSM instances and filesystem/model faults are not modeled. Signed-off-by: trvon <git@trevon.dev>
28 lines
919 B
C++
28 lines
919 B
C++
// Copyright (c) 2026 YAMS Contributors
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <span>
|
|
|
|
#include <spdlog/spdlog.h>
|
|
|
|
#include "startup_fuzz_support.h"
|
|
|
|
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, std::size_t size) {
|
|
// A standalone fuzz process owns its logger and the process-global tinyfsm.
|
|
spdlog::set_level(spdlog::level::off);
|
|
const auto bytes = std::span<const std::uint8_t>{data, size};
|
|
const auto replay = yams::fuzz::replayStartup(bytes);
|
|
if (!replay.ok()) {
|
|
std::fprintf(stderr, "startup replay failed at byte %zu: %s\n", replay.offset,
|
|
replay.error);
|
|
std::abort();
|
|
}
|
|
if (!yams::fuzz::semanticScoresBounded(bytes)) {
|
|
std::fprintf(stderr, "startup semantic-score invariant failed\n");
|
|
std::abort();
|
|
}
|
|
return 0;
|
|
}
|