Skip to content

Commit

Permalink
rpm-ostree-fix-shadow-mode: Also fix previous deployments
Browse files Browse the repository at this point in the history
The fix in coreos#4911 for CVE-2024-2905 only fixes the permissions for the
current deployment and not for previous deployments for existing
installations.

The affected files can still be read from the previous deployment by
looking at them in `/sysroot/ostree/deploy/...`.

Extend the unit to fix all deployments on the system and update the
logic to only update files that exists.

See: coreos#4911
See: GHSA-2m76-cwhg-7wv6
See: ostreedev/ostree#3211
  • Loading branch information
travier committed Apr 12, 2024
1 parent 644fda9 commit bdd5a8e
Showing 1 changed file with 8 additions and 4 deletions.
12 changes: 8 additions & 4 deletions src/daemon/rpm-ostree-fix-shadow-mode.service
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@
# This makes sure to fix permissions on systems that were deployed with the wrong permissions.
Description=Update permissions for /etc/shadow
Documentation=https://github.com/coreos/rpm-ostree-ghsa-2m76-cwhg-7wv6
ConditionPathExists=!/etc/.rpm-ostree-shadow-mode-fixed.stamp
ConditionPathExists=!/etc/.rpm-ostree-shadow-mode-fixed2.stamp
ConditionPathExists=/run/ostree-booted
# Make sure this is started before any unprivileged (interactive) user has access to the system.
Before=systemd-user-sessions.service

[Service]
Type=oneshot
ExecStart=chmod --verbose 0000 /etc/shadow /etc/gshadow
ExecStart=-chmod --verbose 0000 /etc/shadow- /etc/gshadow-
ExecStart=touch /etc/.rpm-ostree-shadow-mode-fixed.stamp
ExecStart=bash -c "find /etc -regex '/etc/g?shadow-?' -exec chmod 0000 {} \;"

This comment has been minimized.

Copy link
@cgwalters

cgwalters Apr 12, 2024

I think this is the point where we should move the logic into Rust.
ExecStart=rpm-ostree internals fix-shadow

This comment has been minimized.

Copy link
@cgwalters

cgwalters Apr 12, 2024

I can do this if you prefer.

This comment has been minimized.

Copy link
@travier

travier Apr 12, 2024

Author Owner

Sounds good to me :) I agree that those commands are not great.

This comment has been minimized.

Copy link
@travier

travier Apr 12, 2024

Author Owner

I started working on this.

This comment has been minimized.

Copy link
@cgwalters

cgwalters Apr 12, 2024

Ah so did I...here's my WIP so far

diff --git a/rust/src/nameservice/shadow.rs b/rust/src/nameservice/shadow.rs
index 9f2b00d1..9f727c6e 100644
--- a/rust/src/nameservice/shadow.rs
+++ b/rust/src/nameservice/shadow.rs
@@ -3,6 +3,7 @@
 // SPDX-License-Identifier: Apache-2.0 OR MIT
 
 use anyhow::{anyhow, Context, Result};
+use cap_std::fs::Dir;
 use std::io::{BufRead, Write};
 
 /// Entry from shadow file.
diff --git a/rust/src/passwd.rs b/rust/src/passwd.rs
index d897da67..81f17d9f 100644
--- a/rust/src/passwd.rs
+++ b/rust/src/passwd.rs
@@ -21,6 +21,7 @@ use gio::prelude::*;
 use nix::unistd::{Gid, Uid};
 use once_cell::sync::Lazy;
 use ostree_ext::{gio, ostree};
+use rustix::fd::BorrowedFd;
 use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
 use std::io::{BufRead, BufReader, BufWriter, Write};
 use std::os::unix::io::AsRawFd;
@@ -363,6 +364,28 @@ impl PasswdKind {
     }
 }
 
+/// Due to a prior bug, the build system had some deployments with a world-readable
+/// shadow file.  This fixes a given deployment.
+#[context("Fixing shadow permissions")]
+pub(crate) fn fix_shadow_perms_in_root(root: &Dir) -> Result<()> {
+    let perms = Permissions::from_mode(0);
+    for path in ["etc/shadow", "etc/shadow-", "etc/gshadow", "etc/gshadow-"] {
+        if let Some(f) = root.open_optional(path)? {
+            f.set_permissions(perms.clone())?;
+        }
+    }
+    Ok(())
+}
+
+pub(crate) fn fix_shadow_perms_in_sysrot(sysroot: &ostree::Sysroot) -> Result<()> {
+    let deployments = sysroot.deployments();
+    let sysroot_fd = Dir::reopen_dir(unsafe { &std::os::fd::BorrowedFd::borrow_raw(sysroot.fd()) })?;
+    for deployment in deployments {
+        let path = sysroot.deployment_dirpath(&deployment);
+        let dir = sysroot_fd.open_dir(&path)?;
+    }
+}
+
 // This function writes the static passwd/group data from the treefile to the
 // target root filesystem.
 fn write_data_from_treefile(

Let's decide who takes this 😄

This comment has been minimized.

Copy link
@travier

travier Apr 12, 2024

Author Owner

You're further along that I am so I can let you do it (and I'm about to log off)

ExecStart=mount -o remount,rw /sysroot
ExecStart=bash -c "find /sysroot/ostree/deploy/*/deploy/*/etc/ -regex '.*/g?shadow-?' -exec chmod 0000 {} \;"
ExecStart=touch /etc/.rpm-ostree-shadow-mode-fixed2.stamp
RemainAfterExit=yes

# The MountFlags=slave is so we remount /sysroot temporarily writable
MountFlags=slave

[Install]
WantedBy=multi-user.target

0 comments on commit bdd5a8e

Please sign in to comment.