/rust/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.10/src/lib.rs
Line  | Count  | Source  | 
1  |  | //! Bindings to [libFuzzer](http://llvm.org/docs/LibFuzzer.html): a runtime for  | 
2  |  | //! coverage-guided fuzzing.  | 
3  |  | //!  | 
4  |  | //! See [the `cargo-fuzz`  | 
5  |  | //! guide](https://rust-fuzz.github.io/book/cargo-fuzz.html) for a usage  | 
6  |  | //! tutorial.  | 
7  |  | //!  | 
8  |  | //! The main export of this crate is [the `fuzz_target!`  | 
9  |  | //! macro](./macro.fuzz_target.html), which allows you to define targets for  | 
10  |  | //! libFuzzer to exercise.  | 
11  |  |  | 
12  |  | #![deny(missing_docs, missing_debug_implementations)]  | 
13  |  |  | 
14  |  | pub use arbitrary;  | 
15  |  | use std::sync::OnceLock;  | 
16  |  |  | 
17  |  | /// Indicates whether the input should be kept in the corpus or rejected. This  | 
18  |  | /// should be returned by your fuzz target. If your fuzz target does not return  | 
19  |  | /// a value (i.e., returns `()`), then the input will be kept in the corpus.  | 
20  |  | #[derive(Debug)]  | 
21  |  | pub enum Corpus { | 
22  |  |     /// Keep the input in the corpus.  | 
23  |  |     Keep,  | 
24  |  |  | 
25  |  |     /// Reject the input and do not keep it in the corpus.  | 
26  |  |     Reject,  | 
27  |  | }  | 
28  |  |  | 
29  |  | impl From<()> for Corpus { | 
30  | 17.7k  |     fn from(_: ()) -> Self { | 
31  | 17.7k  |         Self::Keep  | 
32  | 17.7k  |     }  | 
33  |  | }  | 
34  |  |  | 
35  |  | impl Corpus { | 
36  |  |     #[doc(hidden)]  | 
37  |  |     /// Convert this Corpus result into the [integer codes used by  | 
38  |  |     /// `libFuzzer`](https://llvm.org/docs/LibFuzzer.html#rejecting-unwanted-inputs).  | 
39  |  |     /// This is -1 for reject, 0 for keep.  | 
40  | 17.7k  |     pub fn to_libfuzzer_code(self) -> i32 { | 
41  | 17.7k  |         match self { | 
42  | 17.7k  |             Corpus::Keep => 0,  | 
43  | 0  |             Corpus::Reject => -1,  | 
44  |  |         }  | 
45  | 17.7k  |     }  | 
46  |  | }  | 
47  |  |  | 
48  |  | extern "C" { | 
49  |  |     // We do not actually cross the FFI bound here.  | 
50  |  |     #[allow(improper_ctypes)]  | 
51  |  |     fn rust_fuzzer_test_input(input: &[u8]) -> i32;  | 
52  |  |  | 
53  |  |     fn LLVMFuzzerMutate(data: *mut u8, size: usize, max_size: usize) -> usize;  | 
54  |  | }  | 
55  |  |  | 
56  |  | /// Do not use; only for LibFuzzer's consumption.  | 
57  |  | #[doc(hidden)]  | 
58  |  | #[export_name = "LLVMFuzzerTestOneInput"]  | 
59  | 17.7k  | pub unsafe fn test_input_wrap(data: *const u8, size: usize) -> i32 { | 
60  | 17.7k  |     let test_input = ::std::panic::catch_unwind(|| { | 
61  | 17.7k  |         let data_slice = ::std::slice::from_raw_parts(data, size);  | 
62  | 17.7k  |         rust_fuzzer_test_input(data_slice)  | 
63  | 17.7k  |     });  | 
64  |  |  | 
65  | 17.7k  |     match test_input { | 
66  | 17.7k  |         Ok(i) => i,  | 
67  |  |         Err(_) => { | 
68  |  |             // hopefully the custom panic hook will be called before and abort the  | 
69  |  |             // process before the stack frames are unwinded.  | 
70  | 0  |             ::std::process::abort();  | 
71  |  |         }  | 
72  |  |     }  | 
73  | 17.7k  | }  | 
74  |  |  | 
75  |  | #[doc(hidden)]  | 
76  | 17.7k  | pub fn rust_libfuzzer_debug_path() -> &'static Option<String> { | 
77  |  |     static RUST_LIBFUZZER_DEBUG_PATH: OnceLock<Option<String>> = OnceLock::new();  | 
78  | 17.7k  |     RUST_LIBFUZZER_DEBUG_PATH.get_or_init(|| std::env::var("RUST_LIBFUZZER_DEBUG_PATH").ok()) | 
79  | 17.7k  | }  | 
80  |  |  | 
81  |  | #[doc(hidden)]  | 
82  | 4  | pub fn initialize(_argc: *const isize, _argv: *const *const *const u8) -> isize { | 
83  |  |     // Registers a panic hook that aborts the process before unwinding.  | 
84  |  |     // It is useful to abort before unwinding so that the fuzzer will then be  | 
85  |  |     // able to analyse the process stack frames to tell different bugs appart.  | 
86  |  |     //  | 
87  |  |     // HACK / FIXME: it would be better to use `-C panic=abort` but it's currently  | 
88  |  |     // impossible to build code using compiler plugins with this flag.  | 
89  |  |     // We will be able to remove this code when  | 
90  |  |     // https://github.com/rust-lang/cargo/issues/5423 is fixed.  | 
91  | 4  |     let default_hook = std::panic::take_hook();  | 
92  | 4  |     std::panic::set_hook(Box::new(move |panic_info| { | 
93  | 0  |         default_hook(panic_info);  | 
94  | 0  |         std::process::abort();  | 
95  |  |     }));  | 
96  | 4  |     0  | 
97  | 4  | }  | 
98  |  |  | 
99  |  | /// Define a fuzz target.  | 
100  |  | ///  | 
101  |  | /// ## Example  | 
102  |  | ///  | 
103  |  | /// This example takes a `&[u8]` slice and attempts to parse it. The parsing  | 
104  |  | /// might fail and return an `Err`, but it shouldn't ever panic or segfault.  | 
105  |  | ///  | 
106  |  | /// ```no_run  | 
107  |  | /// #![no_main]  | 
108  |  | ///  | 
109  |  | /// use libfuzzer_sys::fuzz_target;  | 
110  |  | ///  | 
111  |  | /// // Note: `|input|` is short for `|input: &[u8]|`.  | 
112  |  | /// fuzz_target!(|input| { | 
113  |  | ///     let _result: Result<_, _> = my_crate::parse(input);  | 
114  |  | /// });  | 
115  |  | /// # mod my_crate { pub fn parse(_: &[u8]) -> Result<(), ()> { unimplemented!() } } | 
116  |  | /// ```  | 
117  |  | ///  | 
118  |  | /// ## Rejecting Inputs  | 
119  |  | ///  | 
120  |  | /// It may be desirable to reject some inputs, i.e. to not add them to the  | 
121  |  | /// corpus.  | 
122  |  | ///  | 
123  |  | /// For example, when fuzzing an API consisting of parsing and other logic,  | 
124  |  | /// one may want to allow only those inputs into the corpus that parse  | 
125  |  | /// successfully. To indicate whether an input should be kept in or rejected  | 
126  |  | /// from the corpus, return either [Corpus::Keep] or [Corpus::Reject] from your  | 
127  |  | /// fuzz target. The default behavior (e.g. if `()` is returned) is to keep the  | 
128  |  | /// input in the corpus.  | 
129  |  | ///  | 
130  |  | /// For example:  | 
131  |  | ///  | 
132  |  | /// ```no_run  | 
133  |  | /// #![no_main]  | 
134  |  | ///  | 
135  |  | /// use libfuzzer_sys::{Corpus, fuzz_target}; | 
136  |  | ///  | 
137  |  | /// fuzz_target!(|input: String| -> Corpus { | 
138  |  | ///     let parts: Vec<&str> = input.splitn(2, '=').collect();  | 
139  |  | ///     if parts.len() != 2 { | 
140  |  | ///         return Corpus::Reject;  | 
141  |  | ///     }  | 
142  |  | ///  | 
143  |  | ///     let key = parts[0];  | 
144  |  | ///     let value = parts[1];  | 
145  |  | ///     let _result: Result<_, _> = my_crate::parse(key, value);  | 
146  |  | ///     Corpus::Keep  | 
147  |  | /// });  | 
148  |  | /// # mod my_crate { pub fn parse(_key: &str, _value: &str) -> Result<(), ()> { unimplemented!() } } | 
149  |  | /// ```  | 
150  |  | ///  | 
151  |  | /// ## Arbitrary Input Types  | 
152  |  | ///  | 
153  |  | /// The input is a `&[u8]` slice by default, but you can take arbitrary input  | 
154  |  | /// types, as long as the type implements [the `arbitrary` crate's `Arbitrary`  | 
155  |  | /// trait](https://docs.rs/arbitrary/*/arbitrary/trait.Arbitrary.html) (which is  | 
156  |  | /// also re-exported as `libfuzzer_sys::arbitrary::Arbitrary` for convenience).  | 
157  |  | ///  | 
158  |  | /// For example, if you wanted to take an arbitrary RGB color, you could do the  | 
159  |  | /// following:  | 
160  |  | ///  | 
161  |  | /// ```no_run  | 
162  |  | /// #![no_main]  | 
163  |  | /// # mod foo { | 
164  |  | ///  | 
165  |  | /// use libfuzzer_sys::{arbitrary::{Arbitrary, Error, Unstructured}, fuzz_target}; | 
166  |  | ///  | 
167  |  | /// #[derive(Debug)]  | 
168  |  | /// pub struct Rgb { | 
169  |  | ///     r: u8,  | 
170  |  | ///     g: u8,  | 
171  |  | ///     b: u8,  | 
172  |  | /// }  | 
173  |  | ///  | 
174  |  | /// impl<'a> Arbitrary<'a> for Rgb { | 
175  |  | ///     fn arbitrary(raw: &mut Unstructured<'a>) -> Result<Self, Error> { | 
176  |  | ///         let mut buf = [0; 3];  | 
177  |  | ///         raw.fill_buffer(&mut buf)?;  | 
178  |  | ///         let r = buf[0];  | 
179  |  | ///         let g = buf[1];  | 
180  |  | ///         let b = buf[2];  | 
181  |  | ///         Ok(Rgb { r, g, b }) | 
182  |  | ///     }  | 
183  |  | /// }  | 
184  |  | ///  | 
185  |  | /// // Write a fuzz target that works with RGB colors instead of raw bytes.  | 
186  |  | /// fuzz_target!(|color: Rgb| { | 
187  |  | ///     my_crate::convert_color(color);  | 
188  |  | /// });  | 
189  |  | /// # mod my_crate { | 
190  |  | /// #     use super::Rgb;  | 
191  |  | /// #     pub fn convert_color(_: Rgb) {} | 
192  |  | /// # }  | 
193  |  | /// # }  | 
194  |  | /// ```  | 
195  |  | ///  | 
196  |  | /// You can also enable the `arbitrary` crate's custom derive via this crate's  | 
197  |  | /// `"arbitrary-derive"` cargo feature.  | 
198  |  | ///  | 
199  |  | /// ## Init Code  | 
200  |  | ///  | 
201  |  | /// Init code to the fuzz target by using the `init` keyword. This is called once before the fuzzer starts.  | 
202  |  | /// Supports short |input| or |input: <type>| syntax.  | 
203  |  | ///  | 
204  |  | /// ```no_run  | 
205  |  | /// #![no_main]  | 
206  |  | ///  | 
207  |  | /// use libfuzzer_sys::fuzz_target;  | 
208  |  | /// use std::collections::HashSet;  | 
209  |  | /// use std::sync::OnceLock;  | 
210  |  | ///  | 
211  |  | /// static DICTIONARY: OnceLock<HashSet<String>> = OnceLock::new();  | 
212  |  | ///  | 
213  |  | /// fuzz_target!(  | 
214  |  | ///     init: { | 
215  |  | ///         let read_dictionary = |_| unimplemented!();  | 
216  |  | ///         let dictionary = read_dictionary("/usr/share/dict/words"); | 
217  |  | ///         DICTIONARY.set(dictionary).unwrap();  | 
218  |  | ///     },  | 
219  |  | ///     |input| { | 
220  |  | ///         // Use the initialized `DICTIONARY` here...  | 
221  |  | ///     }  | 
222  |  | /// );  | 
223  |  | /// ```  | 
224  |  | ///  | 
225  |  | #[macro_export]  | 
226  |  | macro_rules! fuzz_target { | 
227  |  |     (|$bytes:ident| $body:expr) => { | 
228  |  |         $crate::fuzz_target!(init: (), |$bytes: &[u8]| -> () { $body }); | 
229  |  |     };  | 
230  |  |  | 
231  |  |     (|$bytes:ident: &[u8]| $body:expr) => { | 
232  |  |         $crate::fuzz_target!(init: (), |$bytes: &[u8]| -> () { $body }); | 
233  |  |     };  | 
234  |  |  | 
235  |  |     (|$bytes:ident: &[u8]| -> $rty:ty $body:block) => { | 
236  |  |         $crate::fuzz_target!(init: (), |$bytes: &[u8]| -> $rty { $body }); | 
237  |  |     };  | 
238  |  |  | 
239  |  |     (init: $init:expr, |$bytes:ident| $body:expr) => { | 
240  |  |         $crate::fuzz_target!(init: $init, |$bytes: &[u8]| -> () { $body }); | 
241  |  |     };  | 
242  |  |  | 
243  |  |     (init: $init:expr, |$bytes:ident: &[u8]| $body:expr) => { | 
244  |  |         $crate::fuzz_target!(init: $init, |$bytes: &[u8]| -> () { $body }); | 
245  |  |     };  | 
246  |  |  | 
247  |  |     (init: $init:expr, |$bytes:ident: &[u8]| -> $rty:ty $body:block) => { | 
248  |  |         const _: () = { | 
249  |  |             /// Auto-generated functions  | 
250  |  |             /// LLVMFuzzerInitialize is called once before the fuzzer starts.  | 
251  |  |             #[no_mangle]  | 
252  |  |             pub extern "C" fn LLVMFuzzerInitialize(_argc: *const isize, _argv: *const *const *const u8) -> isize { | 
253  |  |                 $crate::initialize(_argc, _argv);  | 
254  |  |  | 
255  |  |                 // Supplied init code  | 
256  |  |                 $init;  | 
257  |  |                 0  | 
258  |  |             }  | 
259  |  |  | 
260  |  |             #[no_mangle]  | 
261  |  |             pub extern "C" fn rust_fuzzer_test_input(bytes: &[u8]) -> i32 { | 
262  |  |                 // When `RUST_LIBFUZZER_DEBUG_PATH` is set, write the debug  | 
263  |  |                 // formatting of the input to that file. This is only intended for  | 
264  |  |                 // `cargo fuzz`'s use!  | 
265  |  |  | 
266  |  |                 // `RUST_LIBFUZZER_DEBUG_PATH` is set in initialization.  | 
267  |  |                 if let Some(path) = $crate::rust_libfuzzer_debug_path() { | 
268  |  |                     use std::io::Write;  | 
269  |  |                     let mut file = std::fs::File::create(path)  | 
270  |  |                         .expect("failed to create `RUST_LIBFUZZER_DEBUG_PATH` file"); | 
271  |  |                     writeln!(&mut file, "{:?}", bytes) | 
272  |  |                         .expect("failed to write to `RUST_LIBFUZZER_DEBUG_PATH` file"); | 
273  |  |                     return 0;  | 
274  |  |                 }  | 
275  |  |  | 
276  |  |                 let result = ::libfuzzer_sys::Corpus::from(__libfuzzer_sys_run(bytes));  | 
277  |  |                 result.to_libfuzzer_code()  | 
278  |  |             }  | 
279  |  |  | 
280  |  |             // Split out the actual fuzzer into a separate function which is  | 
281  |  |             // tagged as never being inlined. This ensures that if the fuzzer  | 
282  |  |             // panics there's at least one stack frame which is named uniquely  | 
283  |  |             // according to this specific fuzzer that this is embedded within.  | 
284  |  |             //  | 
285  |  |             // Systems like oss-fuzz try to deduplicate crashes and without this  | 
286  |  |             // panics in separate fuzzers can accidentally appear the same  | 
287  |  |             // because each fuzzer will have a function called  | 
288  |  |             // `rust_fuzzer_test_input`. By using a normal Rust function here  | 
289  |  |             // it's named something like `the_fuzzer_name::_::__libfuzzer_sys_run` which should  | 
290  |  |             // ideally help prevent oss-fuzz from deduplicate fuzz bugs across  | 
291  |  |             // distinct targets accidentally.  | 
292  |  |             #[inline(never)]  | 
293  |  |             fn __libfuzzer_sys_run($bytes: &[u8]) -> $rty { | 
294  |  |                 $body  | 
295  |  |             }  | 
296  |  |         };  | 
297  |  |     };  | 
298  |  |  | 
299  |  |     (|$data:ident: $dty:ty| $body:expr) => { | 
300  |  |         $crate::fuzz_target!(init: (), |$data: $dty| -> () { $body }); | 
301  |  |     };  | 
302  |  |  | 
303  |  |     (|$data:ident: $dty:ty| -> $rty:ty $body:block) => { | 
304  |  |         $crate::fuzz_target!(init: (), |$data: $dty| -> $rty { $body }); | 
305  |  |     };  | 
306  |  |  | 
307  |  |     (init: $init:expr, |$data:ident: $dty:ty| $body:expr) => { | 
308  |  |         $crate::fuzz_target!(init: $init, |$data: $dty| -> () { $body }); | 
309  |  |     };  | 
310  |  |  | 
311  |  |     (init: $init:expr, |$data:ident: $dty:ty| -> $rty:ty $body:block) => { | 
312  |  |         const _: () = { | 
313  |  |             /// Auto-generated functions  | 
314  |  |             /// LLVMFuzzerInitialize is called once before the fuzzer starts.  | 
315  |  |             #[no_mangle]  | 
316  | 2  |             pub extern "C" fn LLVMFuzzerInitialize(_argc: *const isize, _argv: *const *const *const u8) -> isize { | 
317  | 2  |                 $crate::initialize(_argc, _argv);  | 
318  |  |  | 
319  |  |                 // Supplied init code  | 
320  |  |                 $init;  | 
321  | 2  |                 0  | 
322  | 2  |             }  | 
323  |  |  | 
324  |  |             #[no_mangle]  | 
325  | 12.7k  |             pub extern "C" fn rust_fuzzer_test_input(bytes: &[u8]) -> i32 { | 
326  |  |                 use $crate::arbitrary::{Arbitrary, Unstructured}; | 
327  |  |  | 
328  |  |                 // Early exit if we don't have enough bytes for the `Arbitrary`  | 
329  |  |                 // implementation. This helps the fuzzer avoid exploring all the  | 
330  |  |                 // different not-enough-input-bytes paths inside the `Arbitrary`  | 
331  |  |                 // implementation. Additionally, it exits faster, letting the fuzzer  | 
332  |  |                 // get to longer inputs that actually lead to interesting executions  | 
333  |  |                 // quicker.  | 
334  | 12.7k  |                 if bytes.len() < <$dty as Arbitrary>::size_hint(0).0 { | 
335  | 15  |                     return -1;  | 
336  | 12.6k  |                 }  | 
337  |  |  | 
338  | 12.6k  |                 let mut u = Unstructured::new(bytes);  | 
339  | 12.6k  |                 let data = <$dty as Arbitrary>::arbitrary_take_rest(u);  | 
340  |  |  | 
341  |  |                 // When `RUST_LIBFUZZER_DEBUG_PATH` is set, write the debug  | 
342  |  |                 // formatting of the input to that file. This is only intended for  | 
343  |  |                 // `cargo fuzz`'s use!  | 
344  |  |  | 
345  |  |                 // `RUST_LIBFUZZER_DEBUG_PATH` is set in initialization.  | 
346  | 12.6k  |                 if let Some(path) = $crate::rust_libfuzzer_debug_path() { | 
347  |  |                     use std::io::Write;  | 
348  | 0  |                     let mut file = std::fs::File::create(path)  | 
349  | 0  |                         .expect("failed to create `RUST_LIBFUZZER_DEBUG_PATH` file"); | 
350  | 0  |                     (match data { | 
351  | 0  |                         Ok(data) => writeln!(&mut file, "{:#?}", data), | 
352  | 0  |                         Err(err) => writeln!(&mut file, "Arbitrary Error: {}", err), | 
353  |  |                     })  | 
354  | 0  |                     .expect("failed to write to `RUST_LIBFUZZER_DEBUG_PATH` file"); | 
355  | 0  |                     return -1;  | 
356  | 12.6k  |                 }  | 
357  |  |  | 
358  | 12.6k  |                 let data = match data { | 
359  | 12.6k  |                     Ok(d) => d,  | 
360  | 0  |                     Err(_) => return -1,  | 
361  |  |                 };  | 
362  |  |  | 
363  | 12.6k  |                 let result = ::libfuzzer_sys::Corpus::from(__libfuzzer_sys_run(data));  | 
364  | 12.6k  |                 result.to_libfuzzer_code()  | 
365  | 12.7k  |             }  | 
366  |  |             // See above for why this is split to a separate function.  | 
367  |  |             #[inline(never)]  | 
368  | 17.7k  |             fn __libfuzzer_sys_run($data: $dty) -> $rty { | 
369  |  |                 $body  | 
370  | 17.7k  |             } roundtrip::_::__libfuzzer_sys_run Line  | Count  | Source  |  368  | 12.6k  |             fn __libfuzzer_sys_run($data: $dty) -> $rty { |  369  |  |                 $body  |  370  | 12.6k  |             }  |  
 decompress::_::__libfuzzer_sys_run Line  | Count  | Source  |  368  | 5.02k  |             fn __libfuzzer_sys_run($data: $dty) -> $rty { |  369  |  |                 $body  |  370  | 5.02k  |             }  |  
  | 
371  |  |         };  | 
372  |  |     };  | 
373  |  | }  | 
374  |  |  | 
375  |  | /// Define a custom mutator.  | 
376  |  | ///  | 
377  |  | /// This is optional, and libFuzzer will use its own, default mutation strategy  | 
378  |  | /// if this is not provided.  | 
379  |  | ///  | 
380  |  | /// You might consider using a custom mutator when your fuzz target is very  | 
381  |  | /// particular about the shape of its input:  | 
382  |  | ///  | 
383  |  | /// * You want to fuzz "deeper" than just the parser.  | 
384  |  | /// * The input contains checksums that have to match the hash of some subset of  | 
385  |  | ///   the data or else the whole thing is invalid, and therefore mutating any of  | 
386  |  | ///   that subset means you need to recompute the checksums.  | 
387  |  | /// * Small random changes to the input buffer make it invalid.  | 
388  |  | ///  | 
389  |  | /// That is, a custom mutator is useful in similar situations where [a `T:  | 
390  |  | /// Arbitrary` input type](macro.fuzz_target.html#arbitrary-input-types) is  | 
391  |  | /// useful. Note that the two approaches are not mutually exclusive; you can use  | 
392  |  | /// whichever is easier for your problem domain or both!  | 
393  |  | ///  | 
394  |  | /// ## Implementation Contract  | 
395  |  | ///  | 
396  |  | /// The original, unmodified input is given in `data[..size]`.  | 
397  |  | ///  | 
398  |  | /// You must modify the data in place and return the new size.  | 
399  |  | ///  | 
400  |  | /// The new size should not be greater than `max_size`. If this is not the case,  | 
401  |  | /// then the `data` will be truncated to fit within `max_size`. Note that  | 
402  |  | /// `max_size < size` is possible when shrinking test cases.  | 
403  |  | ///  | 
404  |  | /// You must produce the same mutation given the same `seed`. Generally, when  | 
405  |  | /// choosing what kind of mutation to make or where to mutate, you should start  | 
406  |  | /// by creating a random number generator (RNG) that is seeded with the given  | 
407  |  | /// `seed` and then consult the RNG whenever making a decision:  | 
408  |  | ///  | 
409  |  | /// ```no_run  | 
410  |  | /// #![no_main]  | 
411  |  | ///  | 
412  |  | /// use rand::{rngs::StdRng, Rng, SeedableRng}; | 
413  |  | ///  | 
414  |  | /// libfuzzer_sys::fuzz_mutator!(|data: &mut [u8], size: usize, max_size: usize, seed: u32| { | 
415  |  | ///     let mut rng = StdRng::seed_from_u64(seed as u64);  | 
416  |  | ///  | 
417  |  | /// #   let first_mutation = |_, _, _, _| todo!();  | 
418  |  | /// #   let second_mutation = |_, _, _, _| todo!();  | 
419  |  | /// #   let third_mutation = |_, _, _, _| todo!();  | 
420  |  | /// #   let fourth_mutation = |_, _, _, _| todo!();  | 
421  |  | ///     // Choose which of our four supported kinds of mutations we want to make.  | 
422  |  | ///     match rng.gen_range(0..4) { | 
423  |  | ///         0 => first_mutation(rng, data, size, max_size),  | 
424  |  | ///         1 => second_mutation(rng, data, size, max_size),  | 
425  |  | ///         2 => third_mutation(rng, data, size, max_size),  | 
426  |  | ///         3 => fourth_mutation(rng, data, size, max_size),  | 
427  |  | ///         _ => unreachable!()  | 
428  |  | ///     }  | 
429  |  | /// });  | 
430  |  | /// ```  | 
431  |  | ///  | 
432  |  | /// ## Example: Compression  | 
433  |  | ///  | 
434  |  | /// Consider a simple fuzz target that takes compressed data as input,  | 
435  |  | /// decompresses it, and then asserts that the decompressed data doesn't begin  | 
436  |  | /// with "boom". It is difficult for `libFuzzer` (or any other fuzzer) to crash  | 
437  |  | /// this fuzz target because nearly all mutations it makes will invalidate the  | 
438  |  | /// compression format. Therefore, we use a custom mutator that decompresses the  | 
439  |  | /// raw input, mutates the decompressed data, and then recompresses it. This  | 
440  |  | /// allows `libFuzzer` to quickly discover crashing inputs.  | 
441  |  | ///  | 
442  |  | /// ```no_run  | 
443  |  | /// #![no_main]  | 
444  |  | ///  | 
445  |  | /// use flate2::{read::GzDecoder, write::GzEncoder, Compression}; | 
446  |  | /// use libfuzzer_sys::{fuzz_mutator, fuzz_target}; | 
447  |  | /// use std::io::{Read, Write}; | 
448  |  | ///  | 
449  |  | /// fuzz_target!(|data: &[u8]| { | 
450  |  | ///     // Decompress the input data and crash if it starts with "boom".  | 
451  |  | ///     if let Some(data) = decompress(data) { | 
452  |  | ///         if data.starts_with(b"boom") { | 
453  |  | ///             panic!();  | 
454  |  | ///         }  | 
455  |  | ///     }  | 
456  |  | /// });  | 
457  |  | ///  | 
458  |  | /// fuzz_mutator!(  | 
459  |  | ///     |data: &mut [u8], size: usize, max_size: usize, _seed: u32| { | 
460  |  | ///         // Decompress the input data. If that fails, use a dummy value.  | 
461  |  | ///         let mut decompressed = decompress(&data[..size]).unwrap_or_else(|| b"hi".to_vec());  | 
462  |  | ///  | 
463  |  | ///         // Mutate the decompressed data with `libFuzzer`'s default mutator. Make  | 
464  |  | ///         // the `decompressed` vec's extra capacity available for insertion  | 
465  |  | ///         // mutations via `resize`.  | 
466  |  | ///         let len = decompressed.len();  | 
467  |  | ///         let cap = decompressed.capacity();  | 
468  |  | ///         decompressed.resize(cap, 0);  | 
469  |  | ///         let new_decompressed_size = libfuzzer_sys::fuzzer_mutate(&mut decompressed, len, cap);  | 
470  |  | ///  | 
471  |  | ///         // Recompress the mutated data.  | 
472  |  | ///         let compressed = compress(&decompressed[..new_decompressed_size]);  | 
473  |  | ///  | 
474  |  | ///         // Copy the recompressed mutated data into `data` and return the new size.  | 
475  |  | ///         let new_size = std::cmp::min(max_size, compressed.len());  | 
476  |  | ///         data[..new_size].copy_from_slice(&compressed[..new_size]);  | 
477  |  | ///         new_size  | 
478  |  | ///     }  | 
479  |  | /// );  | 
480  |  | ///  | 
481  |  | /// fn decompress(compressed_data: &[u8]) -> Option<Vec<u8>> { | 
482  |  | ///     let mut decoder = GzDecoder::new(compressed_data);  | 
483  |  | ///     let mut decompressed = Vec::new();  | 
484  |  | ///     if decoder.read_to_end(&mut decompressed).is_ok() { | 
485  |  | ///         Some(decompressed)  | 
486  |  | ///     } else { | 
487  |  | ///         None  | 
488  |  | ///     }  | 
489  |  | /// }  | 
490  |  | ///  | 
491  |  | /// fn compress(data: &[u8]) -> Vec<u8> { | 
492  |  | ///     let mut encoder = GzEncoder::new(Vec::new(), Compression::default());  | 
493  |  | ///     encoder  | 
494  |  | ///         .write_all(data)  | 
495  |  | ///         .expect("writing into a vec is infallible"); | 
496  |  | ///     encoder.finish().expect("writing into a vec is infallible") | 
497  |  | /// }  | 
498  |  | /// ```  | 
499  |  | ///  | 
500  |  | /// This example is inspired by [a similar example from the official `libFuzzer`  | 
501  |  | /// docs](https://github.com/google/fuzzing/blob/master/docs/structure-aware-fuzzing.md#example-compression).  | 
502  |  | ///  | 
503  |  | /// ## More Example Ideas  | 
504  |  | ///  | 
505  |  | /// * A PNG custom mutator that decodes a PNG, mutates the image, and then  | 
506  |  | /// re-encodes the mutated image as a new PNG.  | 
507  |  | ///  | 
508  |  | /// * A [`serde`](https://serde.rs/) custom mutator that deserializes your  | 
509  |  | ///   structure, mutates it, and then reserializes it.  | 
510  |  | ///  | 
511  |  | /// * A Wasm binary custom mutator that inserts, replaces, and removes a  | 
512  |  | ///   bytecode instruction in a function's body.  | 
513  |  | ///  | 
514  |  | /// * An HTTP request custom mutator that inserts, replaces, and removes a  | 
515  |  | ///   header from an HTTP request.  | 
516  |  | #[macro_export]  | 
517  |  | macro_rules! fuzz_mutator { | 
518  |  |     (  | 
519  |  |         |  | 
520  |  |         $data:ident : &mut [u8] ,  | 
521  |  |         $size:ident : usize ,  | 
522  |  |         $max_size:ident : usize ,  | 
523  |  |         $seed:ident : u32 $(,)*  | 
524  |  |         |  | 
525  |  |         $body:block  | 
526  |  |     ) => { | 
527  |  |         /// Auto-generated function. Do not use; only for LibFuzzer's  | 
528  |  |         /// consumption.  | 
529  |  |         #[export_name = "LLVMFuzzerCustomMutator"]  | 
530  |  |         #[doc(hidden)]  | 
531  |  |         pub unsafe fn rust_fuzzer_custom_mutator(  | 
532  |  |             $data: *mut u8,  | 
533  |  |             $size: usize,  | 
534  |  |             $max_size: usize,  | 
535  |  |             $seed: std::os::raw::c_uint,  | 
536  |  |         ) -> usize { | 
537  |  |             // Depending on if we are growing or shrinking the test case, `size`  | 
538  |  |             // might be larger or smaller than `max_size`. The `data`'s capacity  | 
539  |  |             // is the maximum of the two.  | 
540  |  |             let len = std::cmp::max($max_size, $size);  | 
541  |  |             let $data: &mut [u8] = std::slice::from_raw_parts_mut($data, len);  | 
542  |  |  | 
543  |  |             // `unsigned int` is generally a `u32`, but not on all targets. Do  | 
544  |  |             // an infallible (and potentially lossy, but that's okay because it  | 
545  |  |             // preserves determinism) conversion.  | 
546  |  |             let $seed = $seed as u32;  | 
547  |  |  | 
548  |  |             // Define and invoke a new, safe function so that the body doesn't  | 
549  |  |             // inherit `unsafe`.  | 
550  |  |             fn custom_mutator(  | 
551  |  |                 $data: &mut [u8],  | 
552  |  |                 $size: usize,  | 
553  |  |                 $max_size: usize,  | 
554  |  |                 $seed: u32,  | 
555  |  |             ) -> usize { | 
556  |  |                 $body  | 
557  |  |             }  | 
558  |  |             let new_size = custom_mutator($data, $size, $max_size, $seed);  | 
559  |  |  | 
560  |  |             // Truncate the new size if it is larger than the max.  | 
561  |  |             std::cmp::min(new_size, $max_size)  | 
562  |  |         }  | 
563  |  |     };  | 
564  |  | }  | 
565  |  |  | 
566  |  | /// The default `libFuzzer` mutator.  | 
567  |  | ///  | 
568  |  | /// You generally don't have to use this at all unless you're defining a  | 
569  |  | /// custom mutator with [the `fuzz_mutator!` macro][crate::fuzz_mutator].  | 
570  |  | ///  | 
571  |  | /// Mutates `data[..size]` in place such that the mutated data is no larger than  | 
572  |  | /// `max_size` and returns the new size of the mutated data.  | 
573  |  | ///  | 
574  |  | /// To only allow shrinking mutations, make `max_size < size`.  | 
575  |  | ///  | 
576  |  | /// To additionally allow mutations that grow the size of the data, make  | 
577  |  | /// `max_size > size`.  | 
578  |  | ///  | 
579  |  | /// Both `size` and `max_size` must be less than or equal to `data.len()`.  | 
580  |  | ///  | 
581  |  | /// # Example  | 
582  |  | ///  | 
583  |  | /// ```no_run  | 
584  |  | /// // Create some data in a buffer.  | 
585  |  | /// let mut data = vec![0; 128];  | 
586  |  | /// data[..b"hello".len()].copy_from_slice(b"hello");  | 
587  |  | ///  | 
588  |  | /// // Ask `libFuzzer` to mutate the data. By setting `max_size` to our buffer's  | 
589  |  | /// // full length, we are allowing `libFuzzer` to perform mutations that grow  | 
590  |  | /// // the size of the data, such as insertions.  | 
591  |  | /// let size = b"hello".len();  | 
592  |  | /// let max_size = data.len();  | 
593  |  | /// let new_size = libfuzzer_sys::fuzzer_mutate(&mut data, size, max_size);  | 
594  |  | ///  | 
595  |  | /// // Get the mutated data out of the buffer.  | 
596  |  | /// let mutated_data = &data[..new_size];  | 
597  |  | /// ```  | 
598  | 0  | pub fn fuzzer_mutate(data: &mut [u8], size: usize, max_size: usize) -> usize { | 
599  | 0  |     assert!(size <= data.len());  | 
600  | 0  |     assert!(max_size <= data.len());  | 
601  | 0  |     let new_size = unsafe { LLVMFuzzerMutate(data.as_mut_ptr(), size, max_size) }; | 
602  | 0  |     assert!(new_size <= data.len());  | 
603  | 0  |     new_size  | 
604  | 0  | }  | 
605  |  |  | 
606  |  | /// Define a custom cross-over function to combine test cases.  | 
607  |  | ///  | 
608  |  | /// This is optional, and libFuzzer will use its own, default cross-over strategy  | 
609  |  | /// if this is not provided. (As of the time of writing, this default strategy  | 
610  |  | /// takes alternating byte sequences from the two test cases, to construct the  | 
611  |  | /// new one) (see `FuzzerCrossOver.cpp`)  | 
612  |  | ///  | 
613  |  | /// This could potentially be useful if your input is, for instance, a  | 
614  |  | /// sequence of fixed sized, multi-byte values and the crossover could then  | 
615  |  | /// merge discrete values rather than joining parts of a value.  | 
616  |  | ///  | 
617  |  | /// ## Implementation Contract  | 
618  |  | ///  | 
619  |  | /// The original, read-only inputs are given in the full slices of `data1`, and  | 
620  |  | /// `data2` (as opposed to the, potentially, partial slice of `data` in  | 
621  |  | /// [the `fuzz_mutator!` macro][crate::fuzz_mutator]).  | 
622  |  | ///  | 
623  |  | /// You must place the new input merged from the two existing inputs' data  | 
624  |  | /// into `out` and return the size of the relevant data written to that slice.  | 
625  |  | ///  | 
626  |  | /// The deterministic requirements from [the `fuzz_mutator!` macro][crate::fuzz_mutator]  | 
627  |  | /// apply as well to the `seed` parameter  | 
628  |  | ///  | 
629  |  | /// ## Example: Floating-Point Sum NaN  | 
630  |  | ///  | 
631  |  | /// ```no_run  | 
632  |  | /// #![no_main]  | 
633  |  | ///  | 
634  |  | /// use libfuzzer_sys::{fuzz_crossover, fuzz_mutator, fuzz_target, fuzzer_mutate}; | 
635  |  | /// use rand::{rngs::StdRng, Rng, SeedableRng}; | 
636  |  | /// use std::mem::size_of;  | 
637  |  | ///  | 
638  |  | /// fuzz_target!(|data: &[u8]| { | 
639  |  | ///     let (_, floats, _) = unsafe { data.align_to::<f64>() }; | 
640  |  | ///  | 
641  |  | ///     let res = floats  | 
642  |  | ///         .iter()  | 
643  |  | ///         .fold(0.0, |a, b| if b.is_nan() { a } else { a + b }); | 
644  |  | ///  | 
645  |  | ///     assert!(  | 
646  |  | ///         !res.is_nan(),  | 
647  |  | ///         "The sum of the following floats resulted in a NaN: {floats:?}" | 
648  |  | ///     );  | 
649  |  | /// });  | 
650  |  | ///  | 
651  |  | /// // Inject some ...potentially problematic values to make the example close  | 
652  |  | /// // more quickly.  | 
653  |  | /// fuzz_mutator!(|data: &mut [u8], size: usize, max_size: usize, seed: u32| { | 
654  |  | ///     let mut gen = StdRng::seed_from_u64(seed.into());  | 
655  |  | ///  | 
656  |  | ///     let (_, floats, _) = unsafe { data[..size].align_to_mut::<f64>() }; | 
657  |  | ///  | 
658  |  | ///     let x = gen.gen_range(0..=1000);  | 
659  |  | ///     if x == 0 && !floats.is_empty() { | 
660  |  | ///         floats[0] = f64::INFINITY;  | 
661  |  | ///     } else if x == 1000 && floats.len() > 1 { | 
662  |  | ///         floats[1] = f64::NEG_INFINITY;  | 
663  |  | ///     } else { | 
664  |  | ///         return fuzzer_mutate(data, size, max_size);  | 
665  |  | ///     }  | 
666  |  | ///  | 
667  |  | ///     size  | 
668  |  | /// });  | 
669  |  | ///  | 
670  |  | /// fuzz_crossover!(|data1: &[u8], data2: &[u8], out: &mut [u8], _seed: u32| { | 
671  |  | ///     // Decode each source to see how many floats we can pull with proper  | 
672  |  | ///     // alignment, and destination as to how many will fit with proper alignment  | 
673  |  | ///     //  | 
674  |  | ///     // Keep track of the unaligned prefix to `out`, as we will need to remember  | 
675  |  | ///     // that those bytes will remain prepended to the actual floats that we  | 
676  |  | ///     // write into the out buffer.  | 
677  |  | ///     let (out_pref, out_floats, _) = unsafe { out.align_to_mut::<f64>() }; | 
678  |  | ///     let (_, d1_floats, _) = unsafe { data1.align_to::<f64>() }; | 
679  |  | ///     let (_, d2_floats, _) = unsafe { data2.align_to::<f64>() }; | 
680  |  | ///  | 
681  |  | ///     // Put into the destination, floats first from data1 then from data2, ...if  | 
682  |  | ///     // possible given the size of `out`  | 
683  |  | ///     let mut i: usize = 0;  | 
684  |  | ///     for float in d1_floats.iter().chain(d2_floats).take(out_floats.len()) { | 
685  |  | ///         out_floats[i] = *float;  | 
686  |  | ///         i += 1;  | 
687  |  | ///     }  | 
688  |  | ///  | 
689  |  | ///     // Now that we have written the true floats, report back to the fuzzing  | 
690  |  | ///     // engine that we left the unaligned `out` prefix bytes at the beginning of  | 
691  |  | ///     // `out` and also then the floats that we wrote into the aligned float  | 
692  |  | ///     // section.  | 
693  |  | ///     out_pref.len() * size_of::<u8>() + i * size_of::<f64>()  | 
694  |  | /// });  | 
695  |  | /// ```  | 
696  |  | ///  | 
697  |  | /// This example is a minimized version of [Erik Rigtorp's floating point  | 
698  |  | /// summation fuzzing example][1]. A more detailed version of this experiment  | 
699  |  | /// can be found in the `example_crossover` directory.  | 
700  |  | ///  | 
701  |  | /// [1]: https://rigtorp.se/fuzzing-floating-point-code/  | 
702  |  | #[macro_export]  | 
703  |  | macro_rules! fuzz_crossover { | 
704  |  |     (  | 
705  |  |         |  | 
706  |  |         $data1:ident : &[u8] ,  | 
707  |  |         $data2:ident : &[u8] ,  | 
708  |  |         $out:ident : &mut [u8] ,  | 
709  |  |         $seed:ident : u32 $(,)*  | 
710  |  |         |  | 
711  |  |         $body:block  | 
712  |  |     ) => { | 
713  |  |         /// Auto-generated function. Do not use; only for LibFuzzer's  | 
714  |  |         /// consumption.  | 
715  |  |         #[export_name = "LLVMFuzzerCustomCrossOver"]  | 
716  |  |         #[doc(hidden)]  | 
717  |  |         pub unsafe fn rust_fuzzer_custom_crossover(  | 
718  |  |             $data1: *const u8,  | 
719  |  |             size1: usize,  | 
720  |  |             $data2: *const u8,  | 
721  |  |             size2: usize,  | 
722  |  |             $out: *mut u8,  | 
723  |  |             max_out_size: usize,  | 
724  |  |             $seed: std::os::raw::c_uint,  | 
725  |  |         ) -> usize { | 
726  |  |             let $data1: &[u8] = std::slice::from_raw_parts($data1, size1);  | 
727  |  |             let $data2: &[u8] = std::slice::from_raw_parts($data2, size2);  | 
728  |  |             let $out: &mut [u8] = std::slice::from_raw_parts_mut($out, max_out_size);  | 
729  |  |  | 
730  |  |             // `unsigned int` is generally a `u32`, but not on all targets. Do  | 
731  |  |             // an infallible (and potentially lossy, but that's okay because it  | 
732  |  |             // preserves determinism) conversion.  | 
733  |  |             let $seed = $seed as u32;  | 
734  |  |  | 
735  |  |             // Define and invoke a new, safe function so that the body doesn't  | 
736  |  |             // inherit `unsafe`.  | 
737  |  |             fn custom_crossover(  | 
738  |  |                 $data1: &[u8],  | 
739  |  |                 $data2: &[u8],  | 
740  |  |                 $out: &mut [u8],  | 
741  |  |                 $seed: u32,  | 
742  |  |             ) -> usize { | 
743  |  |                 $body  | 
744  |  |             }  | 
745  |  |  | 
746  |  |             custom_crossover($data1, $data2, $out, $seed)  | 
747  |  |         }  | 
748  |  |     };  | 
749  |  | }  |