1

I am using go-118-fuzz-build and some manual patching to build a libfuzzer executable from a native Go 1.18 fuzz test:

  1. Patch the test file, replacing *testing.F with *github.com/AdamKorcz/go-118-fuzz-build/utils.F, rename it, and move it into a temp folder.
  2. Compile the test go-118-fuzz-build -o fuzz_target.a -func $func ./tmp.
  3. Build an executable with clang -fsanitize=fuzzer fuzz_target.a -o fuzz_target.
  4. Run the fuzzer: ./fuzzer -print_final_stats=1 -artifact_prefix=./crashes/ -error_exitcode=76 -max_total_time=600 corpus -max_total_time=300 (via gitlab-cov-fuzz)

I get the following output:

signal 11 received but handler not on signal stack
fatal error: non-Go code set up signal handler without SA_ONSTACK flag
runtime stack:
(...)
==4126== ERROR: libFuzzer: deadly signal
    #0 0x4aec70 in __sanitizer_print_stack_trace (/builds/accumulatenetwork/accumulate/fuzzer+0x4aec70)
    #1 0x45a5c8 in fuzzer::PrintStackTrace() (/builds/accumulatenetwork/accumulate/fuzzer+0x45a5c8)
    #2 0x440603 in fuzzer::Fuzzer::CrashCallback() (/builds/accumulatenetwork/accumulate/fuzzer+0x440603)
    #3 0x7f900f75613f  (/lib/x86_64-linux-gnu/libpthread.so.0+0x1313f)
    #4 0x520f00 in runtime.raise.abi0 runtime/sys_linux_amd64.s:158
NOTE: libFuzzer has rudimentary signal handlers.
      Combine libFuzzer with AddressSanitizer or similar for better crash reports.
SUMMARY: libFuzzer: deadly signal

I assume the fuzzer input causes my code to raise SIGSEGV but libfuzzer's signal handler is interfering with Go so I don't get the actual stack trace. How do I fix "fatal error: non-Go code set up signal handler without SA_ONSTACK flag"?

Ethan Reesor
  • 2,090
  • 1
  • 23
  • 40
  • There might be some workaround, but from a high level point of view the two are just incompatible: libfuzzer needs to be the only code catching SIGSEGV, and the Go runtime needs to be the only code catching SIGSEGV. This is not possible simultaneously. – torek Sep 15 '22 at 05:14
  • The likely workaround is hinted-at in the `NOTE` above: perhaps libfuzzer isn't quite so adamant as all that, and there's a way to not have it be the (singular) SIGSEGV handler. But in general there can only be one SIGSEGV handler, and Go needs Go to be that handler. – torek Sep 15 '22 at 05:16
  • It's pretty clear that the existing libfuzz depends on some OS- and/or runtime-specific detail that doesn't match up between your own Go implementation and theirs. What detail that is, is not clear. – torek Sep 15 '22 at 05:19
  • Poking around a bit more, it looks like there should be some way to adapt this, but you'll probably want something that's not marked quite so experimental as the github link at the top of your post. – torek Sep 15 '22 at 05:36
  • The underlying cause is that go-118-fuzz-build does not handle `t.Skip()`. I was working on a fork of go-118-fuzz-build and I got a SIGSEGV that Go properly recognized as a nil pointer exception, with the correct stack trace. So either the conflict is triggered by something in Go's test runner, or it's related to GitLab's tooling, I think. – Ethan Reesor Sep 16 '22 at 03:45

0 Answers0