Skip to content

Harden linux-modules-cleanup.service with a systemd drop-in - #10655

Open
surim0n wants to merge 2 commits into
omacom:quattrofrom
surim0n:fix/linux-modules-cleanup-sandbox
Open

Harden linux-modules-cleanup.service with a systemd drop-in#10655
surim0n wants to merge 2 commits into
omacom:quattrofrom
surim0n:fix/linux-modules-cleanup-sandbox

Conversation

@surim0n

@surim0n surim0n commented Sep 7, 2026

Copy link
Copy Markdown

Summary

Harden linux-modules-cleanup.service while retaining access to /usr/lib/modules for stale-tree archival and removal. Fixes #9297.

Changes

  • Restrict persistent writes to /usr/lib/modules, with filesystem/network/process protections.
  • Drop CAP_SYS_ADMIN and CAP_SYS_MODULE; retain other filesystem capabilities for ordinary rsync metadata preservation.
  • Omit ProtectKernelModules, which would hide the required tree.
  • Migration 1788839599.sh reloads cached manager configuration only when NeedDaemonReload reports stale configuration; never starts/restarts cleanup.
  • Add directive/migration checks and an isolated fixture using the actual Arch kernel-modules-hook 0.1.7-3 cleanup command.

Full-system validation

Validated head 439ef7f in a disposable x86_64 Arch VM under QEMU TCG, with real PID-1 systemd 261.2, kernel-modules-hook 0.1.7-3, pacman 7.1 and rsync 3.5.0. This supersedes the earlier container-only validation limitation.

  • Actual newly added drop-in changed NeedDaemonReload to yes; actual migration reloaded it to no and reran idempotently.
  • Actual installed service ran under the complete drop-in: running and pacman-owned trees preserved, stale synthetic tree archived/removed, result success and exit status 0.
  • Archive retained content, ordinary mode, UID/GID, nanosecond timestamps, ACLs, user xattrs, file capabilities, symlinks and hardlinks.
  • Effective capabilities exclude SYS_ADMIN/SYS_MODULE. An actual systemd probe under the identical profile confirmed EROFS outside the allowed tree and EPERM for remount/module loading.
  • No warning-or-higher cleanup journal entries in the successful ordinary-tree runs.
  • Real reboot from kernel 7.2.2 to 7.2.3 automatically archived the formerly running synthetic tree and preserved the newly running kernel.
  • Focused tests passed without skips in the VM. Bash syntax and git diff --check pass.

Scope and limitations

The committed namespace test approximates selected restrictions; the separate VM run above validates the complete profile. Set OMARCHY_REQUIRE_CLEANUP_NAMESPACE_TEST=1 to reject prerequisite skips.

RestrictSUIDSGID intentionally prevents preserving set-ID bits: an additional 06750 fixture caused rsync status 23 and left the source intact. No claim of arbitrary set-ID or trusted/IMA xattr preservation is made. No security score is used as proof of correctness.

Generated with Devin

The kernel-modules-hook cleanup oneshot only needs to remove stale
module trees under /usr/lib/modules. Add a drop-in that makes the
rest of the filesystem read-only and private, lowering the
systemd-analyze security score from 9.6 UNSAFE to a MEDIUM range.

Fixes omacom#9297.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@surim0n
surim0n marked this pull request as draft September 8, 2026 03:50
Retain filesystem metadata capabilities while dropping SYS_ADMIN and
SYS_MODULE. Reload stale manager configuration without starting cleanup.
Exercise the real Arch cleanup command in isolated namespace fixtures
and distinguish these checks from full systemd-profile verification.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@surim0n

surim0n commented Sep 8, 2026

Copy link
Copy Markdown
Author

Pushed 439ef7f and kept draft pending a full native Arch/systemd run. The profile now drops CAP_SYS_ADMIN/CAP_SYS_MODULE, retains ordinary filesystem metadata privileges, and has an idempotent reload migration. Tests execute the actual Arch cleanup command in an isolated namespace and check protected trees, archive metadata, failed transfers and remount denial. Those passed, but approximate selected restrictions; the updated body distinguishes them from complete-profile validation.

@surim0n

surim0n commented Sep 8, 2026

Copy link
Copy Markdown
Author

Full-system follow-up: 439ef7f now passed in a real x86_64 Arch VM with PID-1 systemd 261.2 and kernel-modules-hook 0.1.7-3. The actual service and reload migration worked; running/package-owned trees and ordinary ACL/xattr/file-capability/link metadata were preserved. A separate service under the same complete profile denied outside writes, remounts and module loading. Rebooting to the updated kernel also ran cleanup successfully. An extra set-ID fixture correctly failed archival before source removal; this restriction is explicitly documented. VM is shut down; marking ready for review.

@surim0n
surim0n marked this pull request as ready for review September 8, 2026 04:40
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.

linux-modules-cleanup.service runs with no systemd sandboxing (9.6 UNSAFE)

1 participant