Skip to content

Commit 371c984

Browse files
ksj1230robert3005
andauthored
Fix integer overflow in BitBufferMut::truncate and append_n (#8474)
## Summary Several methods on `BitBufferMut` use unchecked arithmetic on offset/length values, which can overflow in release mode and lead to undefined behavior reachable entirely from safe code (`#![forbid(unsafe_code)]`). Affected methods: - `truncate`: `self.offset + len` overflows, causing the buffer to be truncated to an incorrect size. - `append_n`: `self.offset + self.len + n` overflows, causing incorrect capacity calculation. Fix: add overflow assertions before the unchecked addition. Reproduction (all use `#![forbid(unsafe_code)]`): ```rust // 1. truncate let buffer = ByteBufferMut::zeroed(10); let mut bb = BitBufferMut::from_buffer(buffer, usize::MAX - 2, 80); bb.truncate(3); bb.set(2); // 2. append_n let buffer = ByteBufferMut::zeroed(2); let mut bb = BitBufferMut::from_buffer(buffer, 1000, 0); bb.append_n(true, usize::MAX); bb.set(10000); ``` Related: #7979 (the `BufferMut::zeroed_aligned` overflow I reported to maintainers in April 2025; this PR addresses additional overflow sites found during the same audit) ## Testing Existing `cargo test -p vortex-buffer` passes (789 tests + 6 doc-tests). Both PoCs now panic with overflow message instead of UB. Happy to adjust the approach if maintainers prefer a different fix strategy. --------- Signed-off-by: Sungjin Kim <carp1230@gmail.com> Signed-off-by: Robert Kruszewski <github@robertk.io> Co-authored-by: Robert Kruszewski <github@robertk.io>
1 parent 0c7e0ff commit 371c984

1 file changed

Lines changed: 11 additions & 0 deletions

File tree

vortex-buffer/src/bit/buf_mut.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,10 @@ impl BitBufferMut {
378378
return;
379379
}
380380

381+
assert!(
382+
self.offset <= usize::MAX - len,
383+
"Truncate on BitBufferMut overflowed"
384+
);
381385
let end_bit = self.offset + len;
382386
let new_len_bytes = end_bit.div_ceil(8);
383387
self.buffer.truncate(new_len_bytes);
@@ -444,6 +448,13 @@ impl BitBufferMut {
444448
return;
445449
}
446450

451+
assert!(
452+
self.offset
453+
.checked_add(self.len)
454+
.and_then(|v| v.checked_add(n))
455+
.is_some(),
456+
"Append on BitBufferMut overflowed"
457+
);
447458
let end_bit_pos = self.offset + self.len + n;
448459
let required_bytes = end_bit_pos.div_ceil(8);
449460

0 commit comments

Comments
 (0)