Skip to content

Fix use-after-free in ParsedConfigCache for short config strings#13078

Merged
maskit merged 1 commit intoapache:masterfrom
maskit:fix_targeted_cache_control
Apr 13, 2026
Merged

Fix use-after-free in ParsedConfigCache for short config strings#13078
maskit merged 1 commit intoapache:masterfrom
maskit:fix_targeted_cache_control

Conversation

@maskit
Copy link
Copy Markdown
Member

@maskit maskit commented Apr 9, 2026

  • Fix use-after-free in ParsedConfigCache when config values are short enough for std::string SSO (Small String Optimization)
  • ParsedValue::parse() returned by value, and emplace moved it into the map — relocating the SSO inline buffer while string_views in TargetedCacheControlHeaders::headers[] still pointed to the old address
  • Make ParsedValue non-movable and use try_emplace + parse_into() so parsing happens directly in the map node
  • Also fixes the same class of bug for HostResData::conf_value and HttpStatusCodeList::conf_value pointers

Reproducer: configure conf_remap with a short targeted header value like ACME-Cache-Control (18 chars, within libc++ SSO threshold of 22). The string_views in the per-transaction override become dangling, causing incorrect cache behavior.

The SSO threshold varies by standard library — libc++ (macOS/clang): 22 bytes, libstdc++ (GCC/Linux): 15 bytes. A value like ACME-Cache-Control (18 chars) triggers SSO on libc++ but uses heap allocation on libstdc++, where the buffer pointer survives the move. This is why the bug may reproduce on macOS but not on Linux CI with GCC.

- Fix use-after-free in ParsedConfigCache when config values are short enough for std::string SSO (Small String Optimization)
- ParsedValue::parse() returned by value, and emplace moved it into the map — relocating the SSO inline buffer while string_views in TargetedCacheControlHeaders::headers[] still pointed to the old address
- Make ParsedValue non-movable and use try_emplace + parse_into() so parsing happens directly in the map node
- Also fixes the same class of bug for HostResData::conf_value and HttpStatusCodeList::conf_value pointers

Reproducer: configure conf_remap with a short targeted header value like ACME-Cache-Control (18 chars, within libc++ SSO threshold of 22). The string_views in the per-transaction override become dangling, causing incorrect cache
behavior.

The SSO threshold varies by standard library — libc++ (macOS/clang): 22 bytes, libstdc++ (GCC/Linux): 15 bytes. A value like ACME-Cache-Control (18 chars) triggers SSO on libc++ but uses heap allocation on libstdc++, where the buffer
pointer survives the move. This is why the bug may reproduce on macOS but not on Linux CI with GCC.
@maskit maskit added this to the 11.0.0 milestone Apr 9, 2026
@maskit maskit self-assigned this Apr 9, 2026
@maskit maskit added the Bug label Apr 9, 2026
Copy link
Copy Markdown
Contributor

@brbzull0 brbzull0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!
Thanks.

@maskit maskit merged commit 4f97333 into apache:master Apr 13, 2026
15 checks passed
@github-project-automation github-project-automation Bot moved this to For v10.2.0 in ATS v10.2.x Apr 13, 2026
@cmcfarlen cmcfarlen moved this from For v10.2.0 to Picked v10.2.0 in ATS v10.2.x Apr 15, 2026
@cmcfarlen cmcfarlen modified the milestones: 11.0.0, 10.2.0 Apr 15, 2026
@cmcfarlen
Copy link
Copy Markdown
Contributor

Cherry-picked to 10.2.x

cmcfarlen pushed a commit that referenced this pull request Apr 15, 2026
)

- Fix use-after-free in ParsedConfigCache when config values are short enough for std::string SSO (Small String Optimization)
- ParsedValue::parse() returned by value, and emplace moved it into the map — relocating the SSO inline buffer while string_views in TargetedCacheControlHeaders::headers[] still pointed to the old address
- Make ParsedValue non-movable and use try_emplace + parse_into() so parsing happens directly in the map node
- Also fixes the same class of bug for HostResData::conf_value and HttpStatusCodeList::conf_value pointers

Reproducer: configure conf_remap with a short targeted header value like ACME-Cache-Control (18 chars, within libc++ SSO threshold of 22). The string_views in the per-transaction override become dangling, causing incorrect cache
behavior.

The SSO threshold varies by standard library — libc++ (macOS/clang): 22 bytes, libstdc++ (GCC/Linux): 15 bytes. A value like ACME-Cache-Control (18 chars) triggers SSO on libc++ but uses heap allocation on libstdc++, where the buffer
pointer survives the move. This is why the bug may reproduce on macOS but not on Linux CI with GCC.

(cherry picked from commit 4f97333)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Picked v10.2.0

Development

Successfully merging this pull request may close these issues.

3 participants