@@ -159,6 +159,12 @@ pub const SHM_CMPLOG_ENV_VAR: &str = "__AFL_CMPLOG_SHM_ID";
159
159
/// Environment variable key for a custom AFL coverage map size
160
160
pub const AFL_MAP_SIZE_ENV_VAR : & str = "AFL_MAP_SIZE" ;
161
161
162
+ /// Environment variable keys to skip instrumentation (LLVM variant).
163
+ pub const AFL_LLVM_ONLY_FSRV_VAR : & str = "AFL_LLVM_ONLY_FSRV" ;
164
+
165
+ /// Environment variable keys to skip instrumentation (GCC variant).
166
+ pub const AFL_GCC_ONLY_FSRV_VAR : & str = "AFL_GCC_ONLY_FSRV" ;
167
+
162
168
/// The default signal to use to kill child processes
163
169
const KILL_SIGNAL_DEFAULT : Signal = Signal :: SIGTERM ;
164
170
@@ -374,6 +380,7 @@ impl Forkserver {
374
380
memlimit : u64 ,
375
381
is_persistent : bool ,
376
382
is_deferred_frksrv : bool ,
383
+ is_fsrv_only : bool ,
377
384
dump_asan_logs : bool ,
378
385
coverage_map_size : Option < usize > ,
379
386
debug_output : bool ,
@@ -453,6 +460,11 @@ impl Forkserver {
453
460
command. env ( "__AFL_DEFER_FORKSRV" , "1" ) ;
454
461
}
455
462
463
+ if is_fsrv_only {
464
+ command. env ( AFL_GCC_ONLY_FSRV_VAR , "1" ) ;
465
+ command. env ( AFL_LLVM_ONLY_FSRV_VAR , "1" ) ;
466
+ }
467
+
456
468
#[ cfg( feature = "regex" ) ]
457
469
{
458
470
let asan_options = if dump_asan_logs {
@@ -844,12 +856,14 @@ where
844
856
845
857
/// The builder for `ForkserverExecutor`
846
858
#[ derive( Debug ) ]
859
+ #[ expect( clippy:: struct_excessive_bools) ]
847
860
pub struct ForkserverExecutorBuilder < ' a , SP > {
848
861
target_inner : StdTargetArgsInner ,
849
862
child_env_inner : StdChildArgsInner ,
850
863
uses_shmem_testcase : bool ,
851
864
is_persistent : bool ,
852
865
is_deferred_frksrv : bool ,
866
+ is_fsrv_only : bool ,
853
867
autotokens : Option < & ' a mut Tokens > ,
854
868
shmem_provider : Option < & ' a mut SP > ,
855
869
max_input_size : usize ,
@@ -1058,6 +1072,7 @@ where
1058
1072
0 ,
1059
1073
self . is_persistent ,
1060
1074
self . is_deferred_frksrv ,
1075
+ self . is_fsrv_only ,
1061
1076
self . has_asan_obs ( ) ,
1062
1077
self . map_size ,
1063
1078
self . child_env_inner . debug_child ,
@@ -1316,6 +1331,14 @@ where
1316
1331
Ok ( actual_map_size as usize )
1317
1332
}
1318
1333
1334
+ #[ must_use]
1335
+ /// If set to true, we will only spin up a forkserver without any coverage collected. This is useful for several
1336
+ /// scenario like slave executors of SAND or cmplog executors.
1337
+ pub fn fsrv_only ( mut self , fsrv_only : bool ) -> Self {
1338
+ self . is_fsrv_only = fsrv_only;
1339
+ self
1340
+ }
1341
+
1319
1342
/// Use autodict?
1320
1343
#[ must_use]
1321
1344
pub fn autotokens ( mut self , tokens : & ' a mut Tokens ) -> Self {
@@ -1402,6 +1425,7 @@ impl<'a> ForkserverExecutorBuilder<'a, UnixShMemProvider> {
1402
1425
uses_shmem_testcase : false ,
1403
1426
is_persistent : false ,
1404
1427
is_deferred_frksrv : false ,
1428
+ is_fsrv_only : false ,
1405
1429
autotokens : None ,
1406
1430
shmem_provider : None ,
1407
1431
map_size : None ,
@@ -1430,6 +1454,7 @@ impl<'a> ForkserverExecutorBuilder<'a, UnixShMemProvider> {
1430
1454
uses_shmem_testcase : self . uses_shmem_testcase ,
1431
1455
is_persistent : self . is_persistent ,
1432
1456
is_deferred_frksrv : self . is_deferred_frksrv ,
1457
+ is_fsrv_only : self . is_fsrv_only ,
1433
1458
autotokens : self . autotokens ,
1434
1459
map_size : self . map_size ,
1435
1460
max_input_size : self . max_input_size ,
0 commit comments