Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sliced() function on polars-arrow Array is unsound, allows out-of-bounds access in release mode #20239

Open
2 tasks done
Nathan-Fenner opened this issue Dec 10, 2024 · 0 comments · May be fixed by #21207
Open
2 tasks done
Labels
bug Something isn't working needs triage Awaiting prioritization by a maintainer rust Related to Rust Polars

Comments

@Nathan-Fenner
Copy link

Checks

  • I have checked that this issue has not already been reported.
  • I have confirmed this bug exists on the latest version of Polars.

Reproducible example

fn main() {
    let arr = polars_arrow::array::Int32Array::from_values([1, 2, 3, 4, 5]);

    // (assuming 64-bit usize values)
    //
    // In debug mode, this panics since `(1<<63) + (1<<63)` overflows [correct behavior]
    // In release mode, this creates a very, very long slice that accesses out-of-bounds memory [incorrect, unsound behavior]
    let sliced = arr.sliced(1 << 63, 1 << 63);

    println!("{:?}", sliced);
}

Log output

No response

Issue description

The code for the sliced function attempts to perform a bounds-check to prevent the returned array from going out-of-bounds:

        #[inline]
        #[must_use]
        pub fn sliced(self, offset: usize, length: usize) -> Self {
            assert!(
                offset + length <= self.len(),
                "the offset of the new Buffer cannot exceed the existing length"
            );
            unsafe { Self::sliced_unchecked(self, offset, length) }
        }

In debug mode, the expression offset + length will panic on overflow, which makes this check correct.

In release mode, the expression offset + length will wrap, possibly producing a value that's smaller than self.len() even though the new slice is out-of-bounds.

Expected behavior

sliced() should also panic in release mode if given out-of-bounds arguments.

Installed versions

[dependencies]
polars-arrow = "0.45.1"
@Nathan-Fenner Nathan-Fenner added bug Something isn't working needs triage Awaiting prioritization by a maintainer rust Related to Rust Polars labels Dec 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs triage Awaiting prioritization by a maintainer rust Related to Rust Polars
Projects
None yet
1 participant