Skip to content

Commit c74002d

Browse files
committed
fix(fuzzer): harden LibAFL signal state
Use signal-safe interrupt counters and initialize the jump target before marking an execution active so signal handlers do not observe partially prepared state.
1 parent 1f2aeb9 commit c74002d

1 file changed

Lines changed: 15 additions & 11 deletions

File tree

packages/fuzzer/libafl_runtime.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ struct SyncFuzzTargetContext {
145145
SyncWatchdogState watchdog;
146146
volatile std::sig_atomic_t signal_status = 0;
147147
volatile std::sig_atomic_t execution_active = 0;
148-
volatile int sigints = 0;
148+
volatile std::sig_atomic_t sigints = 0;
149149
std::jmp_buf execution_context;
150150
};
151151

@@ -179,7 +179,7 @@ struct AsyncFuzzTargetContext {
179179
bool is_resolved = false;
180180
int run_status = kRuntimeOk;
181181
volatile std::sig_atomic_t execution_active = 0;
182-
volatile int sigints = 0;
182+
volatile std::sig_atomic_t sigints = 0;
183183
std::jmp_buf execution_context;
184184
};
185185

@@ -450,8 +450,10 @@ int ExecuteSyncInput(void *user_data, const uint8_t *data, size_t size) {
450450

451451
try {
452452
auto buffer = Napi::Buffer<uint8_t>::Copy(context->env, data, size);
453-
context->execution_active = 1;
453+
// Initialize the jump target before signal handlers can treat this
454+
// invocation as actively executing user code.
454455
const auto signal_status = setjmp(context->execution_context);
456+
context->execution_active = 1;
455457
if (signal_status == 0) {
456458
auto result = context->target.Call({buffer});
457459
if (result.IsPromise()) {
@@ -506,14 +508,16 @@ void CallJsFuzzCallback(Napi::Env env, Napi::Function js_fuzz_callback,
506508
try {
507509
if (context->sigints > 0) {
508510
TryPublishExecutionStatus(state, kExecutionStop);
509-
return;
510-
}
511-
512-
context->execution_active = 1;
513-
const auto signal_status = setjmp(context->execution_context);
514-
if (signal_status == SIGSEGV) {
515-
context->execution_active = 0;
516-
std::cerr << "==" << static_cast<unsigned long>(GetPID())
511+
return;
512+
}
513+
514+
// Initialize the jump target before signal handlers can treat this
515+
// invocation as actively executing user code.
516+
const auto signal_status = setjmp(context->execution_context);
517+
context->execution_active = 1;
518+
if (signal_status == SIGSEGV) {
519+
context->execution_active = 0;
520+
std::cerr << "==" << static_cast<unsigned long>(GetPID())
517521
<< "== Segmentation Fault" << std::endl;
518522
libfuzzer::PrintCrashingInput();
519523
_Exit(libfuzzer::EXIT_ERROR_SEGV);

0 commit comments

Comments
 (0)