While fuzzing the Boost.Program_options config parser, I first saw a UUM-style symptom. After reducing the input and checking the source, this looks like a one-byte read before m_prefix in boost::program_options::detail::common_config_file_iterator::get().
The relevant code is in libs/program_options/src/config_file.cpp:
if (*s.begin() == '[' && *s.rbegin() == ']') {
m_prefix = s.substr(1, s.size()-2);
if (*m_prefix.rbegin() != '.')
m_prefix += '.';
}
For an empty section line, [], s.substr(1, s.size()-2) makes m_prefix empty. The next line then dereferences m_prefix.rbegin().
Minimal input:
[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]
[]
With memory checking, this reports an invalid read of size 1 at the m_prefix.rbegin() dereference. The first long section makes m_prefix use heap storage in the tested environment, and the following empty section triggers the empty-string case.
I also checked the ordinary native behavior. I did not find a practical native crash, useful information disclosure, control-flow impact, or unique option-injection behavior. The visible parser-state effect is limited: after the empty section, the next key can become .value, but the same result is also reachable with a valid [.] section.
So I am reporting this as a robustness / undefined behavior bug, not as a demonstrated security issue.
A narrow fix would be to handle the empty section-name case before dereferencing m_prefix.rbegin(). Depending on the intended grammar, [] could either be rejected as invalid config syntax or explicitly allowed without reading from the empty string.
While fuzzing the Boost.Program_options config parser, I first saw a UUM-style symptom. After reducing the input and checking the source, this looks like a one-byte read before
m_prefixinboost::program_options::detail::common_config_file_iterator::get().The relevant code is in
libs/program_options/src/config_file.cpp:For an empty section line,
[],s.substr(1, s.size()-2)makesm_prefixempty. The next line then dereferencesm_prefix.rbegin().Minimal input:
With memory checking, this reports an invalid read of size 1 at the
m_prefix.rbegin()dereference. The first long section makesm_prefixuse heap storage in the tested environment, and the following empty section triggers the empty-string case.I also checked the ordinary native behavior. I did not find a practical native crash, useful information disclosure, control-flow impact, or unique option-injection behavior. The visible parser-state effect is limited: after the empty section, the next key can become
.value, but the same result is also reachable with a valid[.]section.So I am reporting this as a robustness / undefined behavior bug, not as a demonstrated security issue.
A narrow fix would be to handle the empty section-name case before dereferencing
m_prefix.rbegin(). Depending on the intended grammar,[]could either be rejected as invalid config syntax or explicitly allowed without reading from the empty string.