Skip to content

Vec::drain is unsound with range_bounds_assert_len feature #81157

Closed
@KamilaBorowska

Description

@KamilaBorowska

Manually implementing assert_len can cause unsoundness in Vec::drain. This only happens in nightly, as overriding assert_len is only possible in nightly releases.

The following program will segfault.

#![feature(range_bounds_assert_len)]

use std::cell::Cell;
use std::ops::{Bound, Range, RangeBounds};

struct EvilRange(Cell<bool>);

impl RangeBounds<usize> for EvilRange {
    fn start_bound(&self) -> Bound<&usize> {
        unimplemented!()
    }
    fn end_bound(&self) -> Bound<&usize> {
        unimplemented!()
    }
    fn assert_len(self, _len: usize) -> Range<usize> {
        0..42
    }
}

fn main() {
    vec![1, 2, 3].drain(EvilRange(Cell::new(false)));
}

Related issues: #76393, #81154.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-collectionsArea: `std::collections`C-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions