Skip to content

Commit 41546ab

Browse files
committed
lint: Add a sysusers lint
This is not exhaustive yet, but catches things that invoke `useradd` (whether a dpkg/rpm `%post` or just a plain `RUN useradd` in a container) that don't have a sysusers.d entry. Signed-off-by: Colin Walters <[email protected]>
1 parent 569d52a commit 41546ab

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ anyhow = { workspace = true }
1919
bootc-utils = { path = "../utils" }
2020
bootc-blockdev = { path = "../blockdev" }
2121
bootc-tmpfiles = { path = "../tmpfiles" }
22+
bootc-sysusers = { path = "../sysusers" }
2223
camino = { workspace = true, features = ["serde1"] }
2324
ostree-ext = { path = "../ostree-ext", features = ["bootc"] }
2425
chrono = { workspace = true, features = ["serde"] }

lib/src/lints.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,56 @@ fn check_var_tmpfiles(_root: &Dir) -> LintResult {
515515
lint_err(msg)
516516
}
517517

518+
#[distributed_slice(LINTS)]
519+
static LINT_SYSUSERS: Lint = Lint {
520+
name: "sysusers",
521+
ty: LintType::Warning,
522+
description: indoc! { r#"
523+
Check for users in /etc/passwd and groups in /etc/group that do not have corresponding
524+
systemd sysusers.d entries in /usr/lib/sysusers.d.
525+
This can cause a problem across upgrades because if /etc is not transient and is locally
526+
modified (commonly due to local user additions), then the contents of /etc/passwd in the new container
527+
image may not be visible.
528+
529+
Using systemd-sysusers to allocate users and groups will ensure that these are allocated
530+
on system startup alongside other users.
531+
532+
More on this topic in <https://containers.github.io/bootc/building/users-and-groups.html>
533+
"#},
534+
f: check_sysusers,
535+
root_type: None,
536+
};
537+
fn check_sysusers(rootfs: &Dir) -> LintResult {
538+
let r = bootc_sysusers::analyze(rootfs)?;
539+
if r.is_empty() {
540+
return lint_ok();
541+
}
542+
let mut msg = String::new();
543+
if let Some((samples, rest)) =
544+
bootc_utils::iterator_split_nonempty_rest_count(r.missing_users.iter(), 5)
545+
{
546+
msg.push_str("Found /etc/passwd entry without corresponding systemd sysusers.d:\n");
547+
for elt in samples {
548+
writeln!(msg, " {elt}")?;
549+
}
550+
if rest > 0 {
551+
writeln!(msg, " ...and {} more", rest)?;
552+
}
553+
}
554+
if let Some((samples, rest)) =
555+
bootc_utils::iterator_split_nonempty_rest_count(r.missing_groups.iter(), 5)
556+
{
557+
msg.push_str("Found /etc/group entry without corresponding systemd sysusers.d:\n");
558+
for elt in samples {
559+
writeln!(msg, " {elt}")?;
560+
}
561+
if rest > 0 {
562+
writeln!(msg, " ...and {} more", rest)?;
563+
}
564+
}
565+
lint_err(msg)
566+
}
567+
518568
#[distributed_slice(LINTS)]
519569
static LINT_NONEMPTY_BOOT: Lint = Lint::new_warning(
520570
"nonempty-boot",

0 commit comments

Comments
 (0)