Skip to content

Fix nullptr crash in RecConfigOverrideFromEnvironment with runroot#12917

Draft
brbzull0 wants to merge 1 commit intoapache:masterfrom
brbzull0:fix_rec_runroot_override
Draft

Fix nullptr crash in RecConfigOverrideFromEnvironment with runroot#12917
brbzull0 wants to merge 1 commit intoapache:masterfrom
brbzull0:fix_rec_runroot_override

Conversation

@brbzull0
Copy link
Contributor

When runroot is active and the PROXY_CONFIG_* environment variables for path records (bin_path, local_state_dir``, logfile_dir, plugin_dir) are not set, RecConfigOverrideFromEnvironment()returnednullptr. This violated its documented contract ("return either the overridden value, or the original value") and caused a std::logic_erro`r crash during records.yaml parsing:

  basic_string: construction from null is not valid

The nullptr was assigned to std::string in SetRecordFromYAMLNode(), which threw the exception. The bug was masked in autests because the framework always sets these env vars.

Fix: return the original config value instead of nullptr when RecConfigOverrideFromRunroot() matches. The record value is then resolved by Layout::relative() at runtime, producing the correct path.

Add a test that unsets the 4 path env vars to exercise the runroot code path, and validates record values via traffic_ctl config get.

When runroot is active and the PROXY_CONFIG_* environment variables for
path records (bin_path, local_state_dir, logfile_dir, plugin_dir) are
not set, RecConfigOverrideFromEnvironment() returned nullptr. This
violated its documented contract ("return either the overridden value,
or the original value") and caused a std::logic_error crash during
records.yaml parsing:

  basic_string: construction from null is not valid

The nullptr was assigned to std::string in SetRecordFromYAMLNode(),
which threw the exception. The bug was masked in autests because the
framework always sets these env vars.

Fix: return the original config value instead of nullptr when
RecConfigOverrideFromRunroot() matches. The record value is then
resolved by Layout::relative() at runtime, producing the correct path.

Add a test that unsets the 4 path env vars to exercise the runroot code
path, and validates record values via traffic_ctl config get.
@brbzull0 brbzull0 self-assigned this Feb 26, 2026
@brbzull0 brbzull0 added YAML Records Records related code. labels Feb 26, 2026
@bryancall bryancall requested a review from Copilot March 2, 2026 22:52
@bryancall bryancall added this to the 11.0.0 milestone Mar 2, 2026
@bryancall bryancall requested a review from zwoop March 2, 2026 22:53
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a crash in ATS records.yaml parsing when runroot is enabled and certain PROXY_CONFIG_* path environment variables are unset, by ensuring RecConfigOverrideFromEnvironment() never returns nullptr for those records. This keeps the function’s contract intact and prevents exceptions when converting the returned C string into a std::string.

Changes:

  • Update RecConfigOverrideFromEnvironment() to return the original record value (instead of nullptr) for runroot-managed path records when no env override exists.
  • Add a gold test that unsets the four path env vars to reproduce the previous crash path and validates resulting record values via traffic_ctl.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/records/RecConfigParse.cc Prevents nullptr from being returned during env override resolution under runroot, avoiding downstream std::string(nullptr) crashes.
tests/gold_tests/records/records_runroot_null_override.test.py Adds regression coverage for the runroot + missing env-var scenario and verifies both env overrides and path-record behavior.
Comments suppressed due to low confidence (1)

src/records/RecConfigParse.cc:129

  • RecConfigOverrideFromEnvironment() now returns value regardless of whether RecConfigOverrideFromRunroot(name) is true or false (when envval is unset), so this else if branch is redundant and adds an unnecessary RecConfigOverrideFromRunroot() call on the hot path while parsing every record. Consider removing the else if entirely (or otherwise making the runroot branch do something meaningfully different).
  if (envval) {
    return envval;
  } else if (RecConfigOverrideFromRunroot(name)) {
    return value;
  }

  return value;

if (envval) {
return envval;
} else if (RecConfigOverrideFromRunroot(name)) {
return nullptr;
Copy link
Contributor

@zwoop zwoop Mar 3, 2026

Choose a reason for hiding this comment

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

Why this else if ? you return "value" regardless of the value of RecConfigOverrideFromRunroot(name)), no?

Copy link
Contributor

@zwoop zwoop left a comment

Choose a reason for hiding this comment

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

I think you should cleanup the else if, I think CoPilot said the same thing.

@brbzull0
Copy link
Contributor Author

brbzull0 commented Mar 4, 2026

I think you should cleanup the else if, I think CoPilot said the same thing.

thanks for pointing this out. I think I may have introduced a side effect bug. I'll ammend and put this back for review.

@brbzull0 brbzull0 marked this pull request as draft March 4, 2026 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Records Records related code. YAML

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants