#2482·oceanbase

Oversized SDO_RELATE mask causes an unbounded stack allocation and ASan stack overflow

Author: Wwwing301Created Sep 9, 2026Updated Sep 9, 2026

Self Checks

  • I have read the Contributing Guide.
  • This is only for bug report, if you would like to ask a question, please head to Discussions.
  • I have searched for existing issues search for existing issues, including closed ones.
  • I confirm that I am using English to submit this report, otherwise it will be closed.
  • 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
  • Please do not modify this template :) and fill in all the required fields.

OceanBase version

OceanBase CE 5.0.2.0, source revision d128661ca4f5b3d167c1928e556d70d2f901baef.

Self Hosted

Self Hosted (Source)

Environment

Ubuntu 22.04.5 LTS, x86_64, GCC 9.5.0, AddressSanitizer, 8 MiB process stack limit. The attached poc.py needs Python 3, g++, and the affected OceanBase source checkout.

Steps to reproduce

  1. Save the single attached file as poc.py.

  2. Run it on a disposable development host:

    bash
    python3 poc.py /path/to/oceanbase
  3. The script verifies the current VLA in ObQueryRange::get_spatial_relationship_by_mask(), compiles a minimal AddressSanitizer fixture for the same length-to-stack-allocation operation, runs ANYINTERACT as a control, and then supplies a 32 MiB mask.

Observed control:

control: ret=0 op=INTERSECTS

The compact attached PoC reports the same stack-overflow class with parse_mask as its top frame:

AddressSanitizer:DEADLYSIGNAL
ERROR: AddressSanitizer: stack-overflow
    #0 parse_mask(...)
SUMMARY: AddressSanitizer: stack-overflow ... parse_mask
REPRODUCED: mask length controls an unbounded stack allocation

The current production function performs:

cpp
char cmp_str[upper_str.length() + 1];
cmp_str[upper_str.length()] = '\0';
MEMCPY(cmp_str, upper_str.ptr(), upper_str.length());

The authoritative source-anchored run compiled the exact current production function. It had three clean controls and one ASan stack-overflow with return code -6, with ObQueryRange::get_spatial_relationship_by_mask() as the top frame. Its result SHA-256 is 76ed63b1a7484a73efc331fc986168339ada91edf743eb234deae5e6007189b2.

✔️ Expected Behavior

Spatial mask parsing should use bounded storage and reject an unreasonable mask length before copying it. User-controlled length must not determine an unbounded stack allocation.

❌ Actual Behavior

The function sizes a stack VLA directly from the mask length. A 32 MiB component mask exhausts the thread stack and AddressSanitizer reports a stack overflow in the current function.