[Bug 3948] New: servconf.c: unchecked strdup() in Include glob-match path can pass NULL filename to load_server_config()

bugzilla-daemon at mindrot.org bugzilla-daemon at mindrot.org
Tue Apr 14 12:03:25 AEST 2026


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

            Bug ID: 3948
           Summary: servconf.c: unchecked strdup() in Include glob-match
                    path can pass NULL filename to load_server_config()
           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 3955
  --> https://bugzilla.mindrot.org/attachment.cgi?id=3955&action=edit
Docker reproducer for null-deref at servconf.c:2389 under allocator
failure (LD_PRELOAD harness + sshd -T driver).

In the glob-match loop in servconf.c, item->filename =
strdup(gbuf.gl_pathv[n]) is not checked before item->filename is used
by load_server_config(item->filename, ...). If strdup() returns NULL,
the code continues and passes NULL as the filename. On macOS this
manifested as fopen(NULL, "r") returning EFAULT / “Bad address”; on
Linux-based clean-room reproduction this is expected to crash with
SIGSEGV.

This is an unchecked-allocation / invalid-argument propagation bug in
config parsing. I am filing it as a non-security correctness bug.
----------

Location:

servconf.c:2389-2390 allocation/use path
immediate downstream use in load_server_config(item->filename, ...)
----------

Observed behavior:

With deterministic NULL injection at the filename allocation site, sshd
-T fails immediately in the same parsing iteration. The summary
artifact captures this as a confirmed crash/failure surface in the
glob-match path.
----------

Expected behavior:

If strdup(gbuf.gl_pathv[n]) fails, the parser should abort that path
cleanly and should not call load_server_config() with a NULL filename.
----------

Minimal trigger:

A config with an Include that matches a real file, for example:

Port 22
Include /etc/ssh/sshd_config.d/*.conf

with a real file present under /etc/ssh/sshd_config.d/.
----------

Mechanism:

glob() matches one or more config files
item->filename = strdup(gbuf.gl_pathv[n]) returns NULL
code continues without checking item->filename
load_server_config(NULL, ...) is called
downstream fopen(NULL, "r") or equivalent invalid-path behavior occurs
immediate failure / crash in the same parse iteration
----------

Reproduction notes:

I used a deterministic reproduction harness with targeted injection and
a pinned upstream source export. The orchestration script builds and
runs per-finding clean-room reproductions and logs the result.
----------

Additional notes:

Of the three reports, this one is the simplest direct failure-path bug:
failed construction is immediately consumed as a valid argument.

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


More information about the openssh-bugs mailing list