Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fuzz date is quickly identifying errors #3785

Closed
qarmin opened this issue Aug 6, 2022 · 11 comments
Closed

Fuzz date is quickly identifying errors #3785

qarmin opened this issue Aug 6, 2022 · 11 comments
Labels

Comments

@qarmin
Copy link

qarmin commented Aug 6, 2022

When I tried to use with this patch a fuzzer:

Then after first fuzzer(https://github.com/rust-fuzz/cargo-fuzz) run(with any value, since input is always same)

cd src/uu/date
cargo +nightly fuzz run fuzz_target_1

I got this memory leak;

Direct leak of 182 byte(s) in 1 object(s) allocated from:
   #0 0x55bee9d209c6 in __interceptor_realloc /rustc/llvm/src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:85:3
   #1 0x55bee9e3d286 in alloc::raw_vec::RawVec$LT$T$C$A$GT$::shrink::h0cbb59626d49af4c (/home/rafal/test/coreutils/src/uu/date/fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x66f286) (BuildId: 71e645d4db0079b28c3f9b4da7eb5ca63f0a5eee)
   #2 0x55bee9e780ec in uucore::format_usage::h4aeffd44ee9d338a (/home/rafal/test/coreutils/src/uu/date/fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x6aa0ec) (BuildId: 71e645d4db0079b28c3f9b4da7eb5ca63f0a5eee)
   #3 0x55bee9dd442a in uu_date::uu_app::h74bd79f63f3d4e41 (/home/rafal/test/coreutils/src/uu/date/fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x60642a) (BuildId: 71e645d4db0079b28c3f9b4da7eb5ca63f0a5eee)
   #4 0x55bee9da1f9f in uu_date::uumain::uumain::he8b051ec18eef25a (/home/rafal/test/coreutils/src/uu/date/fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x5d3f9f) (BuildId: 71e645d4db0079b28c3f9b4da7eb5ca63f0a5eee)
   #5 0x55bee9da0bb4 in uu_date::uumain::h612725504c625df4 (/home/rafal/test/coreutils/src/uu/date/fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x5d2bb4) (BuildId: 71e645d4db0079b28c3f9b4da7eb5ca63f0a5eee)
   #6 0x55bee9db41d4 in rust_fuzzer_test_input (/home/rafal/test/coreutils/src/uu/date/fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x5e61d4) (BuildId: 71e645d4db0079b28c3f9b4da7eb5ca63f0a5eee)
   #7 0x55beea5f3728 in __rust_try libfuzzer_sys.3c47a7c2-cgu.0
   #8 0x55beea5f2ac8 in LLVMFuzzerTestOneInput (/home/rafal/test/coreutils/src/uu/date/fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0xe24ac8) (BuildId: 71e645d4db0079b28c3f9b4da7eb5ca63f0a5eee)
   #9 0x55beea5f9ef5 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/home/rafal/test/coreutils/src/uu/date/fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0xe2bef5) (BuildId: 71e645d4db0079b28c3f9b4da7eb5ca63f0a5eee)
   #10 0x55beea5ff7a3 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) (/home/rafal/test/coreutils/src/uu/date/fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0xe317a3) (BuildId: 71e645d4db0079b28c3f9b4da7eb5ca63f0a5eee)
   #11 0x55beea6027bb in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) (/home/rafal/test/coreutils/src/uu/date/fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0xe347bb) (BuildId: 71e645d4db0079b28c3f9b4da7eb5ca63f0a5eee)
   #12 0x55beea602997 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) (/home/rafal/test/coreutils/src/uu/date/fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0xe34997) (BuildId: 71e645d4db0079b28c3f9b4da7eb5ca63f0a5eee)
   #13 0x55beea610f70 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/home/rafal/test/coreutils/src/uu/date/fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0xe42f70) (BuildId: 71e645d4db0079b28c3f9b4da7eb5ca63f0a5eee)
   #14 0x55bee9c9f206 in main (/home/rafal/test/coreutils/src/uu/date/fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x4d1206) (BuildId: 71e645d4db0079b28c3f9b4da7eb5ca63f0a5eee)
   #15 0x7fba56b14d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16

I'm not sure if this is a problem with fuzzer or date

@sylvestre
Copy link
Contributor

Cool that you are fuzzing it!
Do you have the input that make date break?
thanks

@qarmin
Copy link
Author

qarmin commented Aug 6, 2022

I haven't tried to use real values from fuzzer because I have a problem even with static and almost empty input(since I didn't use uutils earlier I could done something wrong, so I want to fix or workaround this issue)

use libfuzzer_sys::fuzz_target;

use uu_date::uumain;
use std::ffi::OsString;

fuzz_target!(|data: &[u8]| {
    let iter: Vec<OsString> = [""].into_iter().map(|e|OsString::from(e)).collect();
    let it2 = iter.into_iter();
       uumain(it2);

});

@tertsdiepraam
Copy link
Member

tertsdiepraam commented Aug 6, 2022

The offending function seems to be this: https://github.com/uutils/coreutils/blob/main/src/uucore/src/lib/lib.rs#L104

Which indeed intentionally leaks memory to create a &'static str from a boxed string. A more sophisticated method would be nice, but I don't think this leak is problematic, because it's called only once per invocation.

@sylvestre
Copy link
Contributor

@qarmin could you please suppress this leak and try again? I am curious :)

@qarmin
Copy link
Author

qarmin commented Aug 14, 2022

I only tested date tool, because this it is tool with multiple options which is safe to use(not move any files etc.) - I was able to easily reproduce this issue in less than second of running fuzzer - #3780

fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_target_1: invalid date $'k+Skk\x07\x00'
fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_target_1: invalid date $'k+\x1F'$'2\x01Sk0k\x07'
2022-08-14T21:27:33.047797994+02:00	%%)
		%%)
thread '<unnamed>' panicked at 'a Display implementation returned an error unexpectedly: Error', /rustc/20ffea6938b5839c390252e07940b99e3b6a889a/library/alloc/src/string.rs:2490:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
==20141== ERROR: libFuzzer: deadly signal
    #0 0x55f590eb0301 in __sanitizer_print_stack_trace /rustc/llvm/src/llvm-project/compiler-rt/lib/asan/asan_stack.cpp:87:3
    #1 0x55f59179263e in fuzzer::PrintStackTrace() (/home/rafal/test/coreutils/src/uu/date/fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0xe3a63e) (BuildId: fe48eaa4769aead65a31c2a871d82a481322ec0f)
    #2 0x55f5917762b9 in fuzzer::Fuzzer::CrashCallback() (/home/rafal/test/coreutils/src/uu/date/fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0xe1e2b9) (BuildId: fe48eaa4769aead65a31c2a871d82a481322ec0f)
    ...
    ...
    ...
 NOTE: libFuzzer has rudimentary signal handlers.
      Combine libFuzzer with AddressSanitizer or similar for better crash reports.
SUMMARY: libFuzzer: deadly signal
MS: 3 ChangeBinInt-CrossOver-InsertByte-; base unit: 8f3f38482d6a03ddd64ed1ccbc4cabf8d8ebe506
0x2b,0x1f,0x9,0x9,0x25,0x25,0x25,0x5b,0x25,0x29,
+\x1f\x09\x09%%%[%)
artifact_prefix='/home/rafal/test/coreutils/src/uu/date/fuzz/artifacts/fuzz_target_1/'; Test unit written to /home/rafal/test/coreutils/src/uu/date/fuzz/artifacts/fuzz_target_1/crash-b4639e53c4cc3f6cd15c1cf0612afa385c206572
Base64: Kx8JCSUlJVslKQ==

────────────────────────────────────────────────────────────────────────────────

Failing input:

	fuzz/artifacts/fuzz_target_1/crash-b4639e53c4cc3f6cd15c1cf0612afa385c206572

Output of `std::fmt::Debug`:

	[43, 31, 9, 9, 37, 37, 37, 91, 37, 41]

Steps to reproduce
patch.txt

cargo install cargo-fuzz
git apply patch.txt # patch from above
cd /src/uu/date
cargo +nightly fuzz run fuzz_target_1 -- -detect_leaks=0

@sylvestre sylvestre changed the title Memory leak when trying to use fuzzer with date library Fuzz date is quickly identifying errors Aug 14, 2022
@sylvestre
Copy link
Contributor

Very cool stuff.
Once it doesn't break after a few seconds, I would like to have this into the CI :)

@tertsdiepraam
Copy link
Member

Good news! Using clap 4, I've been able to remove the leak.

@sylvestre
Copy link
Contributor

Nice, I didn't realize that it could be fixed by clap

@tertsdiepraam
Copy link
Member

I originally wrote that function because I needed a string that lived as long as a clap::Command so that I could pass it into Command::override_usage, but now override_usage can also take a String, so we no longer need to worry about the lifetime.

@jaggededgedjustice
Copy link
Contributor

With #4244 I was able to run the fuzzer for ~ 1hour without crashes.

@sylvestre sylvestre moved this to Done in Fuzz everything Mar 18, 2023
@sylvestre sylvestre moved this from Done to In Progress in Fuzz everything Mar 18, 2023
@cakebaker
Copy link
Contributor

Closing this ticket because fuzzing of date has been added to the CICD in the meantime.

@github-project-automation github-project-automation bot moved this from In Progress to Done in Fuzz everything Apr 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Done
Development

No branches or pull requests

5 participants