Skip to content

wolfsshd: fix uninitialized fileNames[] deref in HandleInclude#1029

Open
yosuke-wolfssl wants to merge 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:fix/f_4233
Open

wolfsshd: fix uninitialized fileNames[] deref in HandleInclude#1029
yosuke-wolfssl wants to merge 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:fix/f_4233

Conversation

@yosuke-wolfssl

Copy link
Copy Markdown
Contributor

Description

Fixes a TOCTOU-induced uninitialized-pointer dereference in HandleInclude
(apps/wolfsshd/configuration.c) that can crash wolfsshd with a SIGSEGV.

HandleInclude walks an Include directory using two separate readdir
passes
split by WREWINDDIR:

  1. Pass 1 counts non-directory entries into fileCount.
  2. fileNames is allocated with WMALLOC(fileCount * sizeof(char*))without
    zero-initialization
    .
  3. Pass 2 fills the array but is bounded by
    i < fileCount && (dir = WREADDIR(...)) != NULL, so it stops early if
    readdir returns NULL.
  4. The processing loop then iterated the full fileCount, calling
    WSTRLEN(fileNames[i]) / WSNPRINTF(...) on every slot.

If the directory shrinks between the two passes (a local user removing files
from a writable Include directory, e.g. a group-writable
/etc/ssh/sshd_config.d/), the second pass fills fewer slots than fileCount.
The tail slots [fileFilled .. fileCount-1] remain uninitialized, and the
processing loop dereferences those garbage pointers, crashing the daemon at
start/restart. No SSH authentication is required to trigger it.

Fix

  • Bound the processing loop to the actual fill count. Capture the number of
    slots populated by the second pass (fileFilled = i;) and iterate
    for (i = 0; i < fileFilled; i++) instead of i < fileCount. This is the
    fix that closes the uninitialized read.
  • Zero-initialize the array after allocation (WMEMSET(fileNames, 0, ...))
    as defense-in-depth, so any slot not reached by the second pass is NULL
    rather than garbage and the code fails safe against future changes.

The opposite direction (more files appearing in pass 2) was already safe — the
i < fileCount guard stops the second pass at the allocated size.

Testing

  • ./configure --enable-sshd && make — clean build.
  • apps/wolfsshd/test/test_configuration — all Include / wildcard cases pass,
    including Include sshd_config.d/*.conf, which exercises this exact two-pass
    path and confirms no regression in the normal (fileFilled == fileCount)
    case.

@yosuke-wolfssl yosuke-wolfssl self-assigned this Jun 15, 2026
Copilot AI review requested due to automatic review settings June 15, 2026 06:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens wolfsshd’s Include-directory wildcard handling to prevent an uninitialized-pointer dereference when the directory contents change between the “count” and “fill” readdir() passes in HandleInclude().

Changes:

  • Track the number of entries actually populated during the second readdir() pass (fileFilled) and bound the processing loop to that value.
  • Zero-initialize the fileNames pointer array after allocation as defense-in-depth.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/wolfsshd/configuration.c Outdated

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #1029

Scan targets checked: none
Failed targets: wolfssh-bugs, wolfssh-src

⚠️ Review incomplete — one or more scan targets failed before findings could be produced. See the Fenrir PR review detail page for logs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants