Skip to content

Boost.Program_options config parser reads before m_prefix for empty section [] #156

@Carmel0

Description

@Carmel0

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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions