Vergleichende Fuzzing-Parallel-Rost-Tools
Ich habe zuvor darüber geschrieben, wie wir Rusts „furchtlose Parallelität“ nutzen können , was zu einem Tool namens Ripunzip führte. (Hier sind einige Leistungsergebnisse ).
Wie können wir sicher sein, dass es sich genauso verhält wie ein nicht paralleles, reguläres Entpacken? Auch unter unvorhergesehenen Umständen?
Die Antwort: vergleichendes Fuzzing . Fuzzing ist normalerweise eine Technik, die verwendet wird, um Sicherheitslücken zu finden – hier ist ein Rezept, wie Sie damit nach Fehlern in unsicherem Rust-Code suchen können – Sie können es aber auch verwenden, um zu überprüfen, ob sich zwei Implementierungen gleich verhalten – vergleichendes Fuzzing.
Es eignet sich gut für den Fall, dass wir versuchen, eine schnellere Version eines vorhandenen Tools zu erstellen, und Fuzzing macht ziemlich viel Spaß – besonders in Rust, wo es die wunderbare arbitrary Kiste gibt .
Hier ist der Plan:
- Beschreiben Sie alle Eingaben in
ripunzip, einschließlich der ZIP-Datei, mithilfe derarbitraryKiste - Führen Sie
ripunzipdie Ausführung basierend auf diesen Eingaben durch - Entpacken Sie dieselbe Datei auch mit normalem Single-Thread
zip-rs - Überprüfen Sie, ob beide erfolgreich waren oder beide fehlgeschlagen sind
- Vergleichen Sie das entpackte Verzeichnis. Wenn es anders ist, stürzt ab!
Hier ist der Fuzzer, den wir erhalten haben . Schauen wir uns zunächst die Eingabedaten an:
#[derive(arbitrary::Arbitrary, Eq, PartialEq, Hash, Debug, Clone)]
struct ZipMemberFilename(/* details omitted... described later */);
#[derive(Eq, PartialEq, Hash, Debug, Clone, Copy, arbitrary::Arbitrary)]
enum CompressionMethod {
Stored,
Deflated,
Bzip2,
Zstd,
}
#[derive(arbitrary::Arbitrary, Debug, Clone)]
struct Inputs {
// HashMap to ensure unique filenames in zip
zip_members: HashMap<ZipMemberFilename, Vec<u8>>,
compression_method: CompressionMethod,
single_threaded: bool,
}
Es leitet sich ab Arbitrary, was bedeutet, dass Code generiert wird, um diese Struktur aus einem undurchsichtigen binären Blob zu erstellen. Diese binären Blobs werden von libfuzzer generiert und – was entscheidend ist – sie werden immer wieder geändert, um auf der Grundlage der Abdeckungsrichtlinien nach und nach so viel wie möglich vom Programm zu erkunden.
Wir haben dort einige ziemlich komplexe Eingaben – HashMap, Vektoren und benutzerdefinierte Aufzählungen. Arbitraryist intelligent genug, um sie alle zu generieren.
Nun ist der Fuzzer selbst im Wesentlichen trivial – wir erstellen im wahrsten Sinne des Wortes einfach die ZIP-Datei, entpacken sie zweimal und vergleichen die Ausgaben.
fuzz_target!(|input: Inputs| {
let progress_reporter = ripunzip::NullProgressReporter;
let tempdir = tempfile::tempdir().unwrap();
let output_directory = tempdir.path().join("out_ripunzip");
let output_directory_unzip = tempdir.path().join("out_unzip");
std::fs::create_dir_all(&output_directory).unwrap();
let options = ripunzip::UnzipOptions {
single_threaded: input.single_threaded,
output_directory: Some(output_directory.clone()),
};
let zipfile = tempdir.path().join("file.zip");
let mut zip_data = Vec::new();
create_zip(&mut zip_data, &input.zip_members, input.compression_method);
let mut file = std::fs::File::create(&zipfile).unwrap();
file.write_all(&zip_data).unwrap();
drop(file);
let file = std::fs::File::open(&zipfile).unwrap();
let ripunzip_result: Result<(), anyhow::Error> = (|| {
let ripunzip = ripunzip::UnzipEngine::for_file(file, options, progress_reporter)?;
ripunzip.unzip()
})();
let unziprs_result = unzip_with_zip_rs(&zipfile, &output_directory_unzip);
match unziprs_result {
Err(err) => {
if ripunzip_result.is_ok() {
panic!("ripunzip succeeded; plain unzip gave {:?}", err)
}
}
Ok(_) => {
ripunzip_result.unwrap();
let ripunzip_paths = recursive_lsdir(&output_directory);
let unzip_paths = recursive_lsdir(&output_directory_unzip);
// We do not currently compare the actual zip file contents.
// It seems unlikely that this would be a failure mode where
// ripunzip would differ from zip-rs.
assert_eq!(ripunzip_paths, unzip_paths);
}
}
});
fn recursive_lsdir(dir: &Path) -> HashSet<std::path::PathBuf> {
walkdir::WalkDir::new(dir)
.into_iter()
.filter_map(|e| e.ok())
.map(|e| e.path().strip_prefix(dir).unwrap().to_path_buf())
.collect()
}
// Create a zip file from zip_members into output,
// using the given compression mode. Details omitted.
fn create_zip(output: &mut Vec<u8>, zip_members: &HashMap<ZipMemberFilename, Vec<u8>>, compression_method: CompressionMethod) {
// ...
}
/// Errors that can occur with a regular zip-rs unzip, details omitted
#[derive(Debug)]
enum ZipRsError {
// ...
}
/// Unzip the content with standard zip-rs.
fn unzip_with_zip_rs(zipfile_path: &Path, dest_path: &Path) -> Result<(), ZipRsError> {
// ...
}
#[derive(arbitrary::Arbitrary, Debug, Clone, strum::Display, Hash, Eq, PartialEq)]
enum FilenameSegment {
Fish,
A,
#[strum(serialize = "b")]
B,
#[strum(serialize = "31")]
ThirtyOne,
#[strum(serialize = "_c")]
C,
D,
#[strum(serialize = "e.txt")]
ETxt,
}
#[derive(arbitrary::Arbitrary, Eq, PartialEq, Hash, Debug, Clone)]
struct ZipMemberFilename(Vec<FilenameSegment>);
impl Into<String> for &ZipMemberFilename {
fn into(self) -> String {
self.0.iter().join("/")
}
}
Was passiert, wenn wir das ausführen? Wir sehen diese entzückende Ausgabe als die Fuzzer-Frettchen, die in unserer Codebasis herumschwirren.
$ cargo +nightly fuzz run fuzz_ripunzip
Compiling ripunzip v0.2.2 (ripunzip)
Compiling ripunzip-fuzz v0.0.0 (ripunzip/fuzz)
Finished release [optimized] target(s) in 18.06s
Finished release [optimized] target(s) in 0.18s
Running `target/x86_64-apple-darwin/release/fuzz_ripunzip -artifact_prefix=ripunzip/fuzz/artifacts/fuzz_ripunzip/ ripunzip/fuzz/corpus/fuzz_ripunzip`
fuzz_ripunzip(13490,0x7ff85b1088c0) malloc: nano zone abandoned due to inability to preallocate reserved vm space.
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 3274692728
INFO: Loaded 1 modules (720556 inline 8-bit counters): 720556 [0x107a95260, 0x107b4510c),
INFO: Loaded 1 PC tables (720556 PCs): 720556 [0x107b45110,0x108643bd0),
INFO: 0 files found in ripunzip/fuzz/corpus/fuzz_ripunzip
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: A corpus is not provided, starting from an empty corpus
#2 INITED exec/s: 0 rss: 53Mb
NEW_FUNC[1/171]: 0x105266120 in _$LT$core..iter..adapters..map..Map$LT$I$C$F$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$::fold::h2eed7f9eb6137b14+0x0 (fuzz_ripunzip:x86_64+0x100003120) (BuildId: d85ba98c8ed134a4845c0cff1565ef9632000000200000000100000000000d00)
NEW_FUNC[2/171]: 0x10526abc0 in _$LT$ripunzip..unzip..cloneable_seekable_reader..CloneableSeekableReader$LT$R$GT$$u20$as$u20$std..io..Read$GT$::read::h7325b227d55c68e7+0x0 (fuzz_ripunzip:x86_64+0x100007bc0) (BuildId: d85ba98c8ed134a4845c0cff1565ef9632000000200000000100000000000d00)
#212 NEW cov: 1204 ft: 1177 corp: 2/7b lim: 6 exec/s: 212 rss: 59Mb L: 6/6 MS: 4 ChangeBit-ChangeBit-InsertByte-InsertRepeatedBytes-
#213 NEW cov: 1209 ft: 1182 corp: 3/13b lim: 6 exec/s: 213 rss: 59Mb L: 6/6 MS: 1 ShuffleBytes-
#217 NEW cov: 1210 ft: 1184 corp: 4/18b lim: 6 exec/s: 217 rss: 59Mb L: 5/6 MS: 4 CopyPart-ChangeByte-ShuffleBytes-InsertRepeatedBytes-
NEW_FUNC[1/90]: 0x10526a3b0 in _$LT$std..io..cursor..Cursor$LT$$RF$mut$u20$alloc..vec..Vec$LT$u8$C$A$GT$$GT$$u20$as$u20$std..io..Write$GT$::write::hb0a9a4b62999ace6+0x0 (fuzz_ripunzip:x86_64+0x1000073b0) (BuildId: d85ba98c8ed134a4845c0cff1565ef9632000000200000000100000000000d00)
NEW_FUNC[2/90]: 0x10526ca90 in _$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$alloc..vec..spec_from_iter_nested..SpecFromIterNested$LT$T$C$I$GT$$GT$::from_iter::h62629dd53aaca6a9+0x0 (fuzz_ripunzip:x86_64+0x100009a90) (BuildId: d85ba98c8ed134a4845c0cff1565ef9632000000200000000100000000000d00)
#220 NEW cov: 2100 ft: 2235 corp: 5/23b lim: 6 exec/s: 220 rss: 60Mb L: 5/6 MS: 3 CrossOver-ShuffleBytes-InsertRepeatedBytes-
#222 NEW cov: 2101 ft: 2237 corp: 6/29b lim: 6 exec/s: 222 rss: 60Mb L: 6/6 MS: 2 CrossOver-CopyPart-
NEW_FUNC[1/1]: 0x1053ad5c0 in _$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$alloc..vec..spec_from_iter_nested..SpecFromIterNested$LT$T$C$I$GT$$GT$::from_iter::h14e3944acd671fa2+0x0 (fuzz_ripunzip:x86_64+0x10014a5c0) (BuildId: d85ba98c8ed134a4845c0cff1565ef9632000000200000000100000000000d00)
#231 NEW cov: 2108 ft: 2245 corp: 7/35b lim: 6 exec/s: 231 rss: 60Mb L: 6/6 MS: 4 CopyPart-ShuffleBytes-ShuffleBytes-CopyPart-
NEW_FUNC[1/12]: 0x1052d2580 in core::ptr::drop_in_place$LT$fuzz_ripunzip..ZipRsError$GT$::h864830fa1576e5d5+0x0 (fuzz_ripunzip:x86_64+0x10006f580) (BuildId: d85ba98c8ed134a4845c0cff1565ef9632000000200000000100000000000d00)
NEW_FUNC[2/12]: 0x1053f7e70 in core::ptr::drop_in_place$LT$anyhow..error..ErrorImpl$LT$anyhow..error..ContextError$LT$core..mem..manually_drop..ManuallyDrop$LT$$RF$str$GT$$C$std..io..error..Error$GT$$GT$$GT$::he14691a68652570b+0x0 (fuzz_ripunzip:x86_64+0x100194e70) (BuildId: d85ba98c8ed134a4845c0cff1565ef9632000000200000000100000000000d00)
#235 NEW cov: 2193 ft: 2373 corp: 8/41b lim: 6 exec/s: 235 rss: 60Mb L: 6/6 MS: 4 InsertRepeatedBytes-CopyPart-CopyPart-ChangeByte-
#241 REDUCE cov: 2193 ft: 2373 corp: 8/40b lim: 6 exec/s: 241 rss: 61Mb L: 5/6 MS: 1 EraseBytes-
#244 NEW cov: 2193 ft: 2375 corp: 9/45b lim: 6 exec/s: 244 rss: 61Mb L: 5/6 MS: 3 ChangeByte-EraseBytes-ShuffleBytes-
#252 NEW cov: 2199 ft: 2394 corp: 10/51b lim: 6 exec/s: 252 rss: 61Mb L: 6/6 MS: 3 CrossOver-InsertByte-InsertRepeatedBytes-
#256 NEW cov: 2199 ft: 2398 corp: 11/56b lim: 6 exec/s: 256 rss: 61Mb L: 5/6 MS: 4 ChangeBit-CrossOver-CrossOver-InsertRepeatedBytes-
#273 NEW cov: 2199 ft: 2399 corp: 12/62b lim: 6 exec/s: 273 rss: 62Mb L: 6/6 MS: 2 ChangeBit-InsertByte-
#274 NEW cov: 2199 ft: 2401 corp: 13/68b lim: 6 exec/s: 274 rss: 62Mb L: 6/6 MS: 1 ChangeByte-
#282 NEW cov: 2199 ft: 2402 corp: 14/74b lim: 6 exec/s: 282 rss: 62Mb L: 6/6 MS: 3 ShuffleBytes-CrossOver-ChangeBinInt-
#285 NEW cov: 2205 ft: 2463 corp: 15/80b lim: 6 exec/s: 285 rss: 62Mb L: 6/6 MS: 3 CMP-CopyPart-CMP- DE: " \000\000\000"-"\001\000\000\005"-
#298 NEW cov: 2205 ft: 2465 corp: 16/86b lim: 6 exec/s: 298 rss: 63Mb L: 6/6 MS: 3 ChangeBit-ChangeBinInt-ChangeBinInt-
NEW_FUNC[1/1]: 0x1074d09b0 in _$LT$u8$u20$as$u20$arbitrary..Arbitrary$GT$::arbitrary::hbd4728a44a66213a+0x0 (fuzz_ripunzip:x86_64+0x10226d9b0) (BuildId: d85ba98c8ed134a4845c0cff1565ef9632000000200000000100000000000d00)
#314 NEW cov: 2219 ft: 2479 corp: 17/92b lim: 6 exec/s: 314 rss: 63Mb L: 6/6 MS: 1 ChangeByte-
#340 NEW cov: 2231 ft: 2499 corp: 18/98b lim: 6 exec/s: 340 rss: 64Mb L: 6/6 MS: 1 ChangeBinInt-
#347 NEW cov: 2232 ft: 2502 corp: 19/104b lim: 6 exec/s: 347 rss: 64Mb L: 6/6 MS: 2 ChangeBinInt-ChangeBit-
NEW_FUNC[1/27]: 0x1053a3620 in rayon_core::join::join_context::_$u7b$$u7b$closure$u7d$$u7d$::heeeee28ce9473e59+0x0 (fuzz_ripunzip:x86_64+0x100140620) (BuildId: d85ba98c8ed134a4845c0cff1565ef9632000000200000000100000000000d00)
NEW_FUNC[2/27]: 0x1053a5d20 in rayon_core::sleep::Sleep::new_jobs::hfc61bcd28f9a7e21+0x0 (fuzz_ripunzip:x86_64+0x100142d20) (BuildId: d85ba98c8ed134a4845c0cff1565ef9632000000200000000100000000000d00)
#379 NEW cov: 2447 ft: 3413 corp: 20/110b lim: 6 exec/s: 379 rss: 65Mb L: 6/6 MS: 1 ChangeBinInt-
#384 NEW cov: 2450 ft: 3427 corp: 21/116b lim: 6 exec/s: 384 rss: 65Mb L: 6/6 MS: 5 ChangeByte-CopyPart-ChangeBit-CopyPart-PersAutoDict- DE: "\001\000\000\005"-
NEW_FUNC[1/1]: 0x105285c50 in std::thread::local::fast::Key$LT$T$GT$::try_initialize::h078871c80893dca2+0x0 (fuzz_ripunzip:x86_64+0x100022c50) (BuildId: d85ba98c8ed134a4845c0cff1565ef9632000000200000000100000000000d00)
#387 NEW cov: 2469 ft: 3446 corp: 22/122b lim: 6 exec/s: 387 rss: 65Mb L: 6/6 MS: 3 CrossOver-ChangeByte-CrossOver-
#388 NEW cov: 2470 ft: 3449 corp: 23/128b lim: 6 exec/s: 388 rss: 65Mb L: 6/6 MS: 1 ChangeBinInt-
NEW_FUNC[1/3]: 0x1053b3ea0 in crossbeam_deque::deque::Worker$LT$T$GT$::pop::h027afe55d57c8358+0x0 (fuzz_ripunzip:x86_64+0x100150ea0) (BuildId: d85ba98c8ed134a4845c0cff1565ef9632000000200000000100000000000d00)
NEW_FUNC[2/3]: 0x1053b4b30 in crossbeam_deque::deque::Stealer$LT$T$GT$::steal::h20410f4e42e0f324+0x0 (fuzz_ripunzip:x86_64+0x100151b30) (BuildId: d85ba98c8ed134a4845c0cff1565ef9632000000200000000100000000000d00)
#394 NEW cov: 2497 ft: 3598 corp: 24/134b lim: 6 exec/s: 394 rss: 65Mb L: 6/6 MS: 1 ChangeBit-
#400 NEW cov: 2497 ft: 3602 corp: 25/140b lim: 6 exec/s: 400 rss: 66Mb L: 6/6 MS: 1 CopyPart-
#411 NEW cov: 2502 ft: 3618 corp: 26/146b lim: 6 exec/s: 411 rss: 66Mb L: 6/6 MS: 1 InsertByte-
#439 NEW cov: 2503 ft: 3619 corp: 27/152b lim: 6 exec/s: 439 rss: 67Mb L: 6/6 MS: 3 ChangeBit-ChangeBinInt-ShuffleBytes-
#462 NEW cov: 2504 ft: 3621 corp: 28/158b lim: 6 exec/s: 462 rss: 68Mb L: 6/6 MS: 3 ChangeBinInt-ShuffleBytes-ShuffleBytes-
#463 NEW cov: 2504 ft: 3624 corp: 29/164b lim: 6 exec/s: 463 rss: 68Mb L: 6/6 MS: 1 CrossOver-
#464 NEW cov: 2504 ft: 3630 corp: 30/170b lim: 6 exec/s: 464 rss: 68Mb L: 6/6 MS: 1 ChangeBit-
#480 NEW cov: 2505 ft: 3631 corp: 31/176b lim: 6 exec/s: 480 rss: 68Mb L: 6/6 MS: 1 CrossOver-
#486 NEW cov: 2505 ft: 3636 corp: 32/182b lim: 6 exec/s: 486 rss: 68Mb L: 6/6 MS: 1 ChangeBinInt-
#487 NEW cov: 2505 ft: 3637 corp: 33/188b lim: 6 exec/s: 487 rss: 68Mb L: 6/6 MS: 1 CopyPart-
#527 NEW cov: 2505 ft: 3641 corp: 34/194b lim: 6 exec/s: 527 rss: 69Mb L: 6/6 MS: 5 ChangeBinInt-CrossOver-CopyPart-ChangeBinInt-PersAutoDict- DE: "\001\000\000\005"-
NEW_FUNC[1/1]: 0x1052de9a0 in core::iter::traits::double_ended::DoubleEndedIterator::try_rfold::hcf0f30052624299f+0x0 (fuzz_ripunzip:x86_64+0x10007b9a0) (BuildId: d85ba98c8ed134a4845c0cff1565ef9632000000200000000100000000000d00)
#538 NEW cov: 2535 ft: 3675 corp: 35/200b lim: 6 exec/s: 538 rss: 70Mb L: 6/6 MS: 1 CopyPart-
Nachdem Sie den obigen Absatz eingegeben haben, wurden nun 3795 Codeblöcke untersucht.
Schließlich erreicht es ein Plateau. Es ist unheimlich faszinierend.
Also, hat es funktioniert? Wurden Probleme festgestellt?
Ja! Sofort. Zum Beispiel:
$ RUST_BACKTRACE=1 cargo +nightly fuzz run fuzz_ripunzip
Finished release [optimized] target(s) in 0.21s
Finished release [optimized] target(s) in 0.20s
Running `target/x86_64-apple-darwin/release/fuzz_ripunzip -artifact_prefix=ripunzip/fuzz/artifacts/fuzz_ripunzip/ ripunzip/fuzz/corpus/fuzz_ripunzip`
fuzz_ripunzip(14468,0x7ff85b1088c0) malloc: nano zone abandoned due to inability to preallocate reserved vm space.
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 3659845534
INFO: Loaded 1 modules (719987 inline 8-bit counters): 719987 [0x10c8e5fe0, 0x10c995c53),
INFO: Loaded 1 PC tables (719987 PCs): 719987 [0x10c995c58,0x10d492388),
INFO: 0 files found in ripunzip/fuzz/corpus/fuzz_ripunzip
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: A corpus is not provided, starting from an empty corpus
#2 INITED exec/s: 0 rss: 53Mb
WARNING: no interesting inputs were found so far. Is the code instrumented for coverage?
This may also happen if the target rejected all inputs we tried so far
thread '<unnamed>' panicked at 'attempt to subtract with overflow', ripunzip/src/unzip/cloneable_seekable_reader.rs:93:17
stack backtrace:
0: rust_begin_unwind
at /rustc/ec56537c4325ce5b798fc3628cbdd48ba4949ae5/library/std/src/panicking.rs:575:5
1: core::panicking::panic_fmt
at /rustc/ec56537c4325ce5b798fc3628cbdd48ba4949ae5/library/core/src/panicking.rs:64:14
2: core::panicking::panic
at /rustc/ec56537c4325ce5b798fc3628cbdd48ba4949ae5/library/core/src/panicking.rs:111:5
3: <ripunzip::unzip::cloneable_seekable_reader::CloneableSeekableReader<R> as std::io::Seek>::seek
4: zip::read::<impl zip::read::zip_archive::ZipArchive<R>>::get_directory_counts
5: zip::read::<impl zip::read::zip_archive::ZipArchive<R>>::new
6: ripunzip::unzip::UnzipEngine<P>::for_file
7: fuzz_ripunzip::_::run
8: _rust_fuzzer_test_input
9: std::panicking::try::do_call
10: ___rust_try
11: _LLVMFuzzerTestOneInput
12: __ZN6fuzzer6Fuzzer15ExecuteCallbackEPKhm
13: __ZN6fuzzer6Fuzzer6RunOneEPKhmbPNS_9InputInfoEbPb
14: __ZN6fuzzer6Fuzzer16MutateAndTestOneEv
15: __ZN6fuzzer6Fuzzer4LoopERNSt3__16vectorINS_9SizedFileENS1_9allocatorIS3_EEEE
16: __ZN6fuzzer12FuzzerDriverEPiPPPcPFiPKhmE
17: _main
18: <unknown>
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
==14468== ERROR: libFuzzer: deadly signal
#0 0x10e2a6185 in __sanitizer_print_stack_trace+0x35 (librustc-nightly_rt.asan.dylib:x86_64h+0x53185) (BuildId: d21cf6fbe4db36c3a2772a5990be16c5240000001000000000070a0000030c00)
#1 0x10c2c1d1a in fuzzer::PrintStackTrace()+0x2a (fuzz_ripunzip:x86_64+0x102205d1a) (BuildId: 52587ab92ee03de78cc50b187a499a5332000000200000000100000000000d00)
#2 0x10c2b49e3 in fuzzer::Fuzzer::CrashCallback()+0x43 (fuzz_ripunzip:x86_64+0x1021f89e3) (BuildId: 52587ab92ee03de78cc50b187a499a5332000000200000000100000000000d00)
#3 0x7ff817802c1c in _sigtramp+0x1c (libsystem_platform.dylib:x86_64+0x3c1c) (BuildId: f314b62b98f43a7c82968739f8b6855a240000001000000000010d0000010d00)
NOTE: libFuzzer has rudimentary signal handlers.
Combine libFuzzer with AddressSanitizer or similar for better crash reports.
SUMMARY: libFuzzer: deadly signal
MS: 1 InsertRepeatedBytes-; base unit: adc83b19e793491b1c6ea0fd8b46cd9f32e592fc
0xa,0x0,0x0,0x0,0x0,0x0,
\012\000\000\000\000\000
artifact_prefix='ripunzip/fuzz/artifacts/fuzz_ripunzip/'; Test unit written to ripunzip/fuzz/artifacts/fuzz_ripunzip/crash-fd324ba7ec17e3df5e8735319dc70009a81c1b6c
Base64: CgAAAAAA
────────────────────────────────────────────────────────────────────────────────
Failing input:
artifacts/fuzz_ripunzip/crash-fd324ba7ec17e3df5e8735319dc70009a81c1b6c
Output of `std::fmt::Debug`:
Inputs {
zip_members: {},
compression_method: Stored,
single_threaded: false,
}
Reproduce with:
cargo fuzz run fuzz_ripunzip artifacts/fuzz_ripunzip/crash-fd324ba7ec17e3df5e8735319dc70009a81c1b6c
Minimize test case with:
cargo fuzz tmin fuzz_ripunzip artifacts/fuzz_ripunzip/crash-fd324ba7ec17e3df5e8735319dc70009a81c1b6c
────────────────────────────────────────────────────────────────────────────────
Error: Fuzz target exited with exit status: 77
Stack backtrace:
0: std::backtrace::Backtrace::create
1: std::backtrace::Backtrace::capture
2: anyhow::error::<impl anyhow::Error>::msg
3: cargo_fuzz::project::FuzzProject::exec_fuzz
4: <cargo_fuzz::options::run::Run as cargo_fuzz::RunCommand>::run_command
5: cargo_fuzz::main
6: std::sys_common::backtrace::__rust_begin_short_backtrace
7: std::rt::lang_start::{{closure}}
8: std::rt::lang_start_internal
9: _main
10: <unknown>
Es wurde außerdem Folgendes entdeckt:
- Manchmal rasten mehrere Threads darum, übergeordnete Verzeichnisse der Mitglieder zu erstellen, die sie entpackten.
- Wir haben unterschiedliche Entscheidungen hinsichtlich der Dateinamen getroffen, die auf enden
/– ich habe mich hier am Verhalten von zip-rs orientiert
PS: Es sind jetzt 4359 Codeblöcke erforscht

![Was ist überhaupt eine verknüpfte Liste? [Teil 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































