wolfsshd: open PID file with O_NOFOLLOW and a fixed mode#1074
Conversation
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #1074
Scan targets checked: wolfssh-bugs, wolfssh-src
Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)
This review was generated automatically by Fenrir. Findings are non-blocking.
1c2bf7a to
db65d64
Compare
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #1074
Scan targets checked: wolfssh-bugs, wolfssh-src
No new issues found in the changed files. ✅
aidangarske
left a comment
There was a problem hiding this comment.
🐺 Skoll Code Review
Overall recommendation: REQUEST_CHANGES
Findings: 1 total — 1 posted, 0 skipped
Posted findings
- [High] Existing regular PID files keep unsafe ownership or permissions —
apps/wolfsshd/configuration.c:1828-1845
Review generated by Skoll.
aidangarske
left a comment
There was a problem hiding this comment.
🐺 Skoll Code Review
Overall recommendation: REQUEST_CHANGES
Findings: 1 total — 1 posted, 0 skipped
Posted findings
- [High] Existing regular PID files keep unsafe ownership or permissions —
apps/wolfsshd/configuration.c:1828-1845
Review generated by Skoll.
db65d64 to
bd18800
Compare
|
Hello @aidangarske , |
|
@ejohnstown can you look at this one please |
wolfsshd: harden PID-file write against symlink, hard-link, and FIFO attacks
Summary
wolfSSHD_ConfigSavePIDwrote thePidFilewithWFOPEN(..., "wb")— plainfopen()on POSIX: noO_NOFOLLOW, no explicit mode. The daemon setsumask(0)during daemonization and calls this as root, before privilegedrop. A local user with write access to the
PidFiledirectory could:fopenfollows it and truncatesan arbitrary root-owned file, writing the daemon PID into it; and
umask(0), have the PID file created mode 0666 (world-writable).Exploitability is conditional (the default config leaves
PidFileunset and/var/runis root-owned), so impact is limited to non-defaultPidFilelocations, container/embedded deployments with a non-root-writable PID
directory, or first-install windows.
Addressed by f_5853.
Fix —
apps/wolfsshd/configuration.cThe POSIX path now opens without
O_TRUNC, validates the descriptor, thentruncates and writes:
Defenses, each mapping to a concrete attack:
O_NOFOLLOW(+lstatfallback where unavailable)0644modeumask(0)fstat→S_ISREG && st_nlink == 1O_NOFOLLOWdoes not cover)O_NONBLOCKon opensshdstartup before theS_ISREGcheckO_TRUNC;ftruncateonly after validationWFWRITE/WFCLOSEreturn checked;unlinkon failureOther notes:
ftruncate) only after the descriptor is proven asingle-link regular file, so nothing is clobbered when a target is refused.
_XOPEN_SOURCE/_GNU_SOURCEare defined before the system headers (asauth.cdoes) sofdopen/ftruncate/lstat/S_ISLNKare declared understrict
-std=builds.WFOPENpath, with the sameWFWRITE/WFCLOSEchecks andWREMOVE-on-failure.Supporting change —
wolfssh/port.hThe
WOLFSSH_O_NOFOLLOWportability macro (and its<fcntl.h>include) wasgated behind
(WOLFSSH_SFTP || WOLFSSH_SCP), so it was undefined in an--enable-sshd-only build. It is moved into aWOLFSSH_HAVE_SYMLINKblock witha header-wide
0catch-all, so SFTP, SCP, and SSHD share one definition.Tests —
apps/wolfsshd/test/test_configuration.cNew
test_ConfigSavePID(POSIX) drives the real config loader +wolfSSHD_ConfigSavePID:PidFilewritten with the daemon PID, not group/world writableeven under
umask(0);The symlink-refusal assertion is gated on
WOLFSSH_HAVE_SYMLINKso the test isalso correct under a
WOLFSSH_NO_SYMLINK_CHECKbuild.Scope note
This intentionally does not alter the daemon-wide
umask. The PID file isprotected by its explicit
0644mode, so changing the process umask (whichwould also affect SFTP/SCP client-requested upload modes) was left out to keep
the change scoped to the finding. This matches OpenSSH, which relies on explicit
modes plus a root-owned
PidFiledirectory and does no symlink/hard-link checksitself; operators should still place
PidFilein a root-owned directory.Verification
--enable-all,--enable-scp,--enable-sftp,--enable-scp --disable-sftp,--enable-sftp --disable-scp,and
--enable-sshd(no SFTP/SCP).mode, and hard-link assertions all fail without the fix; a standalone
check confirms
O_NONBLOCKis what prevents the FIFO open from blocking.codespellclean.Files