1
1
use core:: ffi:: c_int;
2
2
#[ cfg( unix) ]
3
- use std:: io:: { Write , stderr, stdout} ;
4
- use std:: { fmt:: Debug , fs:: File , net:: TcpListener , os:: fd:: AsRawFd , str:: FromStr } ;
3
+ use std:: {
4
+ fmt:: Debug ,
5
+ fs:: File ,
6
+ io:: { Write , stderr, stdout} ,
7
+ net:: TcpListener ,
8
+ os:: fd:: AsRawFd ,
9
+ str:: FromStr ,
10
+ } ;
5
11
12
+ #[ cfg( feature = "tui_monitor" ) ]
13
+ use libafl:: monitors:: tui:: TuiMonitor ;
6
14
use libafl:: {
7
15
Error , Fuzzer , HasMetadata ,
8
16
corpus:: Corpus ,
9
- events:: {
10
- EventConfig , EventReceiver , ProgressReporter , SimpleEventManager ,
11
- SimpleRestartingEventManager , launcher:: Launcher ,
12
- } ,
17
+ events:: { EventReceiver , ProgressReporter , SimpleEventManager } ,
13
18
executors:: ExitKind ,
14
- monitors:: { Monitor , MultiMonitor , tui :: TuiMonitor } ,
19
+ monitors:: MultiMonitor ,
15
20
stages:: StagesTuple ,
16
21
state:: { HasCurrentStageId , HasExecutions , HasLastReportTime , HasSolutions , Stoppable } ,
17
22
} ;
23
+ #[ cfg( unix) ]
24
+ use libafl:: {
25
+ events:: { EventConfig , SimpleRestartingEventManager , launcher:: Launcher } ,
26
+ monitors:: Monitor ,
27
+ } ;
28
+ #[ cfg( unix) ]
18
29
use libafl_bolts:: {
19
30
core_affinity:: Cores ,
20
31
shmem:: { ShMemProvider , StdShMemProvider } ,
21
32
} ;
22
33
23
34
use crate :: { feedbacks:: LibfuzzerCrashCauseMetadata , fuzz_with, options:: LibfuzzerOptions } ;
24
35
36
+ #[ cfg( unix) ]
25
37
fn destroy_output_fds ( options : & LibfuzzerOptions ) {
26
- #[ cfg( unix) ]
27
- {
28
- use libafl_bolts:: os:: { dup2, null_fd} ;
38
+ use libafl_bolts:: os:: { dup2, null_fd} ;
29
39
30
- let null_fd = null_fd ( ) . unwrap ( ) ;
31
- let stdout_fd = stdout ( ) . as_raw_fd ( ) ;
32
- let stderr_fd = stderr ( ) . as_raw_fd ( ) ;
40
+ let null_fd = null_fd ( ) . unwrap ( ) ;
41
+ let stdout_fd = stdout ( ) . as_raw_fd ( ) ;
42
+ let stderr_fd = stderr ( ) . as_raw_fd ( ) ;
33
43
34
- if options. tui ( ) {
44
+ #[ cfg( feature = "tui_monitor" ) ]
45
+ if options. tui ( ) {
46
+ dup2 ( null_fd, stdout_fd) . unwrap ( ) ;
47
+ dup2 ( null_fd, stderr_fd) . unwrap ( ) ;
48
+ return ;
49
+ }
50
+
51
+ if options. close_fd_mask ( ) != 0 {
52
+ if options. close_fd_mask ( ) & u8:: try_from ( stderr_fd) . unwrap ( ) != 0 {
35
53
dup2 ( null_fd, stdout_fd) . unwrap ( ) ;
54
+ }
55
+ if options. close_fd_mask ( ) & u8:: try_from ( stderr_fd) . unwrap ( ) != 0 {
36
56
dup2 ( null_fd, stderr_fd) . unwrap ( ) ;
37
- } else if options. close_fd_mask ( ) != 0 {
38
- if options. close_fd_mask ( ) & u8:: try_from ( stderr_fd) . unwrap ( ) != 0 {
39
- dup2 ( null_fd, stdout_fd) . unwrap ( ) ;
40
- }
41
- if options. close_fd_mask ( ) & u8:: try_from ( stderr_fd) . unwrap ( ) != 0 {
42
- dup2 ( null_fd, stderr_fd) . unwrap ( ) ;
43
- }
44
57
}
45
58
}
46
59
}
@@ -87,10 +100,17 @@ where
87
100
return Err ( Error :: shutting_down ( ) ) ;
88
101
}
89
102
}
90
- fuzzer. fuzz_loop ( stages, executor, state, mgr) ?;
103
+ if options. runs ( ) == 0 {
104
+ fuzzer. fuzz_loop ( stages, executor, state, mgr) ?;
105
+ } else {
106
+ for _ in 0 ..options. runs ( ) {
107
+ fuzzer. fuzz_one ( stages, executor, state, mgr) ?;
108
+ }
109
+ }
91
110
Ok ( ( ) )
92
111
}
93
112
113
+ #[ cfg( unix) ]
94
114
fn fuzz_single_forking < M > (
95
115
options : & LibfuzzerOptions ,
96
116
harness : & extern "C" fn ( * const u8 , usize ) -> c_int ,
@@ -121,9 +141,7 @@ where
121
141
} )
122
142
}
123
143
124
- /// Communicate the selected port to subprocesses
125
- const PORT_PROVIDER_VAR : & str = "_LIBAFL_LIBFUZZER_FORK_PORT" ;
126
-
144
+ #[ cfg( unix) ]
127
145
fn fuzz_many_forking < M > (
128
146
options : & LibfuzzerOptions ,
129
147
harness : & extern "C" fn ( * const u8 , usize ) -> c_int ,
@@ -134,6 +152,9 @@ fn fuzz_many_forking<M>(
134
152
where
135
153
M : Monitor + Clone + Debug + ' static ,
136
154
{
155
+ // Communicate the selected port to subprocesses
156
+ const PORT_PROVIDER_VAR : & str = "_LIBAFL_LIBFUZZER_FORK_PORT" ;
157
+
137
158
destroy_output_fds ( options) ;
138
159
let broker_port = std:: env:: var ( PORT_PROVIDER_VAR )
139
160
. map_err ( Error :: from)
@@ -194,35 +215,47 @@ pub fn fuzz(
194
215
options : & LibfuzzerOptions ,
195
216
harness : & extern "C" fn ( * const u8 , usize ) -> c_int ,
196
217
) -> Result < ( ) , Error > {
218
+ #[ cfg( unix) ]
197
219
if let Some ( forks) = options. forks ( ) {
198
220
let shmem_provider = StdShMemProvider :: new ( ) . expect ( "Failed to init shared memory" ) ;
221
+
222
+ #[ cfg( feature = "tui_monitor" ) ]
199
223
if options. tui ( ) {
200
224
let monitor = TuiMonitor :: builder ( )
201
225
. title ( options. fuzzer_name ( ) )
202
226
. enhanced_graphics ( true )
203
227
. build ( ) ;
204
- fuzz_many_forking ( options, harness, shmem_provider, forks, monitor)
205
- } else if forks == 1 {
206
- let monitor = MultiMonitor :: new ( create_monitor_closure ( ) ) ;
207
- fuzz_single_forking ( options, harness, shmem_provider, monitor)
208
- } else {
209
- let monitor = MultiMonitor :: new ( create_monitor_closure ( ) ) ;
210
- fuzz_many_forking ( options, harness, shmem_provider, forks, monitor)
228
+ return fuzz_many_forking ( options, harness, shmem_provider, forks, monitor) ;
211
229
}
212
- } else if options. tui ( ) {
230
+
231
+ // Non-TUI path or when tui_monitor feature is disabled
232
+ let monitor = MultiMonitor :: new ( create_monitor_closure ( ) ) ;
233
+
234
+ if forks == 1 {
235
+ return fuzz_single_forking ( options, harness, shmem_provider, monitor) ;
236
+ }
237
+
238
+ return fuzz_many_forking ( options, harness, shmem_provider, forks, monitor) ;
239
+ }
240
+
241
+ #[ cfg( feature = "tui_monitor" ) ]
242
+ if options. tui ( ) {
213
243
// if the user specifies TUI, we assume they want to fork; it would not be possible to use
214
244
// TUI safely otherwise
215
245
let shmem_provider = StdShMemProvider :: new ( ) . expect ( "Failed to init shared memory" ) ;
216
246
let monitor = TuiMonitor :: builder ( )
217
247
. title ( options. fuzzer_name ( ) )
218
248
. enhanced_graphics ( true )
219
249
. build ( ) ;
220
- fuzz_many_forking ( options, harness, shmem_provider, 1 , monitor)
221
- } else {
222
- destroy_output_fds ( options) ;
223
- fuzz_with ! ( options, harness, do_fuzz, |fuzz_single| {
224
- let mgr = SimpleEventManager :: new( MultiMonitor :: new( create_monitor_closure( ) ) ) ;
225
- crate :: start_fuzzing_single( fuzz_single, None , mgr)
226
- } )
250
+ return fuzz_many_forking ( options, harness, shmem_provider, 1 , monitor) ;
227
251
}
252
+
253
+ // Default path when no forks or TUI are specified, or when tui_monitor feature is disabled
254
+ #[ cfg( unix) ]
255
+ destroy_output_fds ( options) ;
256
+
257
+ fuzz_with ! ( options, harness, do_fuzz, |fuzz_single| {
258
+ let mgr = SimpleEventManager :: new( MultiMonitor :: new( create_monitor_closure( ) ) ) ;
259
+ crate :: start_fuzzing_single( fuzz_single, None , mgr)
260
+ } )
228
261
}
0 commit comments