Bypass debug_assert!
|
impl InlineString { |
|
#[cfg_attr(feature = "nightly", allow(inline_always))] |
|
#[inline(always)] |
|
fn assert_sanity(&self) { |
|
debug_assert!( |
|
self.length as usize <= INLINE_STRING_CAPACITY, |
|
"inlinable_string: internal error: length greater than capacity" |
|
); |
|
debug_assert!( |
|
str::from_utf8(&self.bytes[0..self.length as usize]).is_ok(), |
|
"inlinable_string: internal error: contents are not valid UTF-8!" |
|
); |
|
} |
We consider that the protection of
assert_sanity is not sufficient to check the validity of string due to removed
debug_assert! in release mode.
PoC
fn main() {
let mut s = InlineString::from("A");
{
let bytes: &mut [u8] = s.as_mut();
bytes[0] = 0xFF; // invalid UTF-8 byte
}
// attack vector 1: AsRef<str>::as_ref -> from_utf8_unchecked
let _a: &str = s.as_ref();
// attack vector 2: Index<RangeFull> -> from_utf8_unchecked
let _b: &str = &s[..];
// attack vector 3: Deref -> from_utf8_unchecked
let _c: &str = &*s;
}
With cargo run in nightly version
thread 'main' panicked at /home/usr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/inlinable_string-0.1.15/src/inline_string.rs:283:9:
inlinable_string: internal error: contents are not valid UTF-8!
However, if run with cargo run --release, no error message will show. Maybe consider changing it to assert! instead? Or change it to str::from_utf8 to do error handling could be more straightforward.
Bypass
debug_assert!inlinable_string/src/inline_string.rs
Lines 275 to 287 in f7c0a33
We consider that the protection of
assert_sanityis not sufficient to check the validity of string due to removeddebug_assert!in release mode.PoC
With
cargo runin nightly versionHowever, if run with
cargo run --release, no error message will show. Maybe consider changing it toassert!instead? Or change it tostr::from_utf8to do error handling could be more straightforward.