diff --git a/src/paths.rs b/src/paths.rs index 0bf9800..50920ac 100644 --- a/src/paths.rs +++ b/src/paths.rs @@ -19,6 +19,7 @@ to */ // Strong bypasses pub const PTR_READ: [&str; 3] = ["core", "ptr", "read"]; +pub const PTR_READ_UNALIGNED: [&str; 3] = ["core", "ptr", "read_unaligned"]; pub const PTR_DIRECT_READ: [&str; 5] = ["core", "ptr", "const_ptr", "", "read"]; pub const INTRINSICS_COPY: [&str; 3] = ["core", "intrinsics", "copy"]; @@ -31,6 +32,8 @@ pub const VEC_FROM_RAW_PARTS: [&str; 4] = ["alloc", "vec", "Vec", "from_raw_part pub const TRANSMUTE: [&str; 4] = ["core", "intrinsics", "", "transmute"]; pub const PTR_WRITE: [&str; 3] = ["core", "ptr", "write"]; +pub const PTR_WRITE_UNALIGNED: [&str; 3] = ["core", "ptr", "write_unaligned"]; + pub const PTR_DIRECT_WRITE: [&str; 5] = ["core", "ptr", "mut_ptr", "", "write"]; pub const PTR_AS_REF: [&str; 5] = ["core", "ptr", "const_ptr", "", "as_ref"]; @@ -78,6 +81,7 @@ pub static SPECIAL_PATH_DISCOVERY: Lazy = pub static STRONG_LIFETIME_BYPASS_LIST: Lazy = Lazy::new(move || { PathSet::new(&[ &PTR_READ, + &PTR_READ_UNALIGNED, &PTR_DIRECT_READ, // &INTRINSICS_COPY, @@ -93,6 +97,7 @@ pub static WEAK_LIFETIME_BYPASS_LIST: Lazy = Lazy::new(move || { &TRANSMUTE, // &PTR_WRITE, + &PTR_WRITE_UNALIGNED, &PTR_DIRECT_WRITE, // &PTR_AS_REF, @@ -120,6 +125,7 @@ pub static STRONG_BYPASS_MAP: Lazy = Lazy::new(move || { hashmap! { PTR_READ.iter().map(|p| Symbol::intern(p)).collect::>() => BehaviorFlag::READ_FLOW, + PTR_READ_UNALIGNED.iter().map(|p| Symbol::intern(p)).collect::>() => BehaviorFlag::READ_FLOW, PTR_DIRECT_READ.iter().map(|p| Symbol::intern(p)).collect::>() => BehaviorFlag::READ_FLOW, // INTRINSICS_COPY.iter().map(|p| Symbol::intern(p)).collect::>() => BehaviorFlag::COPY_FLOW, @@ -138,6 +144,7 @@ pub static WEAK_BYPASS_MAP: Lazy = Lazy::new(move || { TRANSMUTE.iter().map(|p| Symbol::intern(p)).collect::>() => BehaviorFlag::TRANSMUTE, // PTR_WRITE.iter().map(|p| Symbol::intern(p)).collect::>() => BehaviorFlag::WRITE_FLOW, + PTR_WRITE_UNALIGNED.iter().map(|p| Symbol::intern(p)).collect::>() => BehaviorFlag::WRITE_FLOW, PTR_DIRECT_WRITE.iter().map(|p| Symbol::intern(p)).collect::>() => BehaviorFlag::WRITE_FLOW, // PTR_AS_REF.iter().map(|p| Symbol::intern(p)).collect::>() => BehaviorFlag::PTR_AS_REF, diff --git a/tests/panic_safety/unaligned.rs b/tests/panic_safety/unaligned.rs new file mode 100644 index 0000000..ae7cd0a --- /dev/null +++ b/tests/panic_safety/unaligned.rs @@ -0,0 +1,21 @@ +/*! +```rudra-test +test_type = "normal" +expected_analyzers = ["UnsafeDataflow"] +``` +!*/ + +use std::ptr; +fn unaligned_insertion_sort_unsafe(arr: &mut [T]) { + unsafe { + for i in 1..arr.len() { + let item = ptr::read_unaligned(&arr[i]); + let mut j = i; + while j > 0 && arr[j - 1] > item { + ptr::swap(arr.as_mut_ptr().add(j), arr.as_mut_ptr().add(j - 1)); + j -= 1; + } + ptr::write_unaligned(arr.as_mut_ptr().add(j), item); + } + } +}