Fix nullptr crash in RecConfigOverrideFromEnvironment with runroot#12917
Fix nullptr crash in RecConfigOverrideFromEnvironment with runroot#12917brbzull0 wants to merge 1 commit intoapache:masterfrom
Conversation
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.
There was a problem hiding this comment.
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 ofnullptr) 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 returnsvalueregardless of whetherRecConfigOverrideFromRunroot(name)is true or false (whenenvvalis unset), so thiselse ifbranch is redundant and adds an unnecessaryRecConfigOverrideFromRunroot()call on the hot path while parsing every record. Consider removing theelse ifentirely (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; |
There was a problem hiding this comment.
Why this else if ? you return "value" regardless of the value of RecConfigOverrideFromRunroot(name)), no?
zwoop
left a comment
There was a problem hiding this comment.
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. |
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 astd::logic_erro`r crash during records.yaml parsing:The nullptr was assigned to
std::stringinSetRecordFromYAMLNode(), 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.