diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 9e48eb804..f5ddefc4f 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -136,6 +136,51 @@ jobs: S=$(cargo fmt -- --check) && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s\n" "$S" | sed -E -n -e "s/^Diff[[:space:]]+in[[:space:]]+${PWD//\//\\/}\/(.*)[[:space:]]+at[[:space:]]+[^0-9]+([0-9]+).*$/::${fault_type} file=\1,line=\2::${fault_prefix}: \`cargo fmt\`: style violation (file:'\1', line:\2; use \`cargo fmt -- \"\1\"\`)/p" ; fault=true ; } if [ -n "${{ steps.vars.outputs.FAIL_ON_FAULT }}" ] && [ -n "$fault" ]; then exit 1 ; fi + fuzz: + name: Run the fuzzers + runs-on: ubuntu-latest + env: + RUN_FOR: 60 + steps: + - uses: actions/checkout@v3 + - uses: Swatinem/rust-cache@v2 + - name: Install `rust` toolchain + run: | + rustup toolchain install nightly --no-self-update --profile minimal + rustup default nightly + - name: Install `cargo-fuzz` + run: cargo install cargo-fuzz + - name: Run fuzz_date for XX seconds + # TODO: fix the issues + continue-on-error: true + shell: bash + run: | + ## Run it + cd fuzz + cargo +nightly fuzz run fuzz_date -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 + - name: Run fuzz_parse_glob for XX seconds + # TODO: fix the issues + continue-on-error: true + shell: bash + run: | + ## Run it + cd fuzz + cargo +nightly fuzz run fuzz_parse_glob -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 + - name: Run fuzz_parse_size for XX seconds + shell: bash + run: | + ## Run it + cd fuzz + cargo +nightly fuzz run fuzz_parse_size -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 + - name: Run fuzz_parse_time for XX seconds + # TODO: fix the issues + continue-on-error: true + shell: bash + run: | + ## Run it + cd fuzz + cargo +nightly fuzz run fuzz_parse_time -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 + style_lint: name: Style/lint runs-on: ${{ matrix.job.os }} diff --git a/.vscode/cspell.dictionaries/acronyms+names.wordlist.txt b/.vscode/cspell.dictionaries/acronyms+names.wordlist.txt index 81bc3bc5f..8711913d9 100644 --- a/.vscode/cspell.dictionaries/acronyms+names.wordlist.txt +++ b/.vscode/cspell.dictionaries/acronyms+names.wordlist.txt @@ -50,6 +50,7 @@ Gmail GNU Illumos Irix +libfuzzer MS-DOS MSDOS MacOS diff --git a/fuzz/.gitignore b/fuzz/.gitignore new file mode 100644 index 000000000..a0925114d --- /dev/null +++ b/fuzz/.gitignore @@ -0,0 +1,3 @@ +target +corpus +artifacts diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml new file mode 100644 index 000000000..89c6bc4ef --- /dev/null +++ b/fuzz/Cargo.toml @@ -0,0 +1,45 @@ +[package] +name = "uucore-fuzz" +version = "0.0.0" +publish = false +edition = "2021" + +[package.metadata] +cargo-fuzz = true + +[dependencies] +libfuzzer-sys = "0.4" + +[dependencies.uucore] +uucore = { workspace = true } + +[dependencies.uu_date] +uu_date = { workspace = true } + +# Prevent this from interfering with workspaces +[workspace] +members = ["."] + +[[bin]] +name = "fuzz_date" +path = "fuzz_targets/fuzz_date.rs" +test = false +doc = false + +[[bin]] +name = "fuzz_parse_glob" +path = "fuzz_targets/fuzz_parse_glob.rs" +test = false +doc = false + +[[bin]] +name = "fuzz_parse_size" +path = "fuzz_targets/fuzz_parse_size.rs" +test = false +doc = false + +[[bin]] +name = "fuzz_parse_time" +path = "fuzz_targets/fuzz_parse_time.rs" +test = false +doc = false diff --git a/fuzz/fuzz_targets/fuzz_date.rs b/fuzz/fuzz_targets/fuzz_date.rs new file mode 100644 index 000000000..96c56cc6b --- /dev/null +++ b/fuzz/fuzz_targets/fuzz_date.rs @@ -0,0 +1,14 @@ +#![no_main] +use libfuzzer_sys::fuzz_target; + +use std::ffi::OsString; +use uu_date::uumain; + +fuzz_target!(|data: &[u8]| { + let delim: u8 = 0; // Null byte + let args = data + .split(|b| *b == delim) + .filter_map(|e| std::str::from_utf8(e).ok()) + .map(|e| OsString::from(e)); + uumain(args); +}); diff --git a/fuzz/fuzz_targets/fuzz_parse_glob.rs b/fuzz/fuzz_targets/fuzz_parse_glob.rs new file mode 100644 index 000000000..061569bc4 --- /dev/null +++ b/fuzz/fuzz_targets/fuzz_parse_glob.rs @@ -0,0 +1,10 @@ +#![no_main] + +use libfuzzer_sys::fuzz_target; +use uucore::parse_glob; + +fuzz_target!(|data: &[u8]| { + if let Ok(s) = std::str::from_utf8(data) { + _ = parse_glob::from_str(s) + } +}); diff --git a/fuzz/fuzz_targets/fuzz_parse_size.rs b/fuzz/fuzz_targets/fuzz_parse_size.rs new file mode 100644 index 000000000..23b3b5ea4 --- /dev/null +++ b/fuzz/fuzz_targets/fuzz_parse_size.rs @@ -0,0 +1,10 @@ +#![no_main] + +use libfuzzer_sys::fuzz_target; +use uucore::parse_size::parse_size; + +fuzz_target!(|data: &[u8]| { + if let Ok(s) = std::str::from_utf8(data) { + _ = parse_size(s); + } +}); diff --git a/fuzz/fuzz_targets/fuzz_parse_time.rs b/fuzz/fuzz_targets/fuzz_parse_time.rs new file mode 100644 index 000000000..a643c6d80 --- /dev/null +++ b/fuzz/fuzz_targets/fuzz_parse_time.rs @@ -0,0 +1,10 @@ +#![no_main] + +use libfuzzer_sys::fuzz_target; +use uucore::parse_time; + +fuzz_target!(|data: &[u8]| { + if let Ok(s) = std::str::from_utf8(data) { + _ = parse_time::from_str(s); + } +});