ReadSparseCOOIndex in cpp/src/arrow/ipc/reader.cc builds the COO indices Tensor with shape {non_zero_length, ndim} directly over indicesBuffer, but never checks the buffer is large enough to hold non_zero_length * ndim index elements. non_zero_length and the shape come unvalidated from the SparseTensor flatbuffer.
The sibling ReadSparseCSXIndex performs this check (indices_minimum_bytes > indices_buffer->length()), but the COO reader does not. A message declaring a large non_zero_length with a small indicesBuffer yields a COO index tensor whose shape exceeds its backing buffer, leading to an out-of-bounds read when the sparse tensor is consumed (for example, converted to dense). A non_zero_length near INT64_MAX also overflows the non_zero_length * ndim * byte_width product, so the size computation needs overflow-safe arithmetic.
Component(s)
C++
ReadSparseCOOIndexincpp/src/arrow/ipc/reader.ccbuilds the COO indicesTensorwith shape{non_zero_length, ndim}directly overindicesBuffer, but never checks the buffer is large enough to holdnon_zero_length * ndimindex elements.non_zero_lengthand the shape come unvalidated from the SparseTensor flatbuffer.The sibling
ReadSparseCSXIndexperforms this check (indices_minimum_bytes > indices_buffer->length()), but the COO reader does not. A message declaring a largenon_zero_lengthwith a smallindicesBufferyields a COO index tensor whose shape exceeds its backing buffer, leading to an out-of-bounds read when the sparse tensor is consumed (for example, converted to dense). Anon_zero_lengthnearINT64_MAXalso overflows thenon_zero_length * ndim * byte_widthproduct, so the size computation needs overflow-safe arithmetic.Component(s)
C++