ANT-2026-QRPT15J8 · duckdb
stack-buffer-overflow high
Severity Claude critical · Security research firm high · Maintainer -
Discovered by Claude Mythos Preview
Anthropic's analysis, sealed at approval. Disclosure to the maintainer was performed by Trail of Bits.
ANT-2026-QRPT15J8: Stack-buffer-overflow in sanitizer_common_interceptors.inc:827
DuckDB's parquet extension decodes dictionary-encoded columns using a fixed 128-byte stack buffer (aligned_data) in RleBpDecoder::GetBatch<unsigned int>. A malformed Parquet file can specify a bit width that causes BitUnpackAlignedInternal to memcpy more unpacked data than this buffer can hold, writing 252 bytes past its end. An attacker who can supply a Parquet file for DuckDB to read controls the overflowing data, yielding stack memory corruption and potential control-flow hijack.
Target
Project: duckdb
Location: sanitizer_common_interceptors.inc:827
Technical Details
ASAN: stack-buffer-overflow, WRITE of size 252. The memcpy in BitUnpackAlignedInternal (decode_utils.hpp:105) writes past the 128-byte stack array aligned_data (frame offset [160, 288)) because the unpacked output size — derived from an attacker-controlled bit width in the Parquet file — is not validated against the fixed buffer size.
Crash trace:
The PoC is a 375-byte crafted Parquet file that triggers a deterministic stack-buffer-overflow in DuckDB's parquet extension.
All 3 reproduction runs in a fresh Docker container produced identical results:
- Error: AddressSanitizer: stack-buffer-overflow (WRITE of size 252)
- Exit code: 134 (SIGABRT from ASAN)
- Root cause: In `RleBpDecoder::GetBatch<unsigned int>` (parquet_rle_bp_decoder.hpp:57), a `memcpy` in `BitUnpackAlignedInternal` (decode_utils.hpp:105) writes 252 bytes past the end of the stack-allocated `aligned_data` buffer (128 bytes at offset [160, 288)). The overflow occurs during dictionary-encoded column decoding when the bit width from the malformed Parquet file causes more data to be unpacked than the fixed-size buffer can hold.
- The crash is entirely in DuckDB project code (parquet extension), deterministic (3/3), not OOM or timeout, and represents a genuine memory safety vulnerability.
Reproduction
- Craft a Parquet file with a dictionary-encoded column whose bit width forces oversized unpacking
- Deliver the file to a DuckDB-based application (e.g., read_parquet / COPY FROM)
- During RLE/bit-packed decoding,
BitUnpackAlignedInternalmemcpy overflows the 128-bytealigned_datastack buffer by 252 bytes
[No reproducer or sanitizer output attached — request from security-cvd@anthropic.com if needed.]
Acknowledgement
This vulnerability was discovered by Claude, Anthropic's AI assistant, and triaged by the Anthropic security team in collaboration with Anthropic Research. Please direct questions to security-cvd@anthropic.com and reference ANT-2026-QRPT15J8.
Reference: ANT-2026-QRPT15J8
Anthropic CVD Policy: https://www.anthropic.com/coordinated-vulnerability-disclosure
Triage and disclosure were performed by Trail of Bits.
- Verdict
- true positive
- Severity
- high
Dates from discovery through public reveal.
- 2026-03-24 Reported to tracker
- 2026-04-29 Sent to maintainer
- 2026-04-29 Maintainer acknowledged
- 2026-06-16 Patch released
- 2026-08-17 Publicly revealed
SHA-3-512 hash:
594f0acb52de146e309c8d00e35a7d44242995d1b10dad1dd6295d7227f6773d7ac5cd12137562aac5a8bcd9c8a8b20e4cb531acf33f77a4ea416a3376b46ac6
Committed 2026-04-29 00:04 PT
Revealed 2026-08-17 10:47 PT
Verify (download preimage.json)
Show preimage JSON
{
"ant_id": "ANT-2026-QRPT15J8",
"bug_class": "Stack-buffer-overflow",
"claude_severity": "critical",
"commit_sha": null,
"created_at": "2026-03-24T18:31:39+00:00",
"description": "DuckDB's parquet extension decodes dictionary-encoded columns using a fixed 128-byte stack buffer (`aligned_data`) in `RleBpDecoder::GetBatch<unsigned int>`. A malformed Parquet file can specify a bit width that causes `BitUnpackAlignedInternal` to `memcpy` more unpacked data than this buffer can hold, writing 252 bytes past its end. An attacker who can supply a Parquet file for DuckDB to read controls the overflowing data, yielding stack memory corruption and potential control-flow hijack.",
"discovered_at": null,
"location": "sanitizer_common_interceptors.inc:827",
"poc_sha256": null,
"preimage_version": 1,
"project": "duckdb",
"reproduction": [
"1. Craft a Parquet file with a dictionary-encoded column whose bit width forces oversized unpacking",
"2. Deliver the file to a DuckDB-based application (e.g., read_parquet / COPY FROM)",
"3. During RLE/bit-packed decoding, `BitUnpackAlignedInternal` memcpy overflows the 128-byte `aligned_data` stack buffer by 252 bytes"
],
"technical_details": "ASAN: stack-buffer-overflow, WRITE of size 252. The `memcpy` in `BitUnpackAlignedInternal` (decode_utils.hpp:105) writes past the 128-byte stack array `aligned_data` (frame offset [160, 288)) because the unpacked output size — derived from an attacker-controlled bit width in the Parquet file — is not validated against the fixed buffer size.",
"title": "Stack-buffer-overflow in sanitizer_common_interceptors.inc:827",
"vendor_severity": "high"
}