oceanbase / oceanbase/oceanbase
Oversized SDO_RELATE mask causes an unbounded stack allocation and ASan stack overflow
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 10.3k
- Forks
- 1.9k
- PR merge metrics
- No merged PRs in 30d
Description
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
-
Save the single attached file as
poc.py. -
Run it on a disposable development host:
python3 poc.py /path/to/oceanbase -
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,
runsANYINTERACTas 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:
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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at ObQueryRange::get_spatial_relationship_by_mask() and inspect the current VLA construction described in the issue. Run the attached poc.py against an OceanBase source checkout to reproduce the controls and ASan failure. Done means oversized masks are rejected before copying, bounded storage is used, and the 32 MiB case no longer causes a stack overflow.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100