SOURCE ARCHIVE
EXTRACTED CONTENT
115,973 chars Guiding Greybox Fuzzing with Mutation Testing
Vasudev Vikram Isabella Laybourn Ao Li
Carnegie Mellon University Carnegie Mellon University Carnegie Mellon University Pittsburgh, PA, USA Pittsburgh, PA, USA Pittsburgh, PA, USA vasumv@cmu.edu ilaybour@andrew.cmu.edu aoli@cmu.edu
Nicole Nair Kelton OBrien Rafaello Sanna
Swarthmore College University of Minnesota University of Rochester
Swarthmore, PA, USA Minneapolis, MN, USA Rochester, NY, USA nnair1@swarthmore.edu obri0707@umn.edu rsanna@u.rochester.edu Rohan Padhye Carnegie Mellon University Pittsburgh, PA, USA rohanpadhye@cmu.edu ABSTRACT ACM Reference Format: Greybox fuzzing and mutation testing are two popular but mostly Vasudev Vikram, Isabella Laybourn, Ao Li, Nicole Nair, Kelton OBrien, independent fields of software testing research that have so far Rafaello Sanna, and Rohan Padhye. 2023. Guiding Greybox Fuzzing with had limited overlap. Greybox fuzzing, generally geared towards Mutation Testing. In Proceedings of the 32nd ACM SIGSOFT International searching for new bugs, predominantly uses code coverage for Symposium on Software Testing and Analysis (ISSTA ’23), July 17–21, 2023, selecting inputs to save. Mutation testing is primarily used as a Seattle, WA, USA. ACM, New York, NY, USA, 13 pages. https://doi.org/10. stronger alternative to code coverage in assessing the quality of 1145/3597926.3598107 regression tests; the idea is to evaluate tests for their ability to 1 identify artificially injected faults in the target program. But what INTRODUCTION if we wanted to use greybox fuzzing to synthesize high-quality Greybox fuzzing [9, 49, 52, 81] and coverage-guided property test- regression tests? ing [44, 58] have become increasingly popular for automated testing. In this paper, we develop and evaluate Mu2, a Java-based frame- Their key idea is to evolve a corpus of test inputs via an evolutionary work for incorporating mutation analysis in the greybox fuzzing search that maximizes code coverage: in each iteration, a new input loop, with the goal of producing a test-input corpus with a high mu- is synthesized by randomly mutating an existing input from the cor- tation score. Mu2 makes use of a differential oracle for identifying pus. The mutated input is added to the corpus if the corresponding inputs that exercise interesting program behavior without causing execution of the test program increases code coverage. crashes. This paper describes several dynamic optimizations imple- Fuzzing is traditionally used to discover inputs that crash pro- mented in Mu2 to overcome the high cost of performing mutation grams and reveal security vulnerabilities [5, 11, 14, 20, 25, 42, 50, analysis with every fuzzer-generated input. These optimizations 54, 59, 68]. In the absence of new bugs, fuzzers are evaluated based introduce trade-offs in fuzzing throughput and mutation killing on code coverage achieved during the fuzzing campaign [10, 48]. ability, which we evaluate empirically on five real-world Java bench- However, in the vast majority of fuzzing research, the end goal is marks. Overall, variants of Mu2 are able to synthesize test-input to find bugs in the moment [42]; not much attention is paid to the corpora with a higher mutation score than state-of-the-art Java inputs saved along the way. fuzzer Zest. In this paper, we explicitly focus on the quality of the test-input corpus produced at the end of a fuzzing campaign. Such a corpus CCS CONCEPTS can be used for continuous regression testing during subsequent • Software and its engineering → Software testing and debug- program development. This practice is recommended by Google’s ging. OSS-Fuzz [28], and is already adopted by some mature projects. For example, in SQLite, “Historical test cases from AFL, OSS Fuzz, and KEYWORDS dbsqlfuzz are collected [...] and then rerun by the fuzzcheck utility fuzz testing, mutation testing, test generation program whenever one runs make test” [71]. Similarly, OpenSSL uses several distinct fuzzer-generated corpora and their correspond- Permission to make digital or hard copies of part or all of this work for personal or ing fuzz drivers for continuous testing [72]. Even though these test classroom use is granted without fee provided that copies are not made or distributed corpora are used for regression testing, the only metric being tar- for profit or commercial advantage and that copies bear this notice and the full citation This work is licensed under a Creative Commons Attribution 4.0 Interna- geted by conventional greybox fuzzers is code coverage. However, on the first page. Copyrights for third-party components of this work must be honored. tional License. coverage alone is not the necessarily the strongest predictor of fault For all other uses, contact the owner/author(s). ©ISSTA ’23, July 17–21, 2023, Seattle, WA, USA detection ability [15, 36]. 2023 Copyright held by the owner/author(s). Now, the technique of mutation testing [19], which evaluates the ACM ISBN 979-8-4007-0221-1/23/07. https://doi.org/10.1145/3597926.3598107 ability of tests to catch artificially injected bugs (a.k.a. mutation
929
ISSTA ’23, July 17–21, 2023, Seale, WA, USA Vasudev Vikram, Isabella Laybourn, Ao Li, Nicole Nair, Kelton OBrien, Rafaello Sanna, and Rohan Padhye
Seeds (Program Mu2 employing different strategies for improving performance. Our
Input
930
Guiding Greybox Fuzzing with Mutation Testing ISSTA ’23, July 17–21, 2023, Seale, WA, USA
Algorithm 1 Coverage-guided greybox fuzzing 𝑃 (𝑥 ) = 𝑃 ′(𝑥 ). Similar to code coverage—where 100% may not be 1: procedure CGF(Program 𝑃 , Set of inputs seeds, Budget 𝑇 ) achievable due to unreachable code—the best use of the adequacy 2: corpus ← seeds ⊲ Initialize saved inputs score is as a relative measurement rather than an absolute one. 3: repeat ⊲ Fuzzing loop One of the most mature and actively developed mutation testing 4: 𝑥 ← PickInput(corpus) ⊲ Sample using heuristics frameworks, PIT [17], targets Java programs by mutating JVM 5: 𝑥′ ← MutateInput(𝑥 ) ⊲ Synthesize new input bytecode. PIT’s default mutation operators include: 6:7: if running 𝑃 (𝑥′ ) leads to a crash then • Conditional boundary mutator (e.g., a<b to a<=b)) coverage(𝑃, 𝑥′ ) ⊈ 𝑥 ∈corpus coverage(𝑃, 𝑥 ) then 8: if raise 𝑥′ Ð ⊲ Bug found! • Increments mutator (e.g., a++ to a--) 9: corpus ← corpus ∪ 𝑥′ •• Invert negatives (e.g., -a to a) 10: until budget 𝑇 Math mutators (e.g., a+b to a*b) 11: return corpus ⊲ Final corpus • Negate conditionals (e.g., a==b to a!=b) • Return values mutator (e.g., replacing operands in return statements with a constant such as null, 0, 1, false, etc. If the execution of any synthesized input 𝑥 ′ causes the program to depending on type). crash, then a bug is reported (Line 7). The fuzzing loop continues 3 until a user-provided resource budget 𝑇 runs out (Line 10), where MUTATION-ANALYSIS-GUIDED FUZZING this budget may be in terms of the number of fuzzing trials (i.e., 3.1 Problem Statement and Scope iterations of the fuzzing loop) or in terms of wall-clock time. The In this paper, we focus on the following problem: corpus of fuzzer-synthesized test inputs is finally returned (Line 11) Can we use mutation analysis to guide greybox fuzzing in order and may be used either as a regression test suite, for seeding future to synthesize a test-input corpus with high mutation score? fuzzing campaigns, or for other applications [28, 55, 71, 72, 75]. The quality of the final test-input corpus is often evaluated using code Recently, Gopinath et al. [31] have identified and discussed sev- coverage [10, 42], though mutation scores—which we describe in eral challenges of combining mutation analysis with fuzzing, in- the next section—have also been used [75]. cluding (1) the strength of oracles used by the fuzzer, (2) the compu- 2.2 Mutation Testing tational expense of performing mutation analysis, (3) dealing with equivalent mutants, and (4) the lack of mutation testing frameworks Mutation testing (also known as a mutation analysis) is a method- that focus on fuzzers. We directly address such challenges in this ology for assessing the adequacy of a set of tests using artificially paper. Oracles are discussed in Section 3.3 and performance con- injected “bugs”, or program mutants [19, 37]. In assessing test ade- cerns in Section 3.4. Our evaluation is not dependent on identifying quacy [27], we are given a program 𝑃 and a suite of passing tests equivalent mutants, since we only care about relative mutation 𝑋 . The goal is to evaluate the quality of 𝑋 by computing a score scores (higher=better) rather than the exact number of mutants that grows monotonically [79] with additions to the set 𝑋 . Code killed by a test-input corpus. Section 3.4.2 deals with reducing the coverage is an example of a test adequacy criteria. performance impact of equivalent mutations. In mutation testing, a set of program mutants, say Mutants(𝑃 ), is first generated. Each mutant 𝑃 ′ ∈ Mutants(𝑃 ) is a program that Scope. Since there is a vast amount of literature on the many differs from 𝑃 in a very small way. Most commonly, mutations are variables involved in mutation analysis, as surveyed by Papadakis replacements of program expressions. For example, an expression et al. [63], we restrict ourselves in this paper to investigating only a+b at line 42 in 𝑃 may be replaced with the expression a-b. We the aspects of combining mutation analysis with greybox fuzzing. can use the notation ⟨𝑃, a+b, a-b, 42⟩ to refer to this mutation. For In particular, we (1) work with the assumption that a high muta- purposes of this paper, we use the notation: tion score is a desirable property of a test-input corpus used for 𝑃 ′ = ⟨𝑃, 𝑒, 𝑒′, 𝑛⟩ regression testing, referring the reader to several empirical stud- ies examining the relationship between mutation scores and real to refer to a program mutant 𝑃 ′ as a modification of program 𝑃 faults [2, 12, 15, 32, 39, 41, 64], and (2) directly use the default set of where expression 𝑒 is replaced with 𝑒′ at program location 𝑛. The mutation operators provided by PIT (ref. Section 2.2), which have main idea is that a program mutation simulates a simple program- been chosen based on several empirical studies of effectiveness, mer error or an artificially injected “bug”. sufficiency, and to align with developer expectations [1, 17, 45, 57]. The test suite 𝑋 is then run on each mutant 𝑃 ′. If some test 𝑥 ∈ 𝑋 fails when run on mutant 𝑃 ′, then the mutant 𝑃 ′ is said to be killed, 3.2 The Mu2 Framework which we denote as Kills(𝑃 ′, 𝑥). If the test suite 𝑋 still passes, then To address our problem statement, we present the mutation- the mutant 𝑃 ′ is said to survive. analysis-guided greybox fuzzing technique in Algorithm 2. This Ideally, we want our tests to be able to identify “bugs” and so we is an extension of Alg. 1, with changes highlighted in grey. The hope to have tests that fail on each mutant 𝑃 ′. So, the adequacy of key additions of this algorithm are in evaluating whether a fuzzer- test suite 𝑋 is defined by the mutation score, which is computed as generated input 𝑥 ′ should be saved to the corpus. The function the fraction of mutants killed: | {𝑃′∈Mutants| (𝑃 ) | ∃𝑥 ∈𝑋:kills(𝑃′,𝑥 ) } | . Mutants(𝑃 ) | ProgMuts2Run (Line 8) returns a set of program mutants to eval- In general, a mutation score of 100% is rarely achievable because uate with input 𝑥 ′. For now, assume it to return Mutants(P) as some mutants 𝑃 ′ may actually be equivalent to 𝑃 —that is, ∀𝑥 : defined in Section 2.2, though we will refine this in Section 3.4.2.
931
ISSTA ’23, July 17–21, 2023, Seale, WA, USA Vasudev Vikram, Isabella Laybourn, Ao Li, Nicole Nair, Kelton OBrien, Rafaello Sanna, and Rohan Padhye
Algorithm 2 Mutation-analysis-guided fuzzing. Changes to Alg. 1 1 class Sort {
are highlighted. 2 static int[] insertionSort(int[] arr) {
1: procedure Mu2 (Program 𝑃 , Set of inputs seeds, Budget 𝑇 ) 3 for (int j = 1; j < arr.length; j++) {
2: corpus ← seeds 4 int key = arr[j], i = j-1;
5 while (i >= 0 && // P'2 changes >= to >
3: repeat 6 key < arr[i]) {
4: 𝑥 ← PickInput(corpus) 7 arr[i+1] = arr[i]; // P'3 sets RHS to 1
5: 𝑥′ ← MutateInput(𝑥Ð) 8 i = i-1; // P'4 removes -1
6: if coverage(𝑃, 𝑥′ ) ⊈ 𝑥 ∈corpus coverage(𝑃, 𝑥 ) then 9 }
7: corpus ← corpus ∪ 𝑥′ 10 arr[i+1] = key; // P'1 removes +1
8: for all 𝑃 ′ ∈ ProgMuts2Run(𝑃, corpus, 𝑥′ ) do 11 }}} return arr;
9: if kills(𝑃 ′, 𝑥′ ) ∧ 𝑃 ′ ∉ killed(𝑃, corpus) then 12
10: corpus ← corpus ∪ 𝑥′ Figure 2: Java program that implements insertion sort, anno-
11: until budget 𝑇
12: return corpus tated with four sample program mutants.
13: function killed(Program 𝑃 , Set of inputs X)
14: return {𝑃 ′ | 𝑃 ′ ∈ Mutants(𝑃 ) ∧ ∃𝑥 ∈ X : kills(𝑃 ′, 𝑥 ) } defined in Figure 2 and the following test method, which is written
in the property-testing style using JQF’s @Fuzz annotation:
1 @Fuzz // Inputs generated using greybox fuzzing
We then determine whether the input 𝑥 ′ is the first input to kill 2 void fuzzInsertionSort(int[] input) {
some mutant 𝑃 ′. If 𝑃 ′ is killed by 𝑥 ′ and 𝑃 ′ has not previously been 3 } assert(isSorted(Sort.insertionSort(input)));
4
killed by any input in the corpus (Lines 9 and 14), then we add 𝑥 ′ to For Mu2, we could use this property test as an oracle. Con-
the corpus (Line 10). Broadly, this algorithm saves fuzzer-generated sider the following examples, using the notation introduced in
inputs if they increase either code coverage or mutation score. Addi- Section 2.2: executing mutant 𝑃 ′ = ⟨Sort, i+1, i, 10⟩ with
tionally, inputs that increase mutation score are marked as favored, 1
giving them more energy to be picked for fuzzing (Line 4). As be- input array 𝑥 = [3, 2, 1] would result in an uncaught
fore, the final corpus of fuzzer-generated inputs is returned as the IndexOutOfBoundsException (-1) on line 10, triggering
result (Line 12). a failure via the implicit oracle. Additionally, executing 𝑃2′ =
We have implemented Algorithm 2 for fuzzing Java programs by ⟨Sort, i>=0, i>0, 5⟩ with 𝑥 would result in an assertion failure in
integrating PIT [17] into JQF [58]. We call this system Mu2, since it the property test because the result of 𝑃2′(𝑥 ) would be the array [3,
combines Mutation-based Greybox Fuzzing with Mutation Testing. 1, 2], which is not sorted. So, both mutants 𝑃1′ and 𝑃2′ would get
We chose PIT and JQF because of their maturity, extensibility, killed by the fuzzer if it discovers such an input.
and their common target platform. As described in Section 2.2, PIT Unfortunately, the property test is not a complete oracle in that
is an actively developed mutation testing framework that operates it does not fully specify the expected behavior of the sort function.
on JVM bytecode. The JQF framework [58] was originally designed Consider a third mutant 𝑃3′ = ⟨Sort, arr[i], 1, 7⟩, which assigns
for coverage-guided property-based testing, which is a structure- a constant to every array element at line 7. This is clearly a bug in
aware variant of greybox fuzzing (ref. Section 2.1) and instruments insertion sort, yet the output is always sorted. For example, when= 𝑥
JVM bytecode for collecting code coverage. JQF also has a highly [3, 2, 1], the result of 𝑃3′(𝑥 ) is [1, 1, 1]. Such a mutant
extensible design for creating pluggable guidances, which supports would incorrectly survive on any input the fuzzer generates.
rapid prototyping of new fuzzing algorithms [43, 55, 56, 59, 69, 75, Writing a complete oracle for testing insertion sort is possible,
83]. but quite cumbersome. In general, this is a hard problem [6]. For
In Mu2, Mutants(𝑃 ) includes all of PIT’s default expression many applications, a complete oracle would need to be as complex
mutation operators (ref. Sections 2.2 and 3.1). For heuristics such as (or in some cases exactly the same) as the original program itself.
PickInput and MutateInput, Mu2 reuses the logic and code from In Mu2, we use the well-known concept of differential testing
Zest [59], which we also use as a baseline for evaluation (Section 4). to define our oracle. In differential testing [21, 53], different im-
plementations of a program that are expected to satisfy the same
3.3 Oracle: Differential Mutation Testing specification are executed on a single input, and their results are
compared to identify discrepancies. In Mu2, our different "imple-
One challenge of mutation-analysis-guided fuzzing is determining mentations" are the original program and program mutants; any
whether a program mutant is killed by a particular input. This discrepancy between the original program output and a mutant’s
corresponds to the kills function invoked in line 9 of Algorithm 2. output leads to that mutant being killed.
In mutation testing, a program mutant 𝑃 ′ is considered killed if To support the comparison of outputs, we create a differential
any test in the test suite fails. The logic that determines whether a mutation testing framework. This allows for (1) output values to
test passes or fails is known as the test oracle. be returned from a fuzzing driver (as opposed to the void returns
Greybox fuzzing generally relies on implicit oracles, which aim used by conventional property testing methods) and (2) a user-
to detect anomalous behavior such as crashes or uncaught excep- defined comparison function for specifying how outputs from the
tions, or property tests, which assert a predicate over the output of original program and a program mutant should be compared. An
some computation. For example, consider the insertion sort method example of differential mutation testing methods in our framework
932
Guiding Greybox Fuzzing with Mutation Testing ISSTA ’23, July 17–21, 2023, Seale, WA, USA
1 @Diff // inputs generated by Mu2 Table 1: Geometric mean of speedups achieved by the execu-
2 int[] runInsertionSort(int[] input) { tion and infection based optimizations (Alg. 3, Line 4) from
3 return Sort.insertionSort(input); the PIE model [38] across 10 repetitions of 3 hours each1.
4 }
5 @Compare // outputs compared with mutant
6 boolean checkEq(int[] outOrig, int[] outMut) { Mean Speedup From: Execution Opt. Infection Opt.
7 return Arrays.equals(outOrig, outMut); ChocoPy 3.6× 7.4×
8 } Gson 18.2× 23.2×
Jackson 60.5× 77.4×
Figure 3: A Mu2 differential mutation test driver and com- Tomcat 13.6× 23.8×
parison method for the insertionSort method (Fig. 2).
Algorithm 3 Logic for determining which mutants to run in a
is shown in Figure 3. The @Diff method runInsertionSort given iteration of the fuzzing loop (Alg. 2)
returns an output value of type int[]. The user-defined com- 1: function ProgMuts2Run(Program 𝑃 , Old inputs corpus, New input 𝑥)
parison method checkEq simply determines if the output ar- 2: surviving ← mutants(𝑃 ) \ killed(𝑃, corpus)
rays are equal. If unspecified, the @Compare function defaults to 3: killable ← {𝑃 ′ = ⟨𝑃, 𝑒, 𝑒′, 𝑛⟩ | (𝑃 ′ ∈ surviving) ∧
the java.lang.Objects.equals() method. Our interface 4: (𝑛 ∈ coverage(𝑃, 𝑥 ) ) ∧ (infect(𝑃, 𝑒, 𝑒′, 𝑥 ) ) }
is general enough to support complex differential testing oracles 5: if AGGRESSIVE_OPT is configured then
such as the ones used in CSmith [80]. 6: return filter (killable, AGGRESSIVE_OPT )
With differential mutation testing, we are able to kill mutants 7: return killable
such as 𝑃3′ described above with an input like [3, 2, 1], where
the output of insertionSort on the original program—[1, 2, methods are expected to be self-contained and not depend on global
3]—is not equal to the output of the mutant—[1, 1, 1]. state. Like JQF and Zest, Mu2 is designed to work in a single JVM.
We can now precisely define Kills(𝑃 ′, 𝑥) which was referenced Mu2 thus adopts a different strategy than PIT and takes advan-
in Algorithm 2. Given a mutant 𝑃 ′ = ⟨𝑃, 𝑒, 𝑒′, 𝑛⟩ and an input 𝑥 , tage of the Java class-loader mechanism to load and run program
Kills(𝑃 ′, 𝑥) returns true iff: mutants within the same JVM, essentially by having copies of the
(1) 𝑃 (𝑥 ) = ~ ∧ 𝑃 ′(𝑥 ) = ′ ∧ ¬Compare(, ~′), where Compare entire class hierarchy (one per mutant) in memory at the same time.
is the user-defined @Compare method (e.g., checkEq in Fig- First, a CoverageClassLoader (CCL) is responsible for loading
ure 3) or Object.equals() if one is not defined; or the original target program 𝑃 and collecting code coverage using
(2) 𝑃 (𝑥 ) = ~ but executing 𝑃 ′(𝑥 ) results in an uncaught run-time on-the-fly instrumentation. For differential testing, the CCL-loaded
exception being thrown; or classes compute the ground-truth outcome 𝑃 (𝑥 ). Second, a family
(3) Executing 𝑃 ′(𝑥 ) takes longer than a predefined TIMEOUT. of MutationClassLoaders (MCL) are used to load program
The timeout is required for killing mutants such as 𝑃4′ = mutants; one MCL per mutant 𝑃 ′ = ⟨𝑃, 𝑒, 𝑒′, 𝑛⟩. When a mutant
⟨Sort, i-1, i, 8⟩, which effectively removes the decrement of i, test program is loaded by the MCL, it performs on-the-fly bytecode
leading to an infinite loop on the input [3, 1, 2]. instrumentation exactly at location 𝑛, replacing expression 𝑒 with
We evaluate the improvement in completeness using the differ- 𝑒′ and loading the rest of the program without changing semantics.
ential oracle over the greybox fuzzing implicit oracle in Section 4.4. The MCL adds instrumentation at backward jumps (i.e., loops) in
order to detect timeouts and exit test execution cleanly if necessary.
3.4 Performance Further, assuming that fuzz tests do not affect global state, Mu2
The biggest challenge with incorporating mutation testing inside loads only one copy of each library class (defined as classes outside
a fuzzing loop is performance. Given its need to execute many a specified package identifying the target application as long as they
mutants on each iteration, mutation testing is in general a very and their transitive dependencies do not reference any application
expensive technique [63], so scaling Mu2 to real-world software class) using a common SharedClassLoader—this dramatically
is a non-trivial task. Two aspects of improving scalability are: (1) reduces memory pressure when mutating large programs.
reducing the average time required to execute each program mutant, To validate our design, we ran an informal preliminary exper-
and (2) reducing the number of program mutants that must be iment of performing mutation analysis with PIT and Mu2’s in-
evaluated at each iteration of the fuzzing loop. memory set-up on a fixed corpus of seed inputs for the Google
3.4.1 Improving Performance of Mutant Execution. When running Closure Compiler [30]. In the steady state (after the first 8 inputs),
a mutation testing tool such as PIT [17], each mutant and test is run Mu2’s in-memory analysis runs with a 9.6× speed-up over PIT.
in a different JVM. For general mutation testing, this is ideal because 3.4.2 Reducing the Number of Mutants to Run in the Fuzzing Loop.
it simplifies managing multiple copies of the same program (sans For each trial—i.e., iteration of the fuzzing loop—(1) the input must
mutations), and prevents global state changes from one program be executed once by the original program and (2) the input must
mutant affecting the state of another program mutant. However, be executed by each mutant. Thus, we can model the time required
this is not necessary for Mu2. For in-process fuzzing, test driver to execute each trial as the following:
1The Closure Compiler benchmark was too large to run without the execution and trialTime = timeorig + 𝑀 ∗ avgTimemut (1)
infection optimizations, so we did not include the speedups in this table. where 𝑀 = |ProgMuts2Run(𝑃, corpus, 𝑥)| as per Algorithm 2.
933
ISSTA ’23, July 17–21, 2023, Seale, WA, USA Vasudev Vikram, Isabella Laybourn, Ao Li, Nicole Nair, Kelton OBrien, Rafaello Sanna, and Rohan Padhye
Observe that the time per trial scales linearly with 𝑀. We can fuzzing campaign. This is a novel reduction strategy designed
improve the fuzzing throughput (i.e., the number of trials executed specifically for the fuzzing loop.
per unit time) directly by reducing 𝑀. From Algorithm 2 (Lines 9– Section 4.2 evaluates the impact of these aggressive optimizations.
10), we can see that we only care about executing a program mutant
if it will help us determine if a given input is the first input to kill it. 4
We can therefore reduce 𝑀 by dynamically pruning mutants whose EVALUATION
execution will necessarily lead to Line 9 evaluating to false. We evaluate Mu2 on 5 different Java program benchmarks, using
So, we begin by applying the following conditions for a given state-of-the-art coverage-guided fuzzer Zest [59] as the baseline.
𝑃 ′ = ⟨𝑃, 𝑒, 𝑒′, 𝑛⟩, which are shown in Algorithm 3, lines 2–4: We structure our evaluation around four research questions:
RQ1: Does mutation-analysis guidance produce a higher quality
(1) If 𝑃 ′ ∈ killed(𝑃, corpus), then 𝑃 ′ does not need to be exe- test-input corpus than coverage-only feedback in greybox fuzzing?
cuted for any future inputs. RQ2: How do the performance optimizations impact the quality of
(2) If the program mutant 𝑃 ′ applies a mutation to a program the test-input corpus produced by mutation-analysis guidance?
location 𝑛, but 𝑛 is not covered when executing the original RQ3: How does the reliability of killing nontrivial mutants differ
program on 𝑥 , then 𝑃 ′ cannot be killed by 𝑥 . This corresponds between mutation-analysis guidance and coverage guidance?
to execution-based pruning in the PIE model [38]. RQ4: How much stronger is the differential mutation testing oracle
(3) If we can guarantee that all dynamic evaluations of 𝑒 during than the implicit oracle?
the execution of 𝑃 on 𝑥 are equivalent to the corresponding Benchmarks. We consider five real-world Java programs:2
evaluations of mutated expression 𝑒′, then 𝑃 ′ cannot be
killed by 𝑥 . This corresponds to infection-based pruning in (1) ChocoPy [7, 61] reference compiler (6K LoC): The test driver
the PIE model [38], which we implemented as a dynamic (reused from [75]) reads in a program in ChocoPy (a statically
analysis of the execution of the original program 𝑃 (𝑥 ). typed dialect of Python) and runs the semantic analysis stage
of the ChocoPy reference compiler to return a type-checked
The last two strategies from the PIE model require additional over- AST object.
head when executing 𝑥 : (1) the execution-based pruning depends on (2) Gson [29] JSON Parser (26K LoC): The test driver parses a
coverage instrumentation, and (2) infection-based pruning requires input JSON string and returns a Java object output.
evaluating and comparing the mutation expression 𝑒 each time (3) Jackson [22] JSON Parser (49K LoC): The test driver acts
that it is executed by 𝑥 . Referring to Equation 1, the optimization similar to that of Gson.
results in a trade-off for trialTime due to the increase in timeorig (4) Apache Tomcat [3] WebXML Parser (10K LoC): The test
and decrease in the number of mutants to run 𝑀. However, we find driver parses a string input and returns the WebXML repre-
this is quite beneficial overall. Table 1 shows the results of prelim- sentation of the parsed output.
inary experiments on 4 benchmarks included in our evaluations (5) Google Closure Compiler [30] (~250K LoC): The test driver
in Section 4 to validate these optimizations; clearly, they improve (reused from [59] and [75]) takes in a JavaScript program
performance significantly. and performs source-to-source optimizations. It then returns
We note that all the pruning methods mentioned above are sound the optimized JavaScript code.
optimizations: a mutant is pruned only if it is guaranteed to sur- Mutation selection. Following previous work on semantic
vive when executed. Effectively, we are pruning mutants that are fuzzing [59, 75], we filter on package names to identify classes
equivalent modulo inputs [47]. relating to the core logic of the program under test. The mutation
3.4.3 Aggressive Mutant Selection Optimizations. While the execu- operators are then applied on these classes. We use the same gen-
tion and infection optimizations significantly improve the overall erators, oracles, and filters for both Zest and Mu2. All of the test
throughput of Mu2, the 𝑀 factor in Equation 1 still grows linearly drivers return objects that override Object.equals, and were
with the size of the program (more code = more mutants). We can thus properly compared by the differential oracle.
be aggressive about reducing 𝑀 by attempting to bound it by a Duration. Following best practices [42], we use a time bound of
constant 𝑘 , at the risk of potentially missing out on analyzing some 24 hours for each experiment.
mutants that could have been killed by a given input. We call these
aggressive optimizations. We use the function filter in Algorithm 3 Repetitions. To account for the randomness in fuzzing, we run
(Line 6) to optionally apply a selection strategy [66, 73] that returns each experiment 20 times and report statistics.
a bounded subset of the killable mutants. We have implemented Metrics. For our evaluations, we compute the branch coverage
two types of filters in Mu2: and mutation scores across each fuzzer-generated test-input corpus.
(1) 𝑘 -Random Mutant Filter: For each generated input, 𝑘 mutants We report mutation scores as the absolute number of mutants killed
are randomly sampled from the killable set in Alg. 3. instead of as a fraction (ref. Section 2.2), since we only care about
(2) 𝑘 -Least-Executed Mutant Filter: For each generated input, comparing these numbers across fuzzing variants, and since the
the killable mutants are sorted by the number of times they denominator is meaningless when considering a single test entry
have been executed on previous inputs. The first 𝑘 mutants point. We additionally compute the kill frequency of each of the
are then selected. The goal is to prioritize executing mutants 2
that have not been tested as frequently during the fuzzing While we note lines of code (LoC) for completeness, only a fraction of this code is
reachable from fuzz drivers. Fig. 5 indicates actual code coverage.
934
Guiding Greybox Fuzzing with Mutation Testing ISSTA ’23, July 17–21, 2023, Seale, WA, USA
ChocoPy Gson Jackson Tomcat Closure
290 310 400 270
285 300 380 235 260
280 290 360 230 250
240
275 280 340 225 230
270
Zest Mu2- Mu2- Mu2- Zest Mu2- Mu2- Mu2- Zest Mu2- Mu2- Mu2- Zest Mu2- Mu2- Mu2- Zest Mu2- Mu2- Mu2-
Default Split OPT Default Split OPT Default Split OPT Default Split OPT Default Split OPT
Figure 4: Box plots showing the number of killed mutants by Zest and Mu2-generated test corpora across 20 repetitions of
24-hour fuzzing campaigns (higher is better). Mu2-Split and Mu2-OPT are two variants of Mu2 detailed in Section 4.1.
Branch Coverage significant increases in all three. Additionally, Figure 5 shows equiv-
1.00 alent branch coverage between Zest and Mu2 for these benchmarks.
For the Tomcat WebXML parser, the number of killed mutants
0.75 saturated at 239 in almost all of the repetitions of the fuzzing cam-
paigns. For the Closure Compiler, our largest benchmark, the Mu2-
0.50 Zest Default corpora achieve, on average, approximately 17% less branch
Mu2-Split performance overhead of running mutation analysis for a large
0.25 Mu2-Default coverage than Zest (shown in Figure 5). This is likely due to the
0.00 Mu2-OPT benchmark, and also likely accounts for the Zest corpora on aver-
ChocoPy Gson Jackson Tomcat Closure age killing 12 more mutants than Mu2-Default, as covering code is a
(4856) (645) (2217) (990) (30792) necessary condition for killing mutants in that part of the code. This
Benchmark suggests Mu2-Default may not scale well to very large programs.
Figure 5: Branch coverage across all benchmarks normal- One way to mitigate this slowdown is to add mutation-analysis
ized to the mean coverage achieved by Zest. The number of feedback to coverage-guided fuzzing later in the campaign. The
branches covered by Zest (used to normalize) is listed below Mu2-Split variant utilizes coverage-only feedback for the first half
each target. Error bars represent 95% confidence intervals. of the campaign (which is very efficient) and then introduces ex-
pensive mutation-analysis feedback for the second half. This is
based on an idea by Gopinath et al. [31], who suggested saturating
nontrivial mutants across the repetitions. When reporting statistical coverage before adding mutation analysis to the fuzzing loop. The
significance, a Mann-Whitney-U test was performed with 𝛼 = 0.05. Mu2-Split-generated corpora show statistically significant increases
in mutation score over Zest for the first 4 benchmarks (Fig. 4), al-
Default variant. Unless explicitly qualified with an aggressive though the effect for Tomcat is very small. There is also a major
optimization strategy, the default variant of Mu2 used in our evalu- improvement over Mu2-Default in the Closure benchmark; Mu2-
ation only uses sound optimizations described in Section 3.4.2. Split is able to bridge the gap in coverage (Fig. 5) and mutation
Reproducibility and Data Availability. We have published a repli- scores (Fig. 4) that Mu2-Default had with the Zest baseline.
cation package and evaluation data at: https://doi.org/10.5281/ Another method of scaling Mu2 is to apply the aggressive opti-
zenodo.7647828. The evaluation data contains logs of fuzzing cam- mizations detailed in Section 3.4.3. Mu2-OPT is a particular vari-
paigns used to generate all evaluation figures and tables [74]. ant we chose that applies the k-Least-Executed filter with 𝑘 = 10
mutants. The Mu2-OPT generated corpus similarly achieves sta-
4.1 RQ1: Test-Input Corpus Quality tistically significant increases in mutation scores across the first
Does mutation-analysis guidance produce a higher quality test- four benchmarks over Zest, with up to 20% increase in the Jackson
input corpus than coverage-only feedback in greybox fuzzing? JSON parser (Fig. 4). There is no significant difference between the
mutation scores of Mu2-OPT and Zest on the Closure Compiler.
RQ1 focuses on evaluating mutation-analysis-guided fuzzing Mu2-OPT achieves slightly less coverage than Zest on two bench-
with a fixed time budget. Higher mutation score from the Mu2- marks (ChocoPy and Closure) and more on one (Jackson)—however,
produced corpus and comparable coverage results would demon- the differences are fairly small (below 2%).
strate that mutation-analysis can be used as an off-the-shelf re- We are also curious about whether the additional saving of
placement for coverage-only guidance. We first discuss results for mutant-killing inputs in Mu2 may bloat the size of the generated
Mu2-Default, then evaluate two variants against the Zest baseline. test-input corpus, impacting its use in regression testing. Table 2
Figure 4 visualizes the mutation scores for each fuzzer-generated displays the average sizes and runtimes for each fuzzer-generated
corpus. The default mutation-analysis guidance (Mu2-Default) is corpus and show that no such bloat occurs in Mu2. While there
able to produce a corpus with higher mutation scores than coverage- are some differences in the number of test inputs, the runtime of
only feedback in the first three benchmarks, achieving statistically the Mu2-produced corpora are not significantly higher than those
935
Coverage Relative to Zest Killed Mutants
ISSTA ’23, July 17–21, 2023, Seale, WA, USA Vasudev Vikram, Isabella Laybourn, Ao Li, Nicole Nair, Kelton OBrien, Rafaello Sanna, and Rohan Padhye
Table 2: Average number of test inputs (and average runtime, ChocoPy Gson
in parentheses below) of fuzzer-generated corpora. Corre-
sponding standard deviations also listed. 290 300
Zest Mu2- Mu2- Mu2- 285 290
Default Split OPT
ChocoPy 864 ± 34 711 ± 47 725 ± 36 746 ± 40 280 280
(18.6 s ± 2.1 s) (9.8 s ± 0.8 s) (11.7 s ± 1.3 s) (10.4 s ± 1.0 s)
Gson 467 ± 18 461 ± 17 469 ± 15 489 ± 21 Jackson Tomcat
(1.7 s ± 0.1 s) (1.7 s ± 0.1 s) (1.7 s ± 0.0 s) (1.7 s ± 0.0 s) 407.5
Jackson 598 ± 19 655 ± 16 641 ± 19 673 ± 15 405.0 235
(2.4 s ± 0.1 s) (2.4 s ± 0.1 s) (2.4 s ± 0.0 s) (2.4 s ± 0.1 s)
Tomcat 138 ± 7 122 ± 6 136 ± 6 171 ± 5 402.5
(2.6 s ± 0.1 s) (2.5 s ± 0.1 s) (2.6 s ± 0.1 s) (2.7 s ± 0.1 s) 400.0 230
Closure 4885 ± 205 1075 ± 219 4044 ± 146 4037 ± 192 397.5
(554 s ± 82 s) (58 s ± 13 s) (360 s ± 27 s) (353 s ± 30 s) 395.0 225
392.5
Closure
Table 3: Geometric mean of speedups achieved by each ag-
gressively filtered variant of Mu2 over Mu2-Default. 20/10/5 280 Variant (in order)
refer to the sizes of the filtered subset of mutants. 270 Mu2-Default
290
260 Mu2-Random-20
LeastExecuted (20/10/5) 250 Mu2-LeastExecuted-20
Random (20/10/5) 285 Mu2-Random-10
ChocoPy 1.1/1.7/2.8× 1.1/1.6/2.5× 240 Mu2-LeastExecuted-10
Gson 0.9/1.1/1.3× 1.0/1.2/1.3× 230 Mu2-Random-5
280 Mu2-LeastExecuted-5
Jackson 1.0/1.1/1.3× 1.1/1.0/1.2×
Tomcat 3.4/3.5/8.2× 2.3/6.0/7.9× Figure 6: Box plots showing number of killed mutants by
Closure 10.4/13.8/21.3× 13.8/19.2/24.9× each aggressively optimized variant of Mu2 and the default,
across 20 repetitions of 24 hour campaigns (higher is better).
produced by Zest. Thus, mutation-analysis-guided fuzzing is able
to produce a higher quality test-input corpus and can be feasibly Closure benchmark. This makes sense, as the main purpose of
used for regression testing. aggressive optimizations is to enable scaling to large programs.
We believe that an aggressively optimized version of mutation- Due to the aggressive nature of the mutant filtering, it is possible
analysis-guided fuzzing can be used as a replacement for coverage- that input candidates that do kill mutants are not saved simply
guided fuzzing if the goal is to produce a test input corpus with high because those killable mutants were filtered. To determine whether
mutation score. Mu2-OPT provides an improvement for 4 bench- the speedup actually results in a test-input corpus with higher muta-
marks and scales to the largest target without paying a performance tion score, we must also measure the impact of these optimizations
penalty. on the mutation score of the generated corpus.
4.2 RQ2: Aggressive Optimizations Figure 6 displays the mutation scores of all of the variants for
each of the 5 benchmarks. At least one optimized variant was bet-
How do the performance optimizations impact the quality of ter than the default in all benchmarks. Somewhat surprisingly, we
the test-input corpus produced by mutation-analysis guidance? observe similar mutation scores between the Mu2-LeastExecuted-𝑘
and Mu2-Random-𝑘 variants for the same value of 𝑘 in the first
This RQ focuses on understanding the benefit of the aggressive four benchmarks. The one exception is Closure Compiler, where
optimizations in mitigating the scalability concerns of Mu2-Default. Mu2-LeastExecuted-10 achieves a statistically significantly higher
We created variants Mu2-LeastExecuted-𝑘 and Mu2-Random-𝑘 , mutation score than Mu2-Random-10. Again, the effect of aggres-
each applying the corresponding filter described in Section 3.4.3, sive optimizations is most pronounced in the largest target.
and chose three different values of 𝑘 ∈ {5, 10, 20}. Another interesting observation is that we can visualize the
First, we measure just the performance benefit. Table 3 shows trade-off between execution speed and mutation score in the Jack-
the speedups achieved—in terms of number of inputs evaluated son benchmark: although the Mu2-Random-5 variant has a faster
over a 24-hour period—by each variant over Mu2-Default. The execution speed than Mu2-Random-10 (Tab. 3) due to the smaller
improvement for the benchmarks Gson and Jackson is relatively number of mutants, the mutation score slightly decreases (Fig. 6)
minor due to the already small number of mutants executed for each since the optimization might skip some mutants at the wrong time.
input after applying the execution and infection optimizations (ref. Nonetheless, the speedup displayed by the variants for the Closure
Section 3.4.2 and Table 1). However, the aggressive optimizations Compiler results in better test-input corpus quality. All of the Mu2
provide significant improvement for the larger benchmarks, with variants are able to achieve statistically significantly higher muta-
almost 25× speedup for the Mu2-LeastExecuted-5 variant on the tion scores than Mu2-Default. Specifically, Mu2-LeastExecuted-10,
936
killed Killed Mutants
Guiding Greybox Fuzzing with Mutation Testing ISSTA ’23, July 17–21, 2023, Seale, WA, USA
Mu2-Random-5, and Mu2-LeastExecuted-5 kill ∼15 more mutants ChocoPy 20 Gson
on average than Mu2-Default. 10
We found that Mu2-LeastExecuted-10 and Mu2-LeastExecuted-5 8 15
were the strongest variants, as they had a statistically significant 6 10
increase in mutation score over Mu2-Default in the most bench- 4
marks (3 out of 5) out of all variants. There was no significant 2 5
difference in mutation scores between these two variants in any 0 0
benchmarks, so we arbitrarily picked Mu2-LeastExecuted-10 as the -20 -15 -10 -5 0 5 10 15 20 -20 -15 -10 -5 0 5 10 15 20
optimized version of mutation-analysis-guided fuzzing (Mu2-OPT) 40 Jackson 6 Tomcat
in our evaluation of RQ1 and RQ4. We do however note for future 5
practitioners that the best aggressively optimized variant of Mu2 30 4
may change depending on the target program. 20 3
2
10
1
4.3 RQ3: Nontrivial Mutants 0 -20 -15 -10 -5 0 5 10 15 20 0 -20 -15 -10 -5 0 5 10 15 20
Closure
How does the reliability of killing nontrivial mutants differ 50 Mu2-OPT
between mutation-analysis guidance and coverage guidance? 40 Zest
Not all mutants are equal—some mutants are easier to kill than 30
others. We define a mutant 𝑃 ′ = ⟨𝑃, 𝑒, 𝑒′, 𝑛⟩ as trivial if it is killed 20
by the first input that executes 𝑛 in every experiment (this is the 10
dynamic version of Kaufman et al.’s definition [40]). Since trivial 0
mutants are killed as soon as the corresponding code is covered, -20 -15 -10 -5 0 5 10 15 20
Difference in Kill Frequency
conventional coverage-guided fuzzing like Zest suffices to capture (bars further right indicate higher reliability of Mu2)
them. On the other hand, since nontrivial mutants may or may
not be killed even after the mutated expression is covered, we are Figure 7: Histogram of difference in kill-rate of nontrivial
interested to know whether these get killed based on pure luck or mutants between Zest and Mu2-OPT over 20 experiments.
whether these get killed reliably across repetitions potentially due X-axis is the difference in repetitions (ranging from -20 to
to the guidance in the fuzzing algorithm. We measure reliability 20), and Y-axis is the number of mutants. Larger positive dif-
by counting the number of repetitions in which each mutant is ferences (right) are better for Mu2-OPT, and larger negative
killed. In particular, we study the difference in reliability of killing differences (left) are better for Zest.
nontrivial mutants between Zest and the best variant of Mu2.
Figure 7 is a histogram showing the difference in kill rate of
nontrivial mutants between Mu2-OPT and Zest. The values on the 4.4 RQ4: Differential Mutation Testing
right side (green) correspond to mutants killed more reliably by How much stronger is the differential mutation testing oracle
Mu2-OPT than Zest. For the sake of visualization, the mutants with than the implicit oracle?
no difference in kill rate (X-axis value 0) are excluded from the
charts. Described in Section 3.3, the differential mutation testing oracle
Mu2-OPT is able to achieve a significantly higher kill frequency is responsible for determining whether an input kills a mutant by
of nontrivial mutants in ChocoPy and Jackson. In fact, there are comparing the outputs of the executions. We contrast it with the
29 mutants in Jackson that are killed during all repetitions of incomplete greybox fuzzing implicit oracle, which only detects un-
Mu2-OPT and zero repetitions of Zest. This is a strong indication caught exceptions or failed property checks. To study the strength
that mutation-analysis feedback can consistently discover mutant- of the differential oracle, we evaluate the improvement in the num-
killing inputs that coverage-only feedback is incapable of finding. ber of killed mutants over the implicit oracle.
For the Gson parser, there are 22 vs. 24 nontrivial mutants killed Figure 8 shows the difference in mutant kills across the bench-
more reliably by Zest and Mu2-OPT respectively, though the X- marks with the two types of oracles. The differential oracle is able
axis values are generally higher for Mu2-OPT. For Closure, there to kill a significantly higher number of mutants across all 5 bench-
are over 60 mutants killed by at least one more repetition of Mu2- marks, with an average increase of 25%. In the ChocoPy benchmark,
OPT compared to the 4 by Zest. Overall, Mu2-OPT is able to kill over 85 more mutants are caught! This is because certain mutants
nontrivial mutants more reliably than Zest. are unkillable by the implicit oracle due to their effect on program
We also note that Figure 7 provides some insight into the di- behavior. We describe one of these mutants below. For brevity, we
versity of mutants, particularly redundant mutants. By definition, describe the code functionality, omitting the actual code snippet.
redundant mutants are grouped together in the same bars since The ChocoPy type-checker has a function to check that the
they are always killed at the same frequency. Flattening the size of left and right operand types of an expression match when using
each bar to 1 removes at least all redundant mutants and acts as a the “+" operator. If so, the type is returned and assigned to the
lower bound on the number of nonredundant mutants. corresponding expression node in the output AST; otherwise, an
937
Number of Mutants
ISSTA ’23, July 17–21, 2023, Seale, WA, USA Vasudev Vikram, Isabella Laybourn, Ao Li, Nicole Nair, Kelton OBrien, Rafaello Sanna, and Rohan Padhye
Strength of Oracle of mutation-analysis-guided fuzzing on mutation score and code
400 Implicit coverage.
300 Differential Our implementation simply reused all the fuzzing hyperparame-
ters (e.g., PickInput and MutateInput in Algorithms 1 and 2) that
200 were set by the baseline Zest fuzzer. Tuning these heuristics could
affect our results, but the size of this search space is too large for
100 us to explore systematically. We stick with the baseline-provided
defaults for simplicity and make sure to use the same hyperparam-
0 eters for both Zest and Mu2 so that our conclusions are exclusively
ChocoPy Gson Jackson Tomcat Closure based on the inclusion of mutation-analysis guidance in Mu2 only.
Benchmark
Threats to external validity. Since our implementation is based
Figure 8: Number of killed mutants detected by the differen- on JQF [58] and PIT [17], which both target JVM bytecode, we
tial oracle vs. the implicit oracle across 20 repetitions of 24 used Zest as the baseline. We do not know if our conclusions will
hour campaigns with Mu2-Default (higher is better). Error generalize to other programming languages or fuzzing platforms,
bars represent 95% confidence intervals. such as the family of tools based on AFL [81] and libFuzzer [49].
The available mutation testing infrastructure for C/C++ appears
to be less mature than that for Java/JVM. Another threat to exter-
error message for the expression is added to the output AST error nal validity arises from our selection bias in choice of benchmark
list. Consider a mutant 𝑃 ′ that modifies this function to return programs. Our targets have input and output formats which make
null instead of the correct type. Executing 𝑃 ′ on the well-typed them amenable to differential mutation testing. This is not always
ChocoPy program [1]+([2]+[3]) results in a type-checking true for all applications that can be fuzzed—e.g., PDF viewers and
error, since the [int] type of [1] does not match the mutated other programs whose output is graphical. The study of the general
null return type of ([2]+[3]). The differential oracle kills 𝑃 ′ test oracle problem [6] is outside the scope of this paper.
since the output AST produced by 𝑃 ′ contains a type error, whereas 6
𝑃 does not. The implicit oracle fails to kill this mutant since no RELATED WORK
exceptions are triggered. Greybox fuzzing. The field of coverage-guided greybox fuzzing
We conclude that the differential oracle is substantially stronger has a vast literature, as surveyed by Manès et al. [52]; a more recent
than a traditional implicit oracle and is valuable for capturing a and evolving publication list is maintained by Wen [78]. The ma-
larger set of mutant program execution behaviors. jority of fuzzing research focuses on improving heuristics such as
seed-picking power schedules [9], input mutations [5, 48, 50], and
5 THREATS TO VALIDITY coverage feedback [14, 25]. FuzzFactory [60] generalizes the feed-
Threats to construct validity. First, the measurement of mutation back of greybox fuzzing beyond code coverage to domain-specific
score is of course dependent on the set of mutation operators be- metrics that satisfy certain conditions. Our proposed mutation-
ing applied to generate program mutants [62]. We aim to mitigate analysis guidance fits into this framework.
this threat by using the default set of operators in the widely used Greybox fuzzing for regression testing. A family of techniques
PIT framework, as justified in Section 3.1. Second, our test oracles have been developed for directing fuzz testing towards specific
(ref. Section 3.3) report an outcome of TIMEOUT if a mutant execu- code locations [8, 13, 77] or code commits [84], which can be used
tion does not terminate within a predefined limit. Such a bound is for identifying regressions. However, this still requires running a
necessary to catch infinite loops (e.g., for mutants that negate loop full fuzzing campaign, which can take hours or days. In contrast,
conditions). However, if this bound is too small, then it is possible we focus on synthesizing a high-quality test-input corpus which
in theory that some mutants could be marked as “killed” by a fuzzer- can be quickly executed in CI—usually taking a few seconds or
generated input even if their execution would eventually produce minutes—as is often already practiced (ref. Section 1).
a correct output. To mitigate this threat, we compute the mutation
scores for the final test-input corpus by re-running saved inputs Guiding fuzzing with mutation testing. We first proposed the
on all program mutants using a larger timeout. We also manually idea of using mutation testing to augment greybox fuzzing in a
analyzed a sample of reported timeouts to confirm correspondence student research competition [46]; independently, Qian et al. [67]
to infinite loops—we found no false kills. published a similar idea at a regional symposium. However, we
believe the current paper is the first to thoroughly evaluate the
Threats to internal validity. Our evaluation uses mutation score performance and scalability of incorporating mutation testing in
when comparing the quality of the generated test-input corpora the fuzzing loop. In particular, we identified that the evaluation in
since our goal was to synthesize a test-input corpus with high Qian et al.’s paper [67] uses an unsound comparison to the baseline
mutation score (ref. Section 3.1). We assume that a high mutation Zest; they use mutation analysis with multiple threads but run
score is a valuable objective for fuzzers. However, there is a potential Zest only single threaded for the same time bound, hence giving
bias from using mutation score as an evaluation metric, as Mu2 higher CPU time to their technique and obscuring the effects of the
benefits from incorporating mutation testing in the fuzzing loop. increased overhead of performing mutation testing. Additionally,
Our results nevertheless capture the performance overhead impact they use a selection strategy to choose 10 mutants at random, but
938
Killed Mutants
Guiding Greybox Fuzzing with Mutation Testing ISSTA ’23, July 17–21, 2023, Seale, WA, USA
do not measure the impact on the overall mutation score, since 7 CONCLUSION they never run all killable mutants. We were unable to perform a We investigated the challenges of incorporating mutation analysis head-to-head evaluation between Mu2 and their technique since to guide greybox fuzzing. Our implementation, Mu2, integrates PIT their implementation is not open source. mutation testing into the JQF framework, and is aimed at producing Using mutation testing in automated test generation. In a regis- a test-input corpus with high mutation score. In our design, we in- tered report, Groce et al. [33] propose fuzzing specially mutated corporated a differential testing as an oracle for killing mutants and targets to find inputs triggering interesting control flow not in the proposed optimizations to improve fuzzing throughput by dynami- original program, and then use those inputs as seeds for coverage- cally pruning the number of mutants to be executed. We applied guided fuzzing. However, they do not target maximizing mutant both sound and aggressive optimizations for Mu2 to help scale it to kills—for example, a mutant which only changes return codes gets larger programs. After conducting a thorough evaluation on Mu2 low fuzzing priority in their approach because it won’t affect con- and several variants, we found that mutation-analysis feedback can trol flow [33]. In contrast, Mu2 aims to find inputs that differentiate improve the mutation score of a test-input corpus and more reliably program output on potentially semantics-altering mutants, which kill nontrivial mutants than coverage-guided fuzzing. often change data values but not necessarily control flow. Our ap- One of the challenges identified by Gopinath et al. [31] was to proach is therefore orthogonal to Groce et al.’s and could potentially “improve visibility of mutation analysis among fuzzing researchers.” even be combined. We hope our work increases awareness of mutation analysis tech- 𝜇-test [24] and EvoSuite [23] are evolutionary test-generation niques in the fuzzing community and encourages other researchers techniques that can use mutation scores as an objective as well to develop more advanced hybrid techniques. as a fitness function. 𝜇-test, which is based on Javalanche [70], ACKNOWLEDGMENTS uses a form of differential testing to compare the coverage traces of the original program and a mutant. Unlike these tools, which This research was funded in part by NSF grant CCF-2120955, a seed generate unit test methods for exercising program API, greybox grant from CMU’s CyLab, and an Amazon Research Award. fuzzing focuses on the generation of inputs for system testing, given a fixed entry point. REFERENCES Improving the performance of mutation testing. A lot of research [1] Paul Ammann. 2015. Transforming mutation testing from the technology of the future into the technology of the present. In International conference on software has been conducted to speed up mutation testing [18, 37, 63, 66, 73]. testing, verification and validation workshops (ICST): Mutation workshop. IEEE. The approaches fall into three categories: (1) reducing the number https://mutation-workshop.github.io/2015/program/MutationKeynote.pdf of mutants to generate, (2) pruning mutants to run on a given test, [2] J. H. Andrews, L. C. Briand, and Y. Labiche. 2005. Is Mutation an Appropriate Tool for Testing Experiments?. In Proceedings of the 27th International Conference on and (3) speeding up mutant evaluation on a given test. For exam- Software Engineering (St. Louis, MO, USA) (ICSE ’05). Association for Computing ple, many techniques have been developed to avoid generating Machinery, 402–411. https://doi.org/10.1145/1062455.1062530 [3] Apache Foundation. 2022. Tomcat. https://github.com/apache/tomcat. Retrieved redundant or equivalent mutants [51]; we do not currently make August 31, 2022. an attempt to identify these statically. Just et al. [39] introduce the [4] Cornelius Aschermann, Tommaso Frassetto, Thorsten Holz, Patrick Jauernig, propagation, infection, execution (PIE) model to prune mutants that Ahmad-Reza Sadeghi, and Daniel Teuchert. 2019. Nautilus: Fishing for Deep Bugs with Grammars. In 26th Annual Network and Distributed System Security are test-equivalent using dynamic analysis. Mu2 implements the Symposium (NDSS ’19). https://doi.org/10.14722/ndss.2019.23412 execution and infection optimizations from this work. MeMu [26] [5] Cornelius Aschermann, Sergej Schumilo, Tim Blazytko, Robert Gawlik, and speeds up PIT’s mutation analysis by memoizing unmutated meth- Thorsten Holz. 2019. REDQUEEN: Fuzzing with Input-to-State Correspondence.. In NDSS, Vol. 19. 1–15. https://doi.org/10.14722/ndss.2019.23371 ods with long execution time; this is a promising approach that [6] Earl T. Barr, Mark Harman, Phil McMinn, Muzammil Shahbaz, and Shin Yoo. 2015. could be integrated into Mu2. Kaufman et al. [40] prioritize mu- The Oracle Problem in Software Testing: A Survey. IEEE Transactions on Software Engineering 41, 5 (2015), 507–525. https://doi.org/10.1109/TSE.2014.2372785 tants to reach test completeness faster. All these optimizations are [7] U. C. Berkeley. 2019. ChocoPy. https://chocopy.org/. Reference compiler JAR sound—they do not avoid analyzing mutants that may be killable. retrieved on January 12, 2022. Other research directions aim to reduce mutation-analysis costs [8] Marcel Böhme, Van-Thuan Pham, Manh-Dung Nguyen, and Abhik Roychoudhury. 2017. Directed greybox fuzzing. In Proceedings of the 2017 ACM SIGSAC Conference while potentially trading off soundness. For example, weak muta- on Computer and Communications Security. 2329–2344. https://doi.org/10.1145/ tion [35] has been proposed to terminate mutant evaluation quickly 3133956.3134020 by observing the intermediate state after executing the mutated pro- [9] Marcel Böhme, Van-Thuan Pham, and Abhik Roychoudhury. 2016. Coverage- based Greybox Fuzzing as Markov Chain. In Proceedings of the 2016 ACM SIGSAC gram locations. Many techniques have been developed for mutation Conference on Computer and Communications Security (CCS). 1032–1043. https: reduction [63, 66, 73]—where only a subset of mutants are evaluated //doi.org/10.1145/2976749.2978428 [10] Marcel Böhme, László Szekeres, and Jonathan Metzman. 2022. On the Reliability based on some program-specific criteria. In this paper, we have of Coverage-Based Fuzzer Benchmarking. In 44th IEEE/ACM International Confer- evaluated the random sampling approach and a novel least-executed ence on Software Engineering (ICSE’22). https://doi.org/10.1145/3510003.3510230 approach to mutant selection. Recently, Guizzo et al. [34] have to appear. [11] Sang Kil Cha, Maverick Woo, and David Brumley. 2015. Program-adaptive proposed an evolutionary approach to automate the generation mutational fuzzing. In 2015 IEEE Symposium on Security and Privacy. IEEE, 725– of optimal cost reduction strategies. Further, predictive mutation 741. https://doi.org/10.1109/SP.2015.50 testing [82] uses machine learning to estimate which mutants are [12] Thierry Titcheu Chekam, Mike Papadakis, Yves Le Traon, and Mark Harman. 2017. An empirical study on mutation, statement and branch coverage fault most likely to be killed. Incorporating such advanced models into revelation that avoids the unreliable clean program assumption. In 2017 IEEE/ACM the Mu2 framework are promising directions for future work. 39th International Conference on Software Engineering (ICSE). IEEE, 597–608. https://doi.org/10.1109/ICSE.2017.61 [13] Hongxu Chen, Yinxing Xue, Yuekang Li, Bihuan Chen, Xiaofei Xie, Xiuheng Wu, and Yang Liu. 2018. Hawkeye: Towards a desired directed grey-box fuzzer. In Proceedings of the 2018 ACM SIGSAC Conference on Computer and Communications Security. 2095–2108. https://doi.org/10.1145/3243734.3243849
939
ISSTA ’23, July 17–21, 2023, Seale, WA, USA Vasudev Vikram, Isabella Laybourn, Ao Li, Nicole Nair, Kelton OBrien, Rafaello Sanna, and Rohan Padhye
[14] Peng Chen and Hao Chen. 2018. Angora: Efficient fuzzing by principled search. [36] Laura Inozemtseva and Reid Holmes. 2014. Coverage is not strongly correlated
In 2018 IEEE Symposium on Security and Privacy (SP). IEEE, 711–725. https: with test suite effectiveness. In Proceedings of the 36th international conference on //doi.org/10.1109/SP.2018.00046 software engineering (ICSE’14). 435–445. https://doi.org/10.1145/2568225.2568271 [15] Yiqun T. Chen, Rahul Gopinath, Anita Tadakamalla, Michael D. Ernst, Reid [37] Yue Jia and Mark Harman. 2010. An analysis and survey of the development of Holmes, Gordon Fraser, Paul Ammann, and René Just. 2020. Revisiting the Re- mutation testing. IEEE transactions on software engineering 37, 5 (2010), 649–678. lationship between Fault Detection, Test Adequacy Criteria, and Test Set Size. https://doi.org/10.1109/TSE.2010.62 In Proceedings of the 35th IEEE/ACM International Conference on Automated Soft- [38] René Just, Michael D Ernst, and Gordon Fraser. 2014. Efficient mutation analysis ware Engineering (Virtual Event, Australia) (ASE ’20). Association for Computing by propagating and partitioning infected execution states. In Proceedings of the Machinery, 237–249. https://doi.org/10.1145/3324884.3416667 2014 International Symposium on Software Testing and Analysis (ISSTA’14). 315– [16] Koen Claessen and John Hughes. 2000. QuickCheck: A Lightweight Tool for 326. https://doi.org/10.1145/2610384.2610388 Random Testing of Haskell Programs. In Proceedings of the 5th ACM SIGPLAN [39] René Just, Darioush Jalali, Laura Inozemtseva, Michael D Ernst, Reid Holmes, and International Conference on Functional Programming (ICFP). https://doi.org/10. Gordon Fraser. 2014. Are mutants a valid substitute for real faults in software 1145/351240.351266 testing?. In Proceedings of the 22nd ACM SIGSOFT International Symposium on [17] Henry Coles, Thomas Laurent, Christopher Henard, Mike Papadakis, and An- Foundations of Software Engineering (FSE’14). 654–665. https://doi.org/10.1145/ thony Ventresque. 2016. PIT: a practical mutation testing tool for Java. In Pro- 2635868.2635929 ceedings of the 25th International Symposium on Software Testing and Analysis [40] Samuel J. Kaufman, Ryan Featherman, Justin Alvin, Bob Kurtz, Paul Ammann, (ISSTA’16). 449–452. https://doi.org/10.1145/2931037.2948707 and René Just. 2022. Prioritizing Mutants to Guide Mutation Testing. In Pro- [18] Fabiano Cutigi Ferrari, Alessandro Viola Pizzoleto, and Jeff Offutt. 2018. A Sys- ceedings of the 44th International Conference on Software Engineering (Pittsburgh, tematic Review of Cost Reduction Techniques for Mutation Testing: Preliminary Pennsylvania) (ICSE ’22). Association for Computing Machinery, 1743–1754. Results. In 2018 IEEE International Conference on Software Testing, Verification and https://doi.org/10.1145/3510003.3510187 Validation Workshops (ICSTW). 1–10. https://doi.org/10.1109/ICSTW.2018.00021 [41] Marinos Kintis, Mike Papadakis, Andreas Papadopoulos, Evangelos Valvis, Nicos [19] R.A. DeMillo, R.J. Lipton, and F.G. Sayward. 1978. Hints on Test Data Selection: Malevris, and Yves Le Traon. 2018. How effective are mutation testing tools? Help for the Practicing Programmer. Computer 11, 4 (1978), 34–41. https: An empirical analysis of Java mutation testing tools with manual analysis and //doi.org/10.1109/C-M.1978.218136 real faults. Empirical Software Engineering 23, 4 (2018), 2426–2463. https: [20] Zhen Yu Ding and Claire Le Goues. 2021. An Empirical Study of OSS-Fuzz Bugs. //doi.org/10.1007/s10664-017-9582-5 In 2021 IEEE/ACM 18th International Conference on Mining Software Repositories [42] George Klees, Andrew Ruef, Benji Cooper, Shiyi Wei, and Michael Hicks. 2018. (MSR). IEEE, 131–142. https://doi.org/10.1109/MSR52588.2021.00026 Evaluating fuzz testing. In Proceedings of the 2018 ACM SIGSAC Conference on [21] Robert B Evans and Alberto Savoia. 2007. Differential testing: a new approach Computer and Communications Security. 2123–2138. https://doi.org/10.1145/ to change detection. In The 6th Joint Meeting on European software engineering 3243734.3243804 conference and the ACM SIGSOFT Symposium on the Foundations of Software En- [43] James Kukucka, Luís Pina, Paul Ammann, and Jonathan Bell. 2022. CONFETTI: gineering: Companion Papers. 549–552. https://doi.org/10.1145/1295014.1295038 Amplifying Concolic Guidance for Fuzzers. In 44th IEEE/ACM International [22] FasterXML. [n. d.]. Jackson: JSON for Java. https://github.com/FasterXML/ Conference on Software Engineering (ICSE’22). https://doi.org/10.1145/3510003. jackson. Retrieved August 31, 2022. 3510628 [23] Gordon Fraser and Andrea Arcuri. 2011. EvoSuite: Automatic Test Suite Gen- [44] Leonidas Lampropoulos, Michael Hicks, and Benjamin C Pierce. 2019. Cover- eration for Object-oriented Software. In Proceedings of the 19th ACM SIGSOFT age guided, property based testing. Proceedings of the ACM on Programming Symposium and the 13th European Conference on Foundations of Software Engi- Languages 3, OOPSLA (2019), 1–29. https://doi.org/10.1145/3360607 neering (ESEC/FSE ’11). https://doi.org/10.1145/2025113.2025179 [45] Thomas Laurent, Mike Papadakis, Marinos Kintis, Christopher Henard, Yves [24] Gordon Fraser and Andreas Zeller. 2010. Mutation-driven Generation of Unit Le Traon, and Anthony Ventresque. 2017. Assessing and improving the mutation Tests and Oracles. In Proceedings of the 19th International Symposium on Software testing practice of PIT. In 2017 IEEE International Conference on Software Testing, Testing and Analysis (Trento, Italy) (ISSTA ’10). ACM, 147–158. https://doi.org/ Verification and Validation (ICST). IEEE, 430–435. https://doi.org/10.1109/ICST. 10.1145/1831708.1831728 2017.47 [25] Shuitao Gan, Chao Zhang, Peng Chen, Bodong Zhao, Xiaojun Qin, Dong Wu, [46] Isabella Laybourn. 2022. 𝜇2: Using Mutation Analysis to Guide Mutation-Based and Zuoning Chen. 2020. GREYONE: Data flow sensitive fuzzing. In 29th USENIX Fuzzing. In Proceedings of the ACM/IEEE 44th International Conference on Software Security Symposium (USENIX Security 20). 2577–2594. https://doi.org/10.5555/ Engineering: Companion Proceedings (Pittsburgh, Pennsylvania) (ICSE ’22). As- 3489212.3489357 sociation for Computing Machinery, 331–333. https://doi.org/10.1145/3510454. [26] Ali Ghanbari and Andrian Marcus. 2022. Faster Mutation Analysis with MeMu. 3522682 In Proceedings of the 31st ACM SIGSOFT International Symposium on Software [47] Vu Le, Mehrdad Afshari, and Zhendong Su. 2014. Compiler Validation via Testing and Analysis (Virtual, South Korea) (ISSTA 2022). 781–784. https://doi. Equivalence modulo Inputs. In Proceedings of the 35th ACM SIGPLAN Confer- org/10.1145/3533767.3543288 ence on Programming Language Design and Implementation (PLDI ’14). 216–226. [27] John B. Goodenough and Susan L. Gerhart. 1975. Toward a Theory of Test Data https://doi.org/10.1145/2594291.2594334 Selection. SIGPLAN Not. 10, 6 (apr 1975), 493–510. https://doi.org/10.1145/390016. [48] Caroline Lemieux and Koushik Sen. 2018. Fairfuzz: A targeted mutation strategy 808473 for increasing greybox fuzz testing coverage. In Proceedings of the 33rd ACM/IEEE [28] Google. 2019. Ideal integration with OSS-Fuzz. https://google. International Conference on Automated Software Engineering. 475–485. https: github.io/oss-fuzz/advanced-topics/ideal-integration/#regression-testing. //doi.org/10.1145/3238147.3238176 https://web.archive.org/web/20200301084941/https://google.github.io/oss- [49] LLVM Compiler Infrastructure. 2016. libFuzzer. https://llvm.org/docs/LibFuzzer. fuzz/advanced-topics/ideal-integration/#regression-testing Retrieved August 31, html. Accessed February 11, 2022. 2022. [50] Chenyang Lyu, Shouling Ji, Chao Zhang, Yuwei Li, Wei-Han Lee, Yu Song, and [29] Google. 2021. Gson: A Java serialization/deserialization library to convert Java Raheem Beyah. 2019. MOPT: Optimized mutation scheduling for fuzzers. In 28th Objects into JSON and back. https://github.com/google/gson. Retrieved August USENIX Security Symposium (USENIX Security 19). 1949–1966. https://doi.org/10. 31, 2022. 5555/3361338.3361473 [30] Google. 2022. Google Closure Compiler. https://github.com/google/closure- [51] Lech Madeyski, Wojciech Orzeszyna, Richard Torkar, and Mariusz Jozala. 2013. compiler. Retrieved August 31, 2022. Overcoming the equivalent mutant problem: A systematic literature review and a [31] Rahul Gopinath, Philipp Görz, and Alex Groce. 2022. Mutation Analysis: An- comparative experiment of second order mutation. IEEE Transactions on Software swering the Fuzzing Challenge. CoRR abs/2201.11303 (2022). arXiv:2201.11303 Engineering 40, 1 (2013), 23–42. https://doi.org/10.1109/TSE.2013.44 https://arxiv.org/abs/2201.11303 [52] Valentin Jean Marie Manès, HyungSeok Han, Choongwoo Han, Sang Kil Cha, [32] Rahul Gopinath, Carlos Jensen, and Alex Groce. 2014. Mutations: How Close Manuel Egele, Edward J Schwartz, and Maverick Woo. 2019. The art, science, are they to Real Faults?. In 2014 IEEE 25th International Symposium on Software and engineering of fuzzing: A survey. IEEE Transactions on Software Engineering Reliability Engineering. 189–200. https://doi.org/10.1109/ISSRE.2014.40 (2019). https://doi.org/10.1109/TSE.2019.2946563 [33] Alex Groce, Goutamkumar Tulajappa Kalburgi, Claire Le Goues, Kush Jain, and [53] William M. McKeeman. 1998. Differential Testing for Software. DIGITAL TECH- Rahul Gopinath. 2022. Registered Report: First, Fuzz the Mutants. In International NICAL JOURNAL 10, 1 (1998), 100–107. Fuzzing Workshop (FUZZING’22). [54] Barton P. Miller, Louis Fredriksen, and Bryan So. 1990. An Empirical Study [34] Giovani Guizzo, Federica Sarro, Jens Krinke, and Silvia R. Vergilio. 2022. Sentinel: of the Reliability of UNIX Utilities. Commun. ACM 33, 12 (dec 1990), 32–44. A Hyper-Heuristic for the Generation of Mutant Reduction Strategies. IEEE https://doi.org/10.1145/96267.96279 Transactions on Software Engineering 48, 3 (2022), 803–818. https://doi.org/10. [55] Hoang Lam Nguyen and Lars Grunske. 2022. BeDivFuzz: Integrating Behav- 1109/TSE.2020.3002496 ioral Diversity into Generator-Based Fuzzing. In Proceedings of the 44th Inter- [35] William E. Howden. 1982. Weak mutation testing and completeness of test national Conference on Software Engineering (Pittsburgh, Pennsylvania) (ICSE sets. IEEE Transactions on Software Engineering SE-8, 4 (1982), 371–379. https: ’22). Association for Computing Machinery, New York, NY, USA, 249–261. //doi.org/10.1109/TSE.1982.235571 https://doi.org/10.1145/3510003.3510182
940
Guiding Greybox Fuzzing with Mutation Testing ISSTA ’23, July 17–21, 2023, Seale, WA, USA
[56] Hoang Lam Nguyen, Nebras Nassar, Timo Kehrer, and Lars Grunske. 2020. Mo- 2020 IEEE/ACM 42nd International Conference on Software Engineering (ICSE).
Fuzz: A fuzzer suite for testing model-driven software engineering tools. In 2020 IEEE, 1410–1421. https://doi.org/10.1145/3377811.3380399
35th IEEE/ACM International Conference on Automated Software Engineering (ASE). [70] David Schuler and Andreas Zeller. 2009. Javalanche: Efficient Mutation Testing
IEEE, 1103–1115. https://doi.org/10.1145/3324884.3416668 for Java. In Proceedings of the 7th Joint Meeting of the European Software En-
[57] A. Jefferson Offutt, Ammei Lee, Gregg Rothermel, Roland H. Untch, and Christian gineering Conference and the ACM SIGSOFT Symposium on The Foundations of
Zapf. 1996. An Experimental Determination of Sufficient Mutant Operators. Software Engineering (Amsterdam, The Netherlands) (ESEC/FSE ’09). Association
ACM Trans. Softw. Eng. Methodol. 5, 2 (apr 1996), 99–118. https://doi.org/10.1145/ for Computing Machinery, 297–298. https://doi.org/10.1145/1595696.1595750
227607.227610 [71] SQLite Authors. 2019. How SQLite is Tested. https://www.sqlite.org/testing.html#
[58] Rohan Padhye, Caroline Lemieux, and Koushik Sen. 2019. JQF: Coverage-guided the_fuzzcheck_test_harness. https://web.archive.org/web/20200427011538/https:
Property-based Testing in Java. In Proceedings of the 28th ACM SIGSOFT In- //www.sqlite.org/testing.html#the_fuzzcheck_test_harness Retrieved August 31,
ternational Symposium on Software Testing and Analysis (ISSTA’19). 398–401. 2022.
https://doi.org/10.1145/3293882.3339002 [72] The OpenSSL Project. 2016. Run the fuzzing corpora as tests. https://github.
[59] Rohan Padhye, Caroline Lemieux, Koushik Sen, Mike Papadakis, and Yves com/openssl/openssl/commit/90d28f05. https://github.com/openssl/openssl/
Le Traon. 2019. Semantic Fuzzing with Zest. In Proceedings of the 28th ACM SIG- tree/openssl-3.0.0/fuzz/corpora Retrieved August 31, 2022.
SOFT International Symposium on Software Testing and Analysis (Beijing, China) [73] Macario Polo Usaola and Pedro Reales Mateo. 2010. Mutation Testing Cost
(ISSTA 2019). ACM, 329–340. https://doi.org/10.1145/3293882.3330576 Reduction Techniques: A Survey. IEEE Software 27, 3 (2010), 80–86. https:
[60] Rohan Padhye, Caroline Lemieux, Koushik Sen, Laurent Simon, and Hayawardh //doi.org/10.1109/MS.2010.79
Vijayakumar. 2019. FuzzFactory: domain-specific fuzzing with waypoints. Pro- [74] Vasudev Vikram, Isabella Laybourn, Ao Li, Nicole Nair, Kelton OBrien, Rafaello
ceedings of the ACM on Programming Languages 3, OOPSLA, Article 174 (2019), Sanna, and Rohan Padhye. 2023. Mu2: Guiding Greybox Fuzzing with Mutation
29 pages. https://doi.org/10.1145/3360600 Testing (Artifact). https://doi.org/10.5281/zenodo.8006662
[61] Rohan Padhye, Koushik Sen, and Paul N. Hilfinger. 2019. ChocoPy: A Program- [75] Vasudev Vikram, Rohan Padhye, and Koushik Sen. 2021. Growing A Test Corpus
ming Language for Compilers Courses. In Proceedings of the 2019 ACM SIGPLAN with Bonsai Fuzzing. In 43rd IEEE/ACM International Conference on Software
Symposium on SPLASH-E (Athens, Greece) (SPLASH-E 2019). Association for Engineering, ICSE 2021, Madrid, Spain, 22-30 May 2021. IEEE, 723–735. https:
Computing Machinery, 41–45. https://doi.org/10.1145/3358711.3361627 //doi.org/10.1109/ICSE43902.2021.00072
[62] Mike Papadakis, Christopher Henard, Mark Harman, Yue Jia, and Yves Le Traon. [76] Junjie Wang, Bihuan Chen, Lei Wei, and Yang Liu. 2019. Superion: Grammar-
2016. Threats to the validity of mutation-based test assessment. In Proceedings Aware Greybox Fuzzing. In 41st International Conference on Software Engineering
of the 25th International Symposium on Software Testing and Analysis. 354–365. (ICSE ’19). https://doi.org/10.1109/ICSE.2019.00081
https://doi.org/10.1145/2931037.2931040 [77] Pengfei Wang, Xu Zhou, Kai Lu, Tai Yue, and Yingying Liu. 2022. SoK: The
[63] Mike Papadakis, Marinos Kintis, Jie Zhang, Yue Jia, Yves Le Traon, and Mark progress, challenges, and perspectives of directed greybox fuzzing. arXiv preprint
Harman. 2019. Mutation testing advances: an analysis and survey. In Advances (2022). https://doi.org/10.48550/arXiv.2005.11907
in Computers. Vol. 112. Elsevier, 275–378. https://doi.org/10.1016/bs.adcom.2018. [78] Cheng Wen. 2022. Recent Papers Related To Fuzzing. https://wcventure.github.
03.015 io/FuzzingPaper/. Retrieved March 16, 2022.
[64] Mike Papadakis, Donghwan Shin, Shin Yoo, and Doo-Hwan Bae. 2018. Are [79] Elaine J Weyuker. 1986. Axiomatizing software test data adequacy. IEEE transac-
mutation scores correlated with real fault detection? a large scale empirical tions on software engineering 12 (1986), 1128–1138.
study on the relationship between mutants and real faults. In 2018 IEEE/ACM [80] Xuejun Yang, Yang Chen, Eric Eide, and John Regehr. 2011. Finding and Under-
40th International Conference on Software Engineering (ICSE). IEEE, 537–548. standing Bugs in C Compilers. In Proceedings of the 32nd ACM SIGPLAN conference
https://doi.org/10.1145/3180155.3180183 on Programming language design and implementation (PLDI ’11). Association for
[65] Van-Thuan Pham, Marcel Böhme, Andrew Edward Santosa, Alexandru Razvan Computing Machinery, 283–294. https://doi.org/10.1145/1993498.1993532
Caciulescu, and Abhik Roychoudhury. 2019. Smart greybox fuzzing. IEEE Trans- [81] Michal Zalewski. 2014. American Fuzzy Lop. https://lcamtuf.coredump.cx/afl/.
actions on Software Engineering (2019). https://doi.org/10.1109/TSE.2019.2941681 Accessed February 11, 2022.
[66] Alessandro Viola Pizzoleto, Fabiano Cutigi Ferrari, Jeff Offutt, Leo Fernandes, and [82] Jie Zhang, Ziyi Wang, Lingming Zhang, Dan Hao, Lei Zang, Shiyang Cheng, Márcio Ribeiro. 2019. A systematic literature review of techniques and metrics to and Lu Zhang. 2016. Predictive Mutation Testing. In Proceedings of the 25th reduce the cost of mutation testing. Journal of Systems and Software 157 (2019), International Symposium on Software Testing and Analysis (Saarbrücken, Ger- 110388. https://doi.org/10.1016/j.jss.2019.07.100 many) (ISSTA 2016). Association for Computing Machinery, New York, NY, USA, [67] Ruixiang Qian, Quanjun Zhang, Chunrong Fang, and Lihua Guo. 2022. Inves- 342–353. https://doi.org/10.1145/2931037.2931038 tigating Coverage Guided Fuzzing with Mutation Testing. In Proceedings of the [83] Qian Zhang, Jiyuan Wang, Muhammad Ali Gulzar, Rohan Padhye, and Miryung 13th Asia-Pacific Symposium on Internetware (Hohhot, China) (Internetware ’22). Kim. 2020. Bigfuzz: Efficient fuzz testing for data analytics using framework ab- Association for Computing Machinery, 272–281. https://doi.org/10.1145/3545258. straction. In 2020 35th IEEE/ACM International Conference on Automated Software 3545285 Engineering (ASE). IEEE, 722–733. https://doi.org/10.1145/3324884.3416641 [68] Alexandre Rebert, Sang Kil Cha, Thanassis Avgerinos, Jonathan Foote, David [84] Xiaogang Zhu and Marcel Böhme. 2021. Regression Greybox Fuzzing. In Pro- Warren, Gustavo Grieco, and David Brumley. 2014. Optimizing seed selection ceedings of the 2021 ACM SIGSAC Conference on Computer and Communications for fuzzing. In 23rd USENIX Security Symposium (USENIX Security 14). 861–875. Security (Virtual Event, Republic of Korea) (CCS ’21). Association for Computing https://doi.org/10.5555/2671225.2671280 Machinery, 2169–2182. https://doi.org/10.1145/3460120.3484596 [69] Sameer Reddy, Caroline Lemieux, Rohan Padhye, and Koushik Sen. 2020. Quickly generating diverse valid test inputs with reinforcement learning. In Received 2023-02-16; accepted 2023-05-03
941