Skip to content

Potential overflow when calling util::bit_mask::set_bits (soundness issue) #9543

@lewismosciski

Description

@lewismosciski

Hi there!

We scanned the most popular libraries on crates.io and found some memory safety bugs in this library.

util::bit_mask::set_bits

PoC

use arrow_buffer::bit_mask::set_bits;

fn main() {
    // Tiny buffers so any huge computed index is out-of-bounds.
    let data = [0u8; 1];
    let mut write_data = [0u8; 1];

    // Choose values so (offset_read + len) wraps to a small number in release builds.
    // offset_read = usize::MAX - 7, len = 8 => wraps to 0.
    // This can bypass `assert!(offset_read + len <= data.len() * 8)`.
    let offset_write: usize = 0;
    let offset_read: usize = usize::MAX - 7;
    let len: usize = 8;

    // Triggers unsafe internal `get_unchecked` with a massive `read_byte = offset_read / 8`.
    let _nulls = set_bits(&mut write_data, &data, offset_write, offset_read, len);

    // Keep the result observable so the call isn't optimized away.
    std::hint::black_box(write_data);
}

Miri Output

error: Undefined Behavior: in-bounds pointer arithmetic failed: attempting to offset pointer by 2305843009213693951 bytes, but got alloc242 which is only 1 byte from the end of the allocation
   --> /home/ccuu/Desktop/llm-detector/experiments/cache/crates_src/arrow-buffer/58.0.0/arrow-buffer-58.0.0/src/util/bit_mask.rs:135:24
    |
135 |     let src = unsafe { data.as_ptr().add(offset) };
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
help: alloc242 was allocated here:
   --> src/main.rs:9:9
    |
  9 |     let data = [0u8; 1];
    |         ^^^^
    = note: BACKTRACE (of the first span):
    = note: inside `arrow_buffer::bit_mask::read_bytes_to_u64` at /home/ccuu/Desktop/llm-detector/experiments/cache/crates_src/arrow-buffer/58.0.0/arrow-buffer-58.0.0/src/util/bit_mask.rs:135:24: 135:49
    = note: inside `arrow_buffer::bit_mask::set_upto_64bits` at /home/ccuu/Desktop/llm-detector/experiments/cache/crates_src/arrow-buffer/58.0.0/arrow-buffer-58.0.0/src/util/bit_mask.rs:116:30: 116:71
    = note: inside `arrow_buffer::bit_mask::set_bits` at /home/ccuu/Desktop/llm-detector/experiments/cache/crates_src/arrow-buffer/58.0.0/arrow-buffer-58.0.0/src/util/bit_mask.rs:44:13: 50:14
note: inside `main`
   --> src/main.rs:20:18
    |
 20 |     let _nulls = set_bits(&mut write_data, &data, offset_write, offset_read, len);
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to 1 previous error

Metadata

Metadata

Assignees

Labels

arrowChanges to the arrow cratebug

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions