libspatialindex icon indicating copy to clipboard operation
libspatialindex copied to clipboard

bulkLoadUsingSTR crashes on ARM/aarch64 due to corrupted Region dimension

Open chance-spatial opened this issue 2 weeks ago • 13 comments

libspatialindex version: 2.1.0 (tarball from downloads) Platform: Ubuntu 22.04 LTS, aarch64 (GCC 15.1.0, CMake 3.29.0) Build flags: -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON (otherwise defaults)

Summary

Calling SpatialIndex::RTree::BulkLoader::bulkLoadUsingSTR on ARM consistently segfaults while constructing nodes. The Region copy constructor receives a fake m_dimension value (e.g. 0x14c0000002a instead of 2) and ends up copying ~21GB via inline_memcpy, which immediately SIGSEGVs.

This only happens when STR sorting is enabled; sequential insertions work fine, and the same workload on x86_64 is stable.

Steps to reproduce

  1. Build libspatialindex 2.1.0 on aarch64 (see flags above).
  2. Use the bundled RTree example or any program that bulk-loads ~300k 2D boxes via BulkLoader::bulkLoadUsingSTR.
  3. Run under gdb:
gdb -q ./bench_abc # any STR bulk-load driver
(gdb) set pagination off
(gdb) run
  1. The process crashes during the first STR level creation.

Observed backtrace

Thread 1 "bench_abc" received signal SIGSEGV, Segmentation fault.
0x0000fffff6fd5f64 in inline_memcpy (__len=0x53800000155, __src=0xfffff3402df0, __dest=0x10bd0c940)
at /usr/include/aarch64-linux-gnu/bits/string_fortified.h:34
#1 SpatialIndex::Region::Region(Region const&) (Region.cc:139)
#2 SpatialIndex::RTree::Leaf::insertEntry(unsigned int, unsigned char*, Region const&, long) (Leaf.cc:137)
#3 SpatialIndex::RTree::BulkLoader::createNode(...) (BulkLoader.cc:260)
#4 SpatialIndex::RTree::BulkLoader::createLevel(...) (BulkLoader.cc:224)
#5 SpatialIndex::RTree::BulkLoader::bulkLoadUsingSTR(...) (BulkLoader.cc:170)

Notes

  • m_dimension inside the Region created from the sorter is garbage when the crash happens
  • I tracked it to ExternalSorter::Record::loadFromFile coming back corrupted when STR reloads temporary files on Arm (likely due to short reads), so the guard should compare it against the tree’s expected dimension
  • the sorter could verify this value before calling Region::makeDimension
  • I have a fix in BulkLoader.{h,cc} + Region.cc and I’d like to contribute a proper fix here if possible.

chance-spatial avatar Dec 10 '25 17:12 chance-spatial