ANT-2026-QRPT15J8 · duckdb

stack-buffer-overflow high

Severity Claude critical · Security research firm high · Maintainer -

Discovered by Claude Mythos Preview

REPORT

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

  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

[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

SECURITY RESEARCH FIRM ANALYSIS

Triage and disclosure were performed by Trail of Bits.

Verdict
true positive
Severity
high
TIMELINE

Dates from discovery through public reveal.

  1. 2026-03-24 Reported to tracker
  2. 2026-04-29 Sent to maintainer
  3. 2026-04-29 Maintainer acknowledged
  4. 2026-06-16 Patch released
  5. 2026-08-17 Publicly revealed
PROVENANCE

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"
}