Skip to content

Commit

Permalink
remove find slice function, fix UB
Browse files Browse the repository at this point in the history
Fixed UB by replacing pointer dereference with read_volatile in scalar
scanning
  • Loading branch information
localcc committed Nov 12, 2023
1 parent 9e05534 commit 65b93d5
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 42 deletions.
9 changes: 6 additions & 3 deletions benches/scan_1gb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,24 @@ fn benchmark(c: &mut Criterion) {
group.bench_function("scalar", |b| {
let scanner = Scanner::new("48 89 5c 24 ?? 48 89 6c 24 ?? 48 89 74 24 ?? 48 89 7c 24 ?? 41 56 41 57 4c 8b 79 38 aa bf cd");
b.iter(|| {
scanner.find(Some(ScanMode::Scalar), &data)
// SAFETY: data is a valid slice
unsafe { scanner.find(Some(ScanMode::Scalar), data.as_ptr(), data.len()) }
});
});

group.bench_function("sse4.2", |b| {
let scanner = Scanner::new("48 89 5c 24 ?? 48 89 6c 24 ?? 48 89 74 24 ?? 48 89 7c 24 ?? 41 56 41 57 4c 8b 79 38 aa bf cd");
b.iter(|| {
scanner.find(Some(ScanMode::Sse42), &data)
// SAFETY: data is a valid slice
unsafe { scanner.find(Some(ScanMode::Sse42), data.as_ptr(), data.len()) }
});
});

group.bench_function("avx2", |b| {
let scanner = Scanner::new("48 89 5c 24 ?? 48 89 6c 24 ?? 48 89 74 24 ?? 48 89 7c 24 ?? 41 56 41 57 4c 8b 79 38 aa bf cd");
b.iter(|| {
scanner.find(Some(ScanMode::Avx2), &data)
// SAFETY: data is a valid slice
unsafe { scanner.find(Some(ScanMode::Avx2), data.as_ptr(), data.len()) }
});
});

Expand Down
2 changes: 1 addition & 1 deletion src/backends/scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub unsafe fn find(pattern: &Pattern, binary: *const u8, binary_size: usize) ->
};

// SAFETY: checked addr is always in binary bounds
if unsafe { *checked_addr } != pattern.data[pattern_offset] {
if unsafe { checked_addr.read_volatile() } != pattern.data[pattern_offset] {
found = false;
break;
}
Expand Down
32 changes: 3 additions & 29 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//! let binary = [0xab, 0xec, 0x48, 0x89, 0x5c, 0x24, 0xee, 0x48, 0x89, 0x6c];
//!
//! let scanner = Scanner::new("48 89 5c 24 ?? 48 89 6c");
//! let result = scanner.find(None, &binary);
//! let result = unsafe { scanner.find(None, binary.as_ptr(), binary.len()) };
//!
//! println!("{:?}", result);
//! ```
Expand Down Expand Up @@ -42,32 +42,6 @@ impl Scanner {
Scanner(Pattern::new(pattern))
}

/// Find the first occurence of the pattern in the binary
///
/// # Params
///
/// * `preferred_scan_mode` - preferred scan mode to use (Avx2, Sse42, Scalar)
/// if the preferred mode is not available, will choose the fastest out of the availble ones
///
/// * `binary` - binary to search for the pattern in
///
/// # Example
///
/// ```
/// use lightningscanner::Scanner;
///
/// let binary = [0xab, 0xec, 0x48, 0x89, 0x5c, 0x24, 0xee, 0x48, 0x89, 0x6c];
///
/// let scanner = Scanner::new("48 89 5c 24 ?? 48 89 6c");
/// let result = scanner.find(None, &binary);
///
/// println!("{:?}", result);
/// ```
pub fn find(&self, preferred_scan_mode: Option<ScanMode>, binary: &[u8]) -> ScanResult {
// SAFETY: always safe to call because binary is a valid slice
unsafe { self.find_ptr(preferred_scan_mode, binary.as_ptr(), binary.len()) }
}

/// Find the first occurence of the pattern in the binary
///
/// # Params
Expand All @@ -93,11 +67,11 @@ impl Scanner {
/// let binary = [0xab, 0xec, 0x48, 0x89, 0x5c, 0x24, 0xee, 0x48, 0x89, 0x6c];
///
/// let scanner = Scanner::new("48 89 5c 24 ?? 48 89 6c");
/// let result = unsafe { scanner.find_ptr(None, binary.as_ptr(), binary.len()) };
/// let result = unsafe { scanner.find(None, binary.as_ptr(), binary.len()) };
///
/// println!("{:?}", result);
/// ```
pub unsafe fn find_ptr(
pub unsafe fn find(
&self,
preferred_scan_mode: Option<ScanMode>,
binary_ptr: *const u8,
Expand Down
9 changes: 6 additions & 3 deletions tests/big_pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ const DATA_SET: [u8; 128] = [
#[cfg(target_feature = "avx2")]
fn avx2() {
let scanner = Scanner::new(PATTERN);
let result = scanner.find(Some(ScanMode::Avx2), &DATA_SET);
// SAFETY: DATA_SET is a valid slice
let result = unsafe { scanner.find(Some(ScanMode::Avx2), DATA_SET.as_ptr(), DATA_SET.len()) };

let data_set_addr = DATA_SET.as_ptr() as usize;
let ptr = result.get_addr() as usize;
Expand All @@ -29,7 +30,8 @@ fn avx2() {
#[cfg(target_feature = "sse4.2")]
fn sse42() {
let scanner = Scanner::new(PATTERN);
let result = scanner.find(Some(ScanMode::Sse42), &DATA_SET);
// SAFETY: DATA_SET is a valid slice
let result = unsafe { scanner.find(Some(ScanMode::Sse42), DATA_SET.as_ptr(), DATA_SET.len()) };

let data_set_addr = DATA_SET.as_ptr() as usize;
let ptr = result.get_addr() as usize;
Expand All @@ -40,7 +42,8 @@ fn sse42() {
#[test]
fn scalar() {
let scanner = Scanner::new(PATTERN);
let result = scanner.find(Some(ScanMode::Scalar), &DATA_SET);
// SAFETY: DATA_SET is a valid slice
let result = unsafe { scanner.find(Some(ScanMode::Scalar), DATA_SET.as_ptr(), DATA_SET.len()) };

let data_set_addr = DATA_SET.as_ptr() as usize;
let ptr = result.get_addr() as usize;
Expand Down
9 changes: 6 additions & 3 deletions tests/similar_pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ const DATA_SET: [u8; 72] = [
#[cfg(target_feature = "avx2")]
fn avx2() {
let scanner = Scanner::new(PATTERN);
let result = scanner.find(Some(ScanMode::Avx2), &DATA_SET);
// SAFETY: DATA_SET is a valid slice
let result = unsafe { scanner.find(Some(ScanMode::Avx2), DATA_SET.as_ptr(), DATA_SET.len()) };

let data_set_addr = DATA_SET.as_ptr() as usize;
let ptr = result.get_addr() as usize;
Expand All @@ -26,7 +27,8 @@ fn avx2() {
#[cfg(target_feature = "sse4.2")]
fn sse42() {
let scanner = Scanner::new(PATTERN);
let result = scanner.find(Some(ScanMode::Sse42), &DATA_SET);
// SAFETY: DATA_SET is a valid slice
let result = unsafe { scanner.find(Some(ScanMode::Sse42), DATA_SET.as_ptr(), DATA_SET.len()) };

let data_set_addr = DATA_SET.as_ptr() as usize;
let ptr = result.get_addr() as usize;
Expand All @@ -37,7 +39,8 @@ fn sse42() {
#[test]
fn scalar() {
let scanner = Scanner::new(PATTERN);
let result = scanner.find(Some(ScanMode::Scalar), &DATA_SET);
// SAFETY: DATA_SET is a valid slice
let result = unsafe { scanner.find(Some(ScanMode::Scalar), DATA_SET.as_ptr(), DATA_SET.len()) };

let data_set_addr = DATA_SET.as_ptr() as usize;
let ptr = result.get_addr() as usize;
Expand Down
9 changes: 6 additions & 3 deletions tests/small_pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ const DATA_SET: [u8; 128] = [
#[cfg(target_feature = "avx2")]
fn avx2() {
let scanner = Scanner::new(PATTERN);
let result = scanner.find(Some(ScanMode::Avx2), &DATA_SET);
// SAFETY: DATA_SET is a valid slice
let result = unsafe { scanner.find(Some(ScanMode::Avx2), DATA_SET.as_ptr(), DATA_SET.len()) };

let data_set_addr = DATA_SET.as_ptr() as usize;
let ptr = result.get_addr() as usize;
Expand All @@ -29,7 +30,8 @@ fn avx2() {
#[cfg(target_feature = "sse4.2")]
fn sse42() {
let scanner = Scanner::new(PATTERN);
let result = scanner.find(Some(ScanMode::Sse42), &DATA_SET);
// SAFETY: DATA_SET is a valid slice
let result = unsafe { scanner.find(Some(ScanMode::Sse42), DATA_SET.as_ptr(), DATA_SET.len()) };

let data_set_addr = DATA_SET.as_ptr() as usize;
let ptr = result.get_addr() as usize;
Expand All @@ -40,7 +42,8 @@ fn sse42() {
#[test]
fn scalar() {
let scanner = Scanner::new(PATTERN);
let result = scanner.find(Some(ScanMode::Scalar), &DATA_SET);
// SAFETY: DATA_SET is a valid slice
let result = unsafe { scanner.find(Some(ScanMode::Scalar), DATA_SET.as_ptr(), DATA_SET.len()) };

let data_set_addr = DATA_SET.as_ptr() as usize;
let ptr = result.get_addr() as usize;
Expand Down

0 comments on commit 65b93d5

Please sign in to comment.