Skip to content

Commit

Permalink
add fuzzer, fix memcopy overlap
Browse files Browse the repository at this point in the history
  • Loading branch information
Pascal Seitz committed Oct 18, 2020
1 parent 8daa6ec commit 286ea4c
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 4 deletions.
4 changes: 4 additions & 0 deletions fuzz/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

target
corpus
artifacts
26 changes: 26 additions & 0 deletions fuzz/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

[package]
name = "lz4_flex-fuzz"
version = "0.0.0"
authors = ["Automatically generated"]
publish = false
edition = "2018"

[package.metadata]
cargo-fuzz = true

[dependencies]
libfuzzer-sys = "0.3"

[dependencies.lz4_flex]
path = ".."

# Prevent this from interfering with workspaces
[workspace]
members = ["."]

[[bin]]
name = "fuzz_target_1"
path = "fuzz_targets/fuzz_target_1.rs"
test = false
doc = false
11 changes: 11 additions & 0 deletions fuzz/fuzz_targets/fuzz_target_1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#![no_main]
use libfuzzer_sys::fuzz_target;

use lz4_flex::block::decompress::decompress_size_prepended;
use lz4_flex::block::compress::compress_prepend_size;
fuzz_target!(|data: &[u8]| {
// fuzzed code goes here
let compressed = compress_prepend_size(data);
let decompressed = decompress_size_prepended(&compressed).unwrap();
assert_eq!(data, decompressed);
});
12 changes: 8 additions & 4 deletions src/block/decompress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,16 @@ fn is_safe_distance(input_pos: usize, in_len: usize) -> bool {
input_pos < in_len
}

/// We copy 24 byte blocks, because aligned copies are faster
const BLOCK_COPY_SIZE: usize = 24;

#[inline]
fn block_copy_from_src(source: *const u8, dst_ptr: *mut u8, num_items: usize) {
debug_assert!(num_items <= 24);
debug_assert!(num_items <= BLOCK_COPY_SIZE);
unsafe {
let dst_ptr_end = dst_ptr.add(num_items);
if (dst_ptr as usize) < dst_ptr_end as usize {
std::ptr::copy_nonoverlapping(source, dst_ptr, 24);
std::ptr::copy_nonoverlapping(source, dst_ptr, BLOCK_COPY_SIZE);
}
}
}
Expand Down Expand Up @@ -209,8 +212,9 @@ pub fn decompress_into(input: &[u8], output: &mut Vec<u8>) -> Result<(), Error>
let start_ptr = unsafe { output_ptr.sub(offset as usize) };

let match_length = (4 + (token & 0xF)) as usize;
// Write the duplicate segment to the output buffer.
if (output_ptr as usize) < unsafe { start_ptr.add(match_length) } as usize {
// Write the duplicate segment to the output buffer from the output buffer
// The blocks can overlap, make sure they are at least BLOCK_COPY_SIZE apart
if (output_ptr as usize) < unsafe { start_ptr.add(match_length).add(BLOCK_COPY_SIZE) } as usize {
duplicate_overlapping(&mut output_ptr, start_ptr, match_length);
} else {
unsafe {
Expand Down

0 comments on commit 286ea4c

Please sign in to comment.