Skip to content

Commit

Permalink
Merge pull request #4911 from travier/fix-cve-2024-2905
Browse files Browse the repository at this point in the history
CVE-2024-2905: passwd: create /etc/[g]shadow with mode 0 & unit: chmod /etc/[g]shadow[-] to 0000
  • Loading branch information
cgwalters committed Apr 9, 2024
2 parents ad42bce + 26a3922 commit 644fda9
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 0 deletions.
1 change: 1 addition & 0 deletions Makefile-daemon.am
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ systemdunit_service_file_names = \
rpm-ostreed-automatic.service \
rpm-ostree-bootstatus.service \
rpm-ostree-countme.service \
rpm-ostree-fix-shadow-mode.service \
$(NULL)

systemdunit_service_files = $(addprefix $(srcdir)/src/daemon/,$(systemdunit_service_file_names))
Expand Down
5 changes: 5 additions & 0 deletions packaging/rpm-ostree.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,11 @@ $PYTHON autofiles.py > files.devel \
# Setup rpm-ostree-countme.timer according to presets
%post
%systemd_post rpm-ostree-countme.timer
# Only enable on rpm-ostree based systems and manually force unit enablement to
# explicitly ignore presets for this security fix
if [ -e /run/ostree-booted ]; then
ln -snf /usr/lib/systemd/system/rpm-ostree-fix-shadow-mode.service /usr/lib/systemd/system/multi-user.target.wants/
fi

%preun
%systemd_preun rpm-ostree-countme.timer
Expand Down
14 changes: 14 additions & 0 deletions rust/src/passwd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,12 @@ fn write_data_from_treefile(
let db = rootfs.open(target_passwd_path).map(BufReader::new)?;
let shadow_name = target.shadow_file();
let target_shadow_path = format!("{}{}", dest_path, shadow_name);
// Ideally these permissions come from `setup`, which is the package
// that owns these files:
// https://src.fedoraproject.org/rpms/setup/blob/c6f58b338bd3/f/setup.spec#_96
// But at this point of the compose, the rootfs is completely empty; we
// haven't started unpacking things yet. So we need to hardcode it here.
let shadow_perms = cap_std::fs::Permissions::from_mode(0);

match target {
PasswdKind::User => {
Expand All @@ -427,6 +433,10 @@ fn write_data_from_treefile(
for user in entries {
writeln!(target_shadow, "{}:*::0:99999:7:::", user.name)?;
}
target_shadow
.get_mut()
.as_file_mut()
.set_permissions(shadow_perms)?;
Ok(())
})
.with_context(|| format!("Writing {target_shadow_path}"))?;
Expand All @@ -438,6 +448,10 @@ fn write_data_from_treefile(
for group in entries {
writeln!(target_shadow, "{}:::", group.name)?;
}
target_shadow
.get_mut()
.as_file_mut()
.set_permissions(shadow_perms)?;
Ok(())
})
.with_context(|| format!("Writing {target_shadow_path}"))?;
Expand Down
19 changes: 19 additions & 0 deletions src/daemon/rpm-ostree-fix-shadow-mode.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[Unit]
# rpm-ostree v2023.6 introduced a permission issue on `/etc/[g]shadow[-]`.
# 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=/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
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
5 changes: 5 additions & 0 deletions tests/compose/libbasic-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ validate_passwd group
ostree --repo=${repo} ls ${treeref} /usr/etc/passwd > passwd.txt
assert_file_has_content_literal passwd.txt '00644 '

ostree --repo=${repo} ls ${treeref} /usr/etc/shadow > shadow.txt
assert_file_has_content_literal shadow.txt '00000 '
ostree --repo=${repo} ls ${treeref} /usr/etc/gshadow > gshadow.txt
assert_file_has_content_literal gshadow.txt '00000 '

ostree --repo=${repo} cat ${treeref} /usr/etc/default/useradd > useradd.txt
assert_file_has_content_literal useradd.txt HOME=/var/home

Expand Down

0 comments on commit 644fda9

Please sign in to comment.