• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: Apache-2.0
2 
3 use std::fs::File;
4 use std::io::Read;
5 use std::io::Write;
6 use std::os::raw::c_int;
7 use std::os::unix::io::{FromRawFd, RawFd};
8 
9 use ciborium::{de::from_reader, value::Value};
10 use rand::Rng;
11 
12 const ITERATIONS: usize = 128 * 1024;
13 
14 #[allow(non_camel_case_types)]
15 type pid_t = i32;
16 
17 extern "C" {
close(fd: RawFd) -> c_int18     fn close(fd: RawFd) -> c_int;
fork() -> pid_t19     fn fork() -> pid_t;
pipe(pipefd: &mut [RawFd; 2]) -> c_int20     fn pipe(pipefd: &mut [RawFd; 2]) -> c_int;
waitpid(pid: pid_t, wstatus: *mut c_int, options: c_int) -> pid_t21     fn waitpid(pid: pid_t, wstatus: *mut c_int, options: c_int) -> pid_t;
22 }
23 
24 #[test]
fuzz()25 fn fuzz() {
26     let mut fds: [RawFd; 2] = [0; 2];
27     assert_eq!(unsafe { pipe(&mut fds) }, 0);
28 
29     let pid = unsafe { fork() };
30     assert!(pid >= 0);
31 
32     match pid {
33         0 => {
34             let mut child = unsafe { File::from_raw_fd(fds[1]) };
35             unsafe { close(fds[0]) };
36 
37             let mut rng = rand::thread_rng();
38             let mut buffer = [0u8; 32];
39 
40             for _ in 0..ITERATIONS {
41                 let len = rng.gen_range(0..buffer.len());
42                 rng.fill(&mut buffer[..len]);
43 
44                 writeln!(child, "{}", hex::encode(&buffer[..len])).unwrap();
45                 writeln!(child, "{:?}", from_reader::<Value, _>(&buffer[..len])).unwrap();
46             }
47         }
48 
49         pid => {
50             let mut parent = unsafe { File::from_raw_fd(fds[0]) };
51             unsafe { close(fds[1]) };
52 
53             let mut string = String::new();
54             parent.read_to_string(&mut string).unwrap();
55             eprint!("{}", string);
56 
57             let mut status = 0;
58             assert_eq!(pid, unsafe { waitpid(pid, &mut status, 0) });
59 
60             eprintln!("exit status: {:?}", status);
61             assert_eq!(0, status);
62         }
63     }
64 }
65