diff --git a/Sources/Fuzzilli/Configuration.swift b/Sources/Fuzzilli/Configuration.swift index 121e9cbb8..30986dcc7 100755 --- a/Sources/Fuzzilli/Configuration.swift +++ b/Sources/Fuzzilli/Configuration.swift @@ -73,6 +73,11 @@ public struct Configuration { // differential fuzzers can inspect (via mutating the JS program to print defined variables). public let forDifferentialFuzzing: Bool + // If true, only programs that trigger JIT compilation will be kept in the corpus. + // This is useful for targeting JIT-specific bugs. When enabled, programs that don't + // set any TurboFan optimization bits will be discarded immediately during evaluation. + public let targetJitOnly: Bool + // The subdirectory in {config.storagePath} at which all programs are stored which could not // be imported due to disabled wasm capabilities in the fuzzer. public static let excludedWasmDirectory = "excluded_wasm_programs" @@ -91,7 +96,8 @@ public struct Configuration { tag: String? = nil, isWasmEnabled: Bool = false, storagePath: String? = nil, - forDifferentialFuzzing: Bool = false) { + forDifferentialFuzzing: Bool = false, + targetJitOnly: Bool = true) { self.arguments = arguments self.timeout = timeout self.logLevel = logLevel @@ -106,6 +112,7 @@ public struct Configuration { self.isWasmEnabled = isWasmEnabled self.storagePath = storagePath self.forDifferentialFuzzing = forDifferentialFuzzing + self.targetJitOnly = targetJitOnly } } diff --git a/Sources/Fuzzilli/Evaluation/ProgramCoverageEvaluator.swift b/Sources/Fuzzilli/Evaluation/ProgramCoverageEvaluator.swift index 72bce6ff5..ac372eb69 100755 --- a/Sources/Fuzzilli/Evaluation/ProgramCoverageEvaluator.swift +++ b/Sources/Fuzzilli/Evaluation/ProgramCoverageEvaluator.swift @@ -190,6 +190,13 @@ public class ProgramCoverageEvaluator: ComponentBase, ProgramEvaluator { let hasOptimizationDelta = optimizationDelta == 1 let hasNewEdges = newEdgeSet.count > 0 + if fuzzer.config.targetJitOnly { + // Optionally filter out programs that didn't trigger JIT compilation + if libcoverage.isOpted(&context) == 0 { + return nil + } + } + if result == 1 || hasOptimizationDelta || hasFeedbackDelta { return hasNewEdges ? CovEdgeSet(edges: newEdgeSet.edge_indices, diff --git a/Sources/FuzzilliCli/main.swift b/Sources/FuzzilliCli/main.swift index fbf5068a8..d6b157ceb 100755 --- a/Sources/FuzzilliCli/main.swift +++ b/Sources/FuzzilliCli/main.swift @@ -101,6 +101,8 @@ Options: This can for example be used to remember the target revision that is being fuzzed. --wasm : Enable Wasm CodeGenerators (see WasmCodeGenerators.swift). --forDifferentialFuzzing : Enable additional features for better support of external differential fuzzing. + --targetJitOnly : Only keep programs that trigger JIT compilation in the corpus. This is enabled by default. + Use --no-targetJitOnly to disable and keep all programs regardless of JIT status. --postgres-url=url : PostgreSQL connection string for PostgreSQL corpus (e.g., postgresql://user:pass@host:port/db). --validate-before-cache : Enable program validation before caching in PostgreSQL corpus (default: true). --execution-history-size=n : Number of recent executions to keep in memory for PostgreSQL corpus (default: 10). @@ -162,6 +164,7 @@ let additionalArguments = args["--additionalArguments"] ?? "" let tag = args["--tag"] let enableWasm = args.has("--wasm") let forDifferentialFuzzing = args.has("--forDifferentialFuzzing") +let targetJitOnly = !args.has("--no-targetJitOnly") // Default is true (enabled), unless --no-targetJitOnly is specified let postgresUrl = args["--postgres-url"] ?? ProcessInfo.processInfo.environment["POSTGRES_URL"] let postgresLogging = args.has("--postgres-logging") @@ -628,7 +631,9 @@ let mainConfig = Configuration(arguments: CommandLine.arguments, staticCorpus: staticCorpus, tag: tag, isWasmEnabled: enableWasm, - storagePath: storagePath) + storagePath: storagePath, + forDifferentialFuzzing: forDifferentialFuzzing, + targetJitOnly: targetJitOnly) let fuzzer = makeFuzzer(with: mainConfig) @@ -767,7 +772,9 @@ let workerConfig = Configuration(arguments: CommandLine.arguments, staticCorpus: staticCorpus, tag: tag, isWasmEnabled: enableWasm, - storagePath: storagePath) + storagePath: storagePath, + forDifferentialFuzzing: forDifferentialFuzzing, + targetJitOnly: targetJitOnly) for _ in 1..turbofan_optimization_bits_current != 0; +} + int cov_evaluate_optimization_bits(struct cov_context* context) { if (!context->shmem) return 0; uint8_t delta = 0; diff --git a/Sources/libcoverage/include/libcoverage.h b/Sources/libcoverage/include/libcoverage.h index a35fe819e..73d3a0eb5 100755 --- a/Sources/libcoverage/include/libcoverage.h +++ b/Sources/libcoverage/include/libcoverage.h @@ -161,6 +161,7 @@ void clear_feedback_nexus(struct cov_context* context); // Turbofan and Maglev optimization bits functions +int isOpted(struct cov_context* context); int cov_evaluate_optimization_bits(struct cov_context* context); void cov_update_optimization_bits(struct cov_context* context); void clear_optimization_bits(struct cov_context* context);