[Bug 3947] New: servconf.c: unchecked strdup() in Include GLOB_NOMATCH path can cache a NULL selector and later crash in strcmp()

bugzilla-daemon at mindrot.org bugzilla-daemon at mindrot.org
Tue Apr 14 11:54:26 AEST 2026


https://bugzilla.mindrot.org/show_bug.cgi?id=3947

            Bug ID: 3947
           Summary: servconf.c: unchecked strdup() in Include GLOB_NOMATCH
                    path can cache a NULL selector and later crash in
                    strcmp()
           Product: Portable OpenSSH
           Version: 10.3p1
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P5
         Component: sshd
          Assignee: unassigned-bugs at mindrot.org
          Reporter: ruihe at magnum-opus.llc

Created attachment 3954
  --> https://bugzilla.mindrot.org/attachment.cgi?id=3954&action=edit
Docker reproducer for null-deref at servconf.c:2379 under allocator
failure (LD_PRELOAD harness + sshd -T driver).

In the Include GLOB_NOMATCH path in servconf.c, item->selector =
strdup(arg) is not checked before the cache item is inserted into the
includes TAILQ. If strdup(arg) returns NULL, the cache entry is still
stored with selector == NULL. A subsequent identical Include directive
causes the cache scan to reach strcmp(item->selector, arg), resulting
in a NULL-dereference crash.

This appears to be a correctness / failure-path bug rather than a
demonstrated security issue. I am filing it as a non-security upstream
bug.


Location:

servconf.c:2379 allocation site
subsequent crash during cache scan at strcmp(item->selector, arg)
----------

Observed behavior:

With deterministic NULL injection at the relevant allocation site, sshd
-T crashes with SIGSEGV when parsing a config containing two identical
Include directives for a non-matching glob. The first Include stores a
cache item with selector == NULL; the second Include scans the cache
and dereferences it in strcmp().
----------

Expected behavior:

If allocation fails, the config parser should fail cleanly and should
not insert a partially initialized cache entry into the includes queue.
----------

Minimal trigger:

Two identical Include directives with a non-matching glob, for example:

Port 22
Include /nonexistent_pattern_xyz/*.conf
Include /nonexistent_pattern_xyz/*.conf
----------

Mechanism:

glob() returns GLOB_NOMATCH
item->selector = strdup(arg) returns NULL
item is still inserted into the include-cache TAILQ
second identical Include scans the cache
strcmp(NULL, arg) is reached
sshd crashes with SIGSEGV
----------

Reproduction notes:

I reproduced this against a pinned upstream source export from a bare
repo using a deterministic clean-room pipeline. The provenance/export
step records exact source commit export from the bare repository, and
the harness supports deterministic NULL injection and per-finding
reproduction.
----------

Additional notes:

I am not claiming remote exploitability here. The report is about
unchecked allocation causing invalid cached state and a later NULL
dereference.

-- 
You are receiving this mail because:
You are watching the assignee of the bug.


More information about the openssh-bugs mailing list