googleprojectzero / googleprojectzero/fuzzilli

Assertion failure in scheduleCorpusImport with --jobs>=2

Open
#551 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Swift
Stars
2.3k
Forks
367
Avg merge
23h 53m
Merged PRs (30d)
1

Description

Summary

Using --jobs=2 (or higher) with the v8Sandbox profile causes a crash due to an assertion failure at Fuzzer.swift:703:

assert(state == .uninitialized)

The child worker calls scheduleCorpusImport after the main fuzzer has already transitioned from .uninitialized to .corpusGeneration, violating the precondition.

Steps to Reproduce

FuzzilliCli   --profile=v8Sandbox   --storagePath=/opt/v8-fuzz   --overwrite   --timeout=500,1200   --corpus=markov   --jobs=2   --logLevel=info   /path/to/d8

Observed Behavior

Fuzzilli starts, completes corpus generation on the main instance, then crashes with:

Fuzzilli/Fuzzer.swift:703: Assertion failed

*** Signal 4: Backtracing from 0x7ee9132e2a30...

This occurs consistently within a few minutes of startup. --jobs=1 works fine. --jobs=2 and --jobs=4 both trigger the crash.

Expected Behavior

Multi-worker mode should work without assertion failures. The assertion at line 703 could be relaxed to allow corpus import during states other than .uninitialized, or the state transition should be synchronized so child workers don't race with the main fuzzer's initialization.

Environment

  • Commit: cbade79edaf1dae0c233890b7957f560008d2c63 (Apr 8, 2026)
  • Profile: v8Sandbox
  • Target: V8 d8 (built with v8_fuzzilli=true, v8_enable_sandbox=true, is_asan=true, sanitizer_coverage_flags="trace-pc-guard")
  • OS: Ubuntu 22.04, 4 cores, 8GB RAM
  • Swift: 6.1

Analysis

The comment at line 701-702 acknowledges this limitation:

// Currently we only allow corpus import when the fuzzer is still uninitialized.
// If necessary, this can be changed, but we'd need to be able to correctly handle
// the .waiting -> .corpusImport state transition.

In multi-worker mode, the main fuzzer transitions to .corpusGeneration before child workers have finished initializing. When a child worker then tries to synchronize its corpus with the main instance via scheduleCorpusImport, the assertion fails because the fuzzer is no longer in .uninitialized state.

A possible fix would be to either:

  1. Allow scheduleCorpusImport during .corpusGeneration / .fuzzing states
  2. Delay the main fuzzer's state transition until all workers have completed initialization
  3. Use a different synchronization path for child workers that doesn't go through scheduleCorpusImport

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in Fuzzer.swift around lines 701-703 and trace scheduleCorpusImport alongside the .uninitialized, .corpusGeneration, .waiting, and .fuzzing states. Run the provided v8Sandbox command with --jobs=1 and --jobs=2 to reproduce the difference, then verify that multi-worker startup completes without the assertion failure and that corpus import remains correct.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
testing-qa
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.