Skip to content

contours(): unbounded segment buffer allocation enables memory DoS #1240

Description

@brendancol

Describe the bug

contours() allocates segment buffers sized to the full raster with no memory check. In _contours_numpy() at xrspatial/contour.py:303-308:

max_segs_per_level = (ny - 1) * (nx - 1) * 2
for level in levels:
    seg_rows = np.empty((max_segs_per_level, 2), dtype=np.float64)
    seg_cols = np.empty((max_segs_per_level, 2), dtype=np.float64)
    ...

Each buffer holds float64 pairs (16 bytes per segment), so peak per level is 32 * (ny-1) * (nx-1) bytes. A 10000x10000 raster uses ~3.2 GB per level; 20000x20000 uses ~12.8 GB per level. _stitch_segments then builds a Python dict keyed by every rounded endpoint on top of that.

contours() does not call _validate_raster and does not bound n_levels or the input shape, so the allocation is driven straight by a DataArray parameter.

To reproduce

import numpy as np
import xarray as xr
from xrspatial import contours

data = np.zeros((20000, 20000), dtype=np.float64)
data[::100, :] = 1.0  # many crossings
agg = xr.DataArray(data, dims=['y', 'x'])
contours(agg, n_levels=10)  # tries ~12.8 GB per level

Expected behavior

The numpy path should estimate peak allocation (2 * 16 * (ny-1) * (nx-1) bytes for the segment buffers) and raise MemoryError before np.empty when the estimate exceeds about half of available memory. The error should mention the dask backend or a smaller n_levels.

Scope

  • numpy: affected
  • cupy: affected (transfers to CPU and calls _contours_numpy)
  • dask+numpy, dask+cupy: not affected (each chunk is bounded by chunk size)

Additional context

Matches the memory guards in bump.py (#1231), viewshed.py (#1229), bilateral.py (#1236), pathfinding.py, and proximity.py, all of which call _available_memory_bytes() before large allocations.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghigh-priorityinput-validationInput validation and error messagesoomOut-of-memory risk with large datasets

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions