Apollo is a JIT compiler fuzzer for JavaScript engines (JSEs) based on Fuzzilli and CSX/JoNM. Apollo augments Fuzzilli with the capability to find mis-compilations, in addition to crashes. Given a set of seed JavaScript programs, Apollo generates a set of semantics-preserving mutants for equivalence validation over their program outputs. To this end, Apollo inserts a checksum value to each program generated by Fuzzilli.
The installation of Apollo is nothing more than building Fuzzilli. See building "Fuzzilli".
Apollo primarily works around the hybrjdon
engine.
To launch it, simply run:
$ swift run FuzzilliCli --engine=hybrjdon --profile=<jse_profile> /path/to/jse
Note that, Apollo differs from Fuzzilli in its JoNM (JIT-op Neutral Mutation)-based fuzzing engine named hybrjdon
.
Since Fuzzilli-generated programs do not produce output, hybrjdon
inserts a checksum variable along with update operations (such as addition, subtraction, multiplication, etc.) on that checksum variable before performing mutation.
hybrjdon
prints the final value of the checksum variable to stdout at the end of a sample's execution as its program output.
Additionally, rather than performing random mutation, hybrjdon
's mutators are JIT-op neutral, i.e., semantics-preserving as stated in the TOCS paper.
For each generated mutant, hybrjdon
checks whether the value of the inserted checksum variable is identical to that of the seed program.
It reports a mis-compilation for any checksum that differs, or a crash if the mutant leads to a crash.
Finally, Apollo periodically reverts to the jeneration
and the default mutation
engine to enhance the diversity of the seed corpus, where jeneration
is a generative engine similar to generation
but with some JIT templates.
In addition to hybrjdon
, there exist two simpler engines in Apollo, jitmut
and jonmut
, that can be enabled through the --engine
option.
Compared with hybrjdon
:
jonmut
never falls back tojeneration
andmutation
. It consistently mutating the same finite set of seed programs via JoNM without introducing new seeds and random mutation.jitmut
works likejonmut
deleting the insurance of preserving semantics when performing mutation.
Apollo is still a working-in-progress tool. Supporting mis-compilation via checksum is not that straightforward, although conceptually simple. This is because JavaScript is a programming language with dynamic types and treats functions as a first-class member. These features make it more frequent to produce programs with indeterministic behaviors, resulting from for example infinite recursion, implicit type-casting (or type coercion), prototype pollution, and checksum overflow among others, potentially breaking the the semantics-preserving requirement. To prevent these issues, Apollo enables some harsh policies such as disabling explicit generation of recursion functions. However, these policies are never complete and can still lead to false positives. Please use it at your own risk.
- For coding style, Apollo follows that of Fuzzilli.
- For technical contributions, please first navigate to our paper for technical details.
- For bugs/issues/questions/feature requests, please file an issue.
Apollo is initially a research work with the following TOCS 2025 paper. Please consider citing us if you used Apollo in your work!
@article{csx_tocs25,
author = {Li, Cong and Jiang, Yanyan and Xu, Chang and Su, Zhendong},
title = {Validating JIT Compilers via Compilation Space Exploration},
year = {2025},
note = {Just Accepted},
journal = {ACM Trans. Comput. Syst.},
month = feb
}
Apache License Version 2.0
- Fuzzilli (on which this project is based)
- Tiana Xing (who sketches the logo)