Skip to content

Potential Soundness Issues #18

Description

@sisy2020

Hi, I noticed a couple of potential soundness issues in i_triangle 0.26.0. Both seem to rely on crate-internal invariants being upheld.

  1. Delaunay::build
    In src/delaunay/delaunay.rs:
pub(crate) fn build(&mut self) {
    let count = self.triangles.len();
    let mut visit_marks = vec![false; count];
    // ...
    let mut triangle = *unsafe { self.triangles.get_unchecked(i) };
    // ...
    for k in 0..3 {
        let neighbor_index = triangle.neighbor_by_order(k);
        if neighbor_index.is_nil() {
            continue;
        }
        let neighbor = *unsafe { self.triangles.get_unchecked(neighbor_index) };
        // ...
    }
}

This assumes that every non-NIL value in DTriangle.neighbors is a valid index into self.triangles. If an internal construction path ever produces a triangle with a neighbor index greater than or equal to self.triangles.len(), the call to get_unchecked(neighbor_index) would be out of bounds.

  1. MSliceBuffer::new
    In src/monotone/mslice_buffer.rs:
pub(crate) fn new(vertex_count: usize, slices: &[MSlice]) -> Self {
    let mut vertex_marks = vec![false; vertex_count];
    let mut edges = vec![Edge::EMPTY; slices.len()];

    for (i, slice) in slices.iter().enumerate() {
        unsafe {
            *vertex_marks.get_unchecked_mut(slice.a) = true;
            *vertex_marks.get_unchecked_mut(slice.b) = true;

            let id = Self::id(vertex_count, slice.a, slice.b);
            *edges.get_unchecked_mut(i) = Edge {
                id,
                edge: NIL_INDEX,
                triangle: NIL_INDEX,
            };
        }
    }
    // ...
}

This assumes that both slice.a and slice.b are smaller than vertex_count. Since MSlice::new(a, b) accepts arbitrary endpoint values, an internal caller could potentially pass an endpoint outside the bounds of vertex_marks, making either unchecked write out of bounds.

Thanks for taking a look!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions