• v5.5.3-19 18f5f2af84

    v5.5.3-19 Stable

    amnesia released this 2026-07-05 01:23:04 +02:00 | 12 commits to main since this release

    protocol7-core 5.5.3-19 (2026-07-04)

    Current state (as of 5.5.3-19)

    • lainos-notifyd: v4.7, fuzzed clean and verified end-to-end. Runlevel placement
      (sysinit-only) confirmed durable across a clean rebuild/reinstall/reboot cycle. No
      known issues.
    • seatd: confirmed default-only, matching documented architecture.
    • lainos-ghost-units: audited, no code changes needed. Boot-ordering fix shipped
      and confirmed working across reboot.
    • lainos-audio-init / lainos-init: patched and compile-checked. NOT yet verified
      end-to-end on a real login cycle ~ pending test.
    • lainos-net-init: removed from the package. Still outstanding: doc corrections in
      project-status.md, iteration-log.md, and new-master-reference.md still describe it
      as active/present.
    • net.ipv4.tcp_timestamps: recommended change to 0 for consistency with existing
      anti-fingerprinting posture ~ NOT yet applied to
      /etc/sysctl.d/99-lainos-hardening.conf.
    • lainos-dbus-bridge: unchanged this session ~ already fuzz tested clean in a
      prior session (dfuzzer 2.6 + ASan against the full org.freedesktop.login1
      interface, see 5.5.3-12 entry).

    Fixes

    protocol7-core.install ~ fixed incomplete lainos-notifyd runlevel correction from -18

    Root cause: The -18 fix added lainos-notifyd to sysinit correctly, but rc-update add
    is purely additive ~ it never removed the stale default entry left over from earlier
    manual/script-added state. The duplicate persisted through -18 despite the fix looking
    correct in isolation.
    Fix: Added an explicit rc-update del "$svc" default before the rc-update add "$svc" sysinit call in the lainos-notifyd case branch, so the script self-corrects regardless
    of prior state on every future upgrade, not just this one.

    Verification

    • Clean reboot after rebuild/reinstall: rc-update show confirms lainos-notifyd is
      sysinit-only, seatd is default-only
    • Both services started correctly with no manual rc-update intervention required
    • /dev/log confirmed present and receiving log lines with no manual fix needed
    • lainos-notifyd confirmed running v4.7 (strings check against installed binary)

    protocol7-core 5.5.3-18 (2026-07-04)

    protocol7-core.install ~ lainos-notifyd runlevel misassignment

    Root cause: post_install()'s runlevel-registration loop unconditionally routed
    lainos-notifyd through the generic case fallthrough, which adds every non-boot
    service to default. This directly contradicts notifyd's own depend() (before seatd)
    once seatd is correctly single-homed in default ~ placing notifyd in default too gives
    no ordering guarantee against seatd within the same runlevel.
    Fix: Added an explicit lainos-notifyd case routing it to sysinit instead of the
    generic fallthrough. (Incomplete as shipped ~ see -19: didn't clean up the pre-existing
    stale default entry, so the duplicate persisted until -19.)

    seatd ~ reverted incorrect manual runlevel change

    Earlier in the session, seatd had been removed from default and left boot-only, based
    on reading its depend() block alone without checking the project's documented runlevel
    architecture (session handoff doc), which places seatd in default. Restored to
    default-only.


    protocol7-core 5.5.3-17 (2026-07-04)

    lainos-ghost-units.initd ~ shipped in a real pkgrel

    Rebuild to ship the after syslog-ng depend() fix written into -16's source tree but
    not yet built/deployed as its own pkgrel. No other changes.
    Root cause (originally found and fixed in source at -16): ghost-units creating
    /run/systemd/system before syslog-ng starts causes syslog-ng's sd_booted() check to
    falsely detect a systemd host and skip binding /dev/log entirely ~ breaking all system
    logging, not just notifyd's.


    protocol7-core 5.5.3-16 (2026-07-04)

    lainos-net-init ~ removed

    Dropped from source=, build(), and package() in the PKGBUILD. Confirmed dead code:
    never invoked by any init script, udev rule, or session hook across every prior
    version in the repo history. Sysctl hardening it attempted is fully covered, and more
    completely, by /etc/sysctl.d/99-lainos-hardening.conf via OpenRC's native sysctl
    service.

    lainos-audio-init ~ stale-socket race in PipeWire readiness check

    Root cause: wait_for_socket() only checked that a filesystem node existed at the
    expected socket path, not that it was live. A socket file left behind by a crashed
    prior instance would report "ready" instantly, before the newly-spawned pipewire had
    bound anything, causing wireplumber to launch against a dead socket.
    Fix: unlink any stale socket file before spawning pipewire, so existence
    afterward genuinely means the new instance created it. Bumped to v4.5.

    lainos-init ~ wired up lainos-audio-init for the first time

    Root cause: lainos-audio-init has been built and shipped since v4.4 but nothing
    on the system ever invoked it. lainos-init only sets environment and execs the
    compositor; no fork ever happened before that exec. Sessions were running on bare
    ALSA with no PipeWire/WirePlumber/Pulse-compat layer at all.
    Fix: Added a double-fork launcher (launch_audio_init()) called before both
    compositor execlp() calls (X11 and Wayland branches), so the launcher doesn't zombie
    under whatever process ends up in lainos-init's PID after exec. Bumped to v4.7.


    protocol7-core 5.5.3-15 (2026-07-04)

    Package integrity

    Bumped provides= to systemd=1:999 (epoch 1) for permanent systemd>=X dependency
    satisfaction regardless of upstream version.

    lainos-ghost-units.initd ~ added to package

    Confirmed tracked in source= / package() as of this rebuild.


    protocol7-core 5.5.3-14 (2026-07-04)

    Root cause: After drop_privileges(), the process runs as nobody, but /run/systemd
    is root-owned 0755 ~ unlink() there always failed on permissions. The v4.6 seccomp fix
    (below) only stopped the process being killed by SIGSYS; it didn't fix the underlying
    EACCES, which was silently ignored since the return value was never checked.
    Fix: Removed the shutdown-time unlink() entirely. Startup-time unlink() (root,
    before bind()) already handles stale-socket cleanup on next start, making the
    shutdown-time call both broken and redundant. Removed unlink/unlinkat from seccomp
    accordingly, tightening the filter back down.


    protocol7-core 5.5.3-13 (2026-07-04)

    lainos-notifyd v4.6 ~ signal handling, seccomp, and message-handling hardening

    Root cause 1 (shutdown hang): SA_RESTART on the SIGTERM/SIGINT handlers meant
    recv() was transparently restarted by the kernel after a signal, so shutdown_flag was
    never checked until another datagram arrived. The daemon could hang indefinitely on
    stop if no more messages came in.
    Fix: Removed SA_RESTART from the signal handlers.
    Root cause 2 (seccomp kill on shutdown): The shutdown path called unlink() on the
    socket after the seccomp filter (default SCMP_ACT_KILL) was loaded, killing the
    process with SIGSYS instead of a clean exit.
    Fix: Added unlink/unlinkat to the seccomp whitelist. (Superseded at -14 once the
    actual permissions root cause was found ~ see above.)

    Added

    • Switched recv() to recvmsg() with SO_PASSCRED ~ every logged message now carries
      the sender's real uid/pid (SCM_CREDENTIALS) instead of trusting unauthenticated
      message content
    • MSG_TRUNC detection ~ oversized datagrams are logged as truncated and dropped
      instead of silently clipped
    • Control-character sanitization on logged message bodies, closing a syslog
      log-line injection path via embedded newlines

    Verification

    • parse_and_log()/sanitize_for_log() (the message-parsing path handling untrusted
      external bytes) fuzzed with a libFuzzer harness (clang-18, ASan+UBSan), seeded with
      every message-type prefix, boundary lengths, empty input, and a log-injection
      attempt
    • 2,000,000 executions, coverage plateaued (fully explored), zero crashes, zero leaks
    • This code path is unchanged in v4.7 (-14), so the result still applies ~ the -14
      fixes were control-flow bugs (signal handling, permissions), not parsing bugs,
      which is why fuzzing wouldn't have caught them and doesn't need re-running
    • test-notifyd.sh: all checks passing on live hardware (clean shutdown timing,
      socket lifecycle, credential attribution, truncation handling, log-injection
      sanitization)

    Downloads