π ~4 min read β’ Source: OpenBSD 7.5 errata 009_readdir
Errata topic: Security: readdir (All architectures)
Issued: September 17, 2024
Upstream summary: In readdir name validation exclude any '/' to avoid unexpected directory traversal on untrusted file systems.
Table of contents
Symptom & Impact
On OpenBSD 7.5 hosts the OpenBSD 7.5 errata 009_readdir entry covers readdir. Until doas syspatch applies the signed binary patch (or the operator builds and installs the upstream source diff), the running kernel and userland on the affected architectures keep the unfixed code paths in place. Defence-in-depth from pledge(2) and unveil(2) (maintained by upstream, not user-tuned) reduces blast radius but does not retire the underlying defect. Edge boxes, firewall hosts under pf(4), and mail relays running smtpd(8) are the typical impact surface.
Environment & Reproduction
Reproduction targets OpenBSD 7.5. Confirm release, kernel build, and currently applied patches:
uname -a
sysctl kern.version
cat /etc/motd
doas syspatch -l # patches already applied to base
doas syspatch -c # patches still pending for this release
pkg_info readdir 2>/dev/null || true # only meaningful for ports-side names
Trigger the workflow that exposes readdir β errata 009_readdir β reliability fix β syspatch and remediation while collecting log evidence from syslogd(8):
tail -200 /var/log/messages
tail -200 /var/log/daemon
tail -200 /var/log/authlog
dmesg | tail -200
Root Cause Analysis
Root cause is tracked at OpenBSD 7.5 errata 009_readdir. The OpenBSD release engineers shipped a signed patch (009_readdir) against the 7.5 base tree; hosts that have not yet run doas syspatch for this release remain exposed. Correlate the timeline of the failure with the patch issue date and with kernel / daemon state:
doas syspatch -l # already applied
doas syspatch -c # pending
sysctl kern.version
sysctl kern.osrelease kern.osrevision
tail -500 /var/log/messages
tail -500 /var/log/daemon
Quick Triage
Run these checks on OpenBSD 7.5 to confirm the failure mode and current state of readdir / errata 009_readdir:
doas syspatch -c # is THIS errata still pending?
doas syspatch -l # has it already been applied?
pkg_info -Q readdir # search ports/packages catalogue
pkg_info readdir 2>/dev/null # info on installed port (if any)
tail -100 /var/log/messages
tail -100 /var/log/daemon
dmesg | tail -100
doas pfctl -sr # current pf rules, if exposure is network-side
doas pfctl -ss # active state table
# If readdir maps to an rc(8) service, the script name may differ from the errata tag
# (e.g. 'unbound', 'smtpd', 'httpd'); list and probe with rcctl:
doas rcctl ls started
doas rcctl get readdir 2>/dev/null || true
Step-by-Step Diagnosis
-
List started and enabled services with
rcctl(8)β the OpenBSD service manager.doas rcctl ls started doas rcctl ls on -
Follow live system, daemon and auth logs.
tail -F /var/log/messages tail -F /var/log/daemon tail -F /var/log/authlog -
Validate pf(4) rules and state if exposure is network-facing.
doas pfctl -sr doas pfctl -ss doas pfctl -si -
Inspect kernel and process state.
dmesg | tail -200 vmstat 1 5 systat -b vmstat 1 fstat | head pstat -f | head -
Snapshot live packets on the affected interface (replace em0 as needed).
doas tcpdump -ni em0 -c 200 -
Confirm the errata is still pending and correlate with the upstream entry.
doas syspatch -c -
Cross-reference findings against OpenBSD 7.5 errata 009_readdir to pin the commit that introduced readdir β errata 009_readdir β reliability fix β syspatch and remediation.
Solution – Primary Fix
Apply the signed base-system binary patch with syspatch(8). Patches are signify(1)-verified against /etc/signify/openbsd-75-base.pub before they install:
doas syspatch -c # list pending patches for this release
doas syspatch # apply all pending base patches
doas syspatch -l # confirm the new patch is in the applied list
# Some patches require restarting a daemon rather than rebooting;
# use rcctl(8) β the OpenBSD service manager:
doas rcctl restart readdir 2>/dev/null || true
# Patches that touch the kernel or libc require a reboot:
doas shutdown -r now
If the affected component is a port/package rather than base (check with pkg_info readdir), upgrade via pkg_add(1) β note OpenBSD uses pkg_add/pkg_delete, not pkg:
doas pkg_add -u readdir # upgrade this single package
doas pkg_add -u # upgrade every installed package
pkg_info readdir # confirm the new version
Manually verify the signed patch tarball if you do not trust the in-tree mirror selection:
cd /tmp && ftp https://ftp.openbsd.org/pub/OpenBSD/7.5/SHA256.sig
signify -Cp /etc/signify/openbsd-75-base.pub -x SHA256.sig
Need help rolling syspatch across a fleet of OpenBSD edge / firewall / mail-relay boxes? Our IT Solutions & Services team supports OpenBSD edge / firewall / mail relay deployments with signify-verified syspatch automation. Get in touch for a free consultation.
Solution – Alternative Approaches
If syspatch is not viable (unsupported architecture β syspatch only ships binary patches for amd64, i386 and arm64; or fully custom kernels) choose from these alternatives:
-
Fetch and apply the upstream source diff, then rebuild the affected subsystem against the release branch (the canonical OpenBSD route on sparc64/powerpc64/riscv64):
cd /tmp && ftp https://ftp.openbsd.org/pub/OpenBSD/patches/7.5/common/009_readdir.patch.sig signify -Vep /etc/signify/openbsd-75-base.pub -m 009_readdir.patch.sig -x 009_readdir.patch.sig cd /usr/src && doas patch -p0 < /tmp/009_readdir.patch # Then rebuild the affected component per the patch header instructions # (typical kernel rebuild): cd /sys/arch/$(uname -m)/compile/GENERIC.MP && doas make obj && doas make config && doas make && doas make install doas shutdown -r now -
Move to a snapshot (
-current) build withsysupgradewhen the release branch lags behind a fast-moving fix:doas sysupgrade -s # jump to the current snapshot # or to the next release point: doas sysupgrade -
Constrain the exposure window with stricter
pf(4)rules untilsyspatchcan run. Edit/etc/pf.confand reload:# /etc/pf.conf β minimal hardening snippet block return pass out quick inet proto { tcp udp icmp } pass in quick on egress proto tcp from <trusted> to (egress) port { ssh } # then reload: doas pfctl -nf /etc/pf.conf # dry-run / syntax check doas pfctl -f /etc/pf.conf -
Disable the affected service with
rcctluntil the patch is rolled (note: some operators installsudoas a port, but OpenBSD shipsdoas(1)as the default and uses/etc/doas.conf):doas rcctl stop readdir 2>/dev/null || true doas rcctl disable readdir 2>/dev/null || true -
If the affected component is a port, pin to a known-good build by reinstalling from a saved tarball with
pkg_add -D installed.
Verification & Acceptance Criteria
All of these should pass after the fix:
doas syspatch -c # MUST list no pending patches for this errata
doas syspatch -l # MUST include this errata id
# If readdir is a port/package, confirm the version moved forward:
pkg_info readdir 2>/dev/null
tail -50 /var/log/messages # no new errors after the reboot/restart
tail -50 /var/log/daemon
doas rcctl check readdir 2>/dev/null || true
The original reproduction for readdir β errata 009_readdir β reliability fix β syspatch and remediation must not trigger across two consecutive runs.
Rollback Plan
OpenBSD syspatch keeps the pre-patch binaries; rolling back a single base patch is a one-liner. Capture the pre-state first:
doas syspatch -l > /root/syspatch-pre.txt
pkg_info -m > /root/pkg-pre.txt
To revert this specific erratum if the new build misbehaves:
doas syspatch -r # revert the most recent patch
# If multiple patches landed in the same run and you need an earlier one:
doas syspatch -r # repeat until syspatch -l matches /root/syspatch-pre.txt
doas shutdown -r now # reboot if the rollback touched the kernel
For port-side reverts, reinstall the saved binary package:
doas pkg_add -D installed -F update /var/cache/pkg/readdir-<previous-version>.tgz
There is no LVM/BE concept on OpenBSD; for full-host rollback take a dump(8) of the affected filesystems before any change and restore from restore(8) if needed.
Prevention & Hardening
Prevent recurrence on OpenBSD 7.5 hosts running readdir:
-
Schedule
syspatchfromcron(8)so signed patches land within hours of publication:# /var/cron/tabs/root β append: ~ * * * * -ns /usr/sbin/syspatch && /usr/sbin/syspatch -c | grep -q . && logger -t syspatch 'patches pending' -
Subscribe to
[email protected]and to the per-release errata RSS / page at openbsd.org/errata75.html. -
Pair
syspatchwithsysupgradefor major version jumps; never let a host drift more than one release behind:doas sysupgrade # next release doas sysupgrade -s # current snapshot (-current) -
Verify every downloaded SHA256 manifest with
signify(1)before trusting it (this is whatsyspatchdoes internally β replicate it for manual installs):signify -Cp /etc/signify/openbsd-75-base.pub -x SHA256.sig -
Tighten
pf(4)with a default-deny ruleset, anchors per service, and rate-limiting on edge interfaces. Reload safely with the dry-run flag:doas pfctl -nf /etc/pf.conf # syntax check only doas pfctl -f /etc/pf.conf # commit doas pfctl -sr | head # show loaded rules -
Enable W^X enforcement and rely on upstream-shipped
pledge(2)/unveil(2)annotations as defence-in-depth. These are not user-tuned β they are baked into each base binary by the OpenBSD developers and reduce the blast radius if a future bug like readdir β errata 009_readdir β reliability fix β syspatch and remediation reappears. -
If you run readdir as an internet-facing service, consider running it under OpenBSD’s built-in daemons β
httpd(8),relayd(8)andsmtpd(8)ship in base and are kept current by the same release-engineering cycle that produces these errata. -
Manage
doas(1)rules carefully in/etc/doas.conf(nosudoby default β some shops add thesudoport butdoasis the supported tool):permit nopass keepenv root permit persist :wheel
Related Errors & Cross-Refs
Issues that commonly surface alongside readdir β errata 009_readdir β reliability fix β syspatch and remediation: stale signify public keys after a release jump, syspatch hanging on a half-applied update, pf rule drift across reboots, and ksh(1) completion mismatches after libc patches. Triage with:
uname -a
doas syspatch -l
doas syspatch -c
doas pfctl -sr
ls -la /etc/signify/
View all openbsd-7-5 tutorials on the Tutorials Hub →
Browse all common problems & solutions on the Tutorials Hub.
References & Further Reading
Primary reference: OpenBSD 7.5 errata 009_readdir. Useful manual pages on OpenBSD 7.5:
man syspatch
man sysupgrade
man signify
man pkg_add
man pkg_info
man rcctl
man pf
man pf.conf
man doas
man doas.conf
Other resources: the OpenBSD FAQ at openbsd.org/faq, the per-release errata index at openbsd.org/errata75.html, and the signed release manifest at ftp.openbsd.org/pub/OpenBSD/7.5/SHA256.sig for readdir β errata 009_readdir β reliability fix β syspatch and remediation.