From 39b60599106040562bca705297d7a7768b2587f5 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 1 Apr 2024 00:56:22 +0200 Subject: [PATCH 1/4] rustfmt the expr fuzzer --- fuzz/fuzz_targets/fuzz_expr.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fuzz/fuzz_targets/fuzz_expr.rs b/fuzz/fuzz_targets/fuzz_expr.rs index 8bc18fae4..4d55155b1 100644 --- a/fuzz/fuzz_targets/fuzz_expr.rs +++ b/fuzz/fuzz_targets/fuzz_expr.rs @@ -22,7 +22,8 @@ static CMD_PATH: &str = "expr"; fn generate_expr(max_depth: u32) -> String { let mut rng = rand::thread_rng(); let ops = [ - "+", "-", "*", "/", "%", "<", ">", "=", "&", "|", "!=", "<=", ">=", ":", "index", "length", "substr", + "+", "-", "*", "/", "%", "<", ">", "=", "&", "|", "!=", "<=", ">=", ":", "index", "length", + "substr", ]; let mut expr = String::new(); From 08f324bf4073af217ea59528eb2454b7d723951c Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 1 Apr 2024 01:01:39 +0200 Subject: [PATCH 2/4] Silent some clippy warnings --- fuzz/fuzz_targets/fuzz_echo.rs | 1 + fuzz/fuzz_targets/fuzz_test.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/fuzz/fuzz_targets/fuzz_echo.rs b/fuzz/fuzz_targets/fuzz_echo.rs index 3f15b257e..c5f986b8d 100644 --- a/fuzz/fuzz_targets/fuzz_echo.rs +++ b/fuzz/fuzz_targets/fuzz_echo.rs @@ -21,6 +21,7 @@ fn generate_echo() -> String { // Randomly decide whether to include options let include_n = rng.gen_bool(0.1); // 10% chance let include_e = rng.gen_bool(0.1); // 10% chance + #[allow(non_snake_case)] let include_E = rng.gen_bool(0.1); // 10% chance if include_n { diff --git a/fuzz/fuzz_targets/fuzz_test.rs b/fuzz/fuzz_targets/fuzz_test.rs index bed7ca770..045462fb3 100644 --- a/fuzz/fuzz_targets/fuzz_test.rs +++ b/fuzz/fuzz_targets/fuzz_test.rs @@ -18,6 +18,7 @@ use crate::fuzz_common::{ compare_result, generate_and_run_uumain, generate_random_string, run_gnu_cmd, }; +#[allow(clippy::upper_case_acronyms)] #[derive(PartialEq, Debug, Clone)] enum ArgType { STRING, From 7919b4e3cd76c0e7021ae617399894b2acd3916e Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 1 Apr 2024 01:03:14 +0200 Subject: [PATCH 3/4] fuzz: start fuzzing env & tr --- fuzz/Cargo.toml | 14 +++++ fuzz/fuzz_targets/fuzz_env.rs | 97 +++++++++++++++++++++++++++++++++++ fuzz/fuzz_targets/fuzz_tr.rs | 73 ++++++++++++++++++++++++++ 3 files changed, 184 insertions(+) create mode 100644 fuzz/fuzz_targets/fuzz_env.rs create mode 100644 fuzz/fuzz_targets/fuzz_tr.rs diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index dfb62aba5..a97054192 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -25,6 +25,8 @@ uu_sort = { path = "../src/uu/sort/" } uu_wc = { path = "../src/uu/wc/" } uu_cut = { path = "../src/uu/cut/" } uu_split = { path = "../src/uu/split/" } +uu_tr = { path = "../src/uu/tr/" } +uu_env = { path = "../src/uu/env/" } # Prevent this from interfering with workspaces [workspace] @@ -107,3 +109,15 @@ name = "fuzz_parse_time" path = "fuzz_targets/fuzz_parse_time.rs" test = false doc = false + +[[bin]] +name = "fuzz_tr" +path = "fuzz_targets/fuzz_tr.rs" +test = false +doc = false + +[[bin]] +name = "fuzz_env" +path = "fuzz_targets/fuzz_env.rs" +test = false +doc = false diff --git a/fuzz/fuzz_targets/fuzz_env.rs b/fuzz/fuzz_targets/fuzz_env.rs new file mode 100644 index 000000000..955ba4149 --- /dev/null +++ b/fuzz/fuzz_targets/fuzz_env.rs @@ -0,0 +1,97 @@ +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. +// spell-checker:ignore chdir + +#![no_main] +use libfuzzer_sys::fuzz_target; +use uu_env::uumain; + +use std::ffi::OsString; + +mod fuzz_common; +use crate::fuzz_common::{ + compare_result, generate_and_run_uumain, generate_random_string, run_gnu_cmd, CommandResult, +}; +use rand::Rng; + +static CMD_PATH: &str = "env"; + +fn generate_env_args() -> Vec { + let mut rng = rand::thread_rng(); + let mut args = Vec::new(); + + let opts = ["-i", "-0", "-v", "-vv"]; + for opt in &opts { + if rng.gen_bool(0.2) { + args.push(opt.to_string()); + } + } + + if rng.gen_bool(0.3) { + args.push(format!( + "-u={}", + generate_random_string(rng.gen_range(3..10)) + )); + } + + if rng.gen_bool(0.2) { + args.push(format!("--chdir={}", "/tmp")); // Simplified example + } + + /* + Options not implemented for now + if rng.gen_bool(0.15) { + let sig_opts = ["--block-signal"];//, /*"--default-signal",*/ "--ignore-signal"]; + let chosen_sig_opt = sig_opts[rng.gen_range(0..sig_opts.len())]; + args.push(chosen_sig_opt.to_string()); + // Simplify by assuming SIGPIPE for demonstration + if !chosen_sig_opt.ends_with("list-signal-handling") { + args.push(String::from("SIGPIPE")); + } + }*/ + + // Adding a few random NAME=VALUE pairs + for _ in 0..rng.gen_range(0..3) { + args.push(format!( + "{}={}", + generate_random_string(5), + generate_random_string(5) + )); + } + + args +} + +fuzz_target!(|_data: &[u8]| { + let env_args = generate_env_args(); + let mut args = vec![OsString::from("env")]; + args.extend(env_args.iter().map(OsString::from)); + let input_lines = generate_random_string(10); + + let rust_result = generate_and_run_uumain(&args, uumain, Some(&input_lines)); + + let gnu_result = match run_gnu_cmd(CMD_PATH, &args[1..], false, None) { + Ok(result) => result, + Err(error_result) => { + eprintln!("Failed to run GNU command:"); + eprintln!("Stderr: {}", error_result.stderr); + eprintln!("Exit Code: {}", error_result.exit_code); + CommandResult { + stdout: String::new(), + stderr: error_result.stderr, + exit_code: error_result.exit_code, + } + } + }; + + compare_result( + "env", + &format!("{:?}", &args[1..]), + None, + &rust_result, + &gnu_result, + false, + ); +}); diff --git a/fuzz/fuzz_targets/fuzz_tr.rs b/fuzz/fuzz_targets/fuzz_tr.rs new file mode 100644 index 000000000..d67046be4 --- /dev/null +++ b/fuzz/fuzz_targets/fuzz_tr.rs @@ -0,0 +1,73 @@ +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +#![no_main] +use libfuzzer_sys::fuzz_target; +use std::ffi::OsString; +use uu_tr::uumain; + +use rand::Rng; + +mod fuzz_common; +use crate::fuzz_common::{ + compare_result, generate_and_run_uumain, generate_random_string, run_gnu_cmd, CommandResult, +}; +static CMD_PATH: &str = "tr"; + +fn generate_tr_args() -> Vec { + let mut rng = rand::thread_rng(); + let mut args = Vec::new(); + + // Translate, squeeze, and/or delete characters + let opts = ["-c", "-d", "-s", "-t"]; + for opt in &opts { + if rng.gen_bool(0.25) { + args.push(opt.to_string()); + } + } + + // Generating STRING1 and optionally STRING2 + let string1 = generate_random_string(rng.gen_range(1..=20)); + args.push(string1); + if rng.gen_bool(0.7) { + // Higher chance to add STRING2 for translation + let string2 = generate_random_string(rng.gen_range(1..=20)); + args.push(string2); + } + + args +} + +fuzz_target!(|_data: &[u8]| { + let tr_args = generate_tr_args(); + let mut args = vec![OsString::from("tr")]; + args.extend(tr_args.iter().map(OsString::from)); + + let input_chars = generate_random_string(100); + + let rust_result = generate_and_run_uumain(&args, uumain, Some(&input_chars)); + let gnu_result = match run_gnu_cmd(CMD_PATH, &args[1..], false, Some(&input_chars)) { + Ok(result) => result, + Err(error_result) => { + eprintln!("Failed to run GNU command:"); + eprintln!("Stderr: {}", error_result.stderr); + eprintln!("Exit Code: {}", error_result.exit_code); + CommandResult { + stdout: String::new(), + stderr: error_result.stderr, + exit_code: error_result.exit_code, + } + } + }; + + compare_result( + "tr", + &format!("{:?}", &args[1..]), + Some(&input_chars), + &rust_result, + &gnu_result, + false, + ); +}); From 14ef1a204c90ef9ecca90580df34b185ca00c0bf Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 1 Apr 2024 01:05:20 +0200 Subject: [PATCH 4/4] fuzz: run the new fuzzers in the CI --- .github/workflows/fuzzing.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/fuzzing.yml b/.github/workflows/fuzzing.yml index c60c01ff4..e045d9b4f 100644 --- a/.github/workflows/fuzzing.yml +++ b/.github/workflows/fuzzing.yml @@ -53,6 +53,8 @@ jobs: - { name: fuzz_wc, should_pass: false } - { name: fuzz_cut, should_pass: false } - { name: fuzz_split, should_pass: false } + - { name: fuzz_tr, should_pass: false } + - { name: fuzz_env, should_pass: false } - { name: fuzz_parse_glob, should_pass: true } - { name: fuzz_parse_size, should_pass: true } - { name: fuzz_parse_time, should_pass: true }