import CS rpm-ostree-2024.7-3.el9_5

This commit is contained in:
eabdullin 2024-11-12 13:06:16 +00:00
parent ebe83f9794
commit 7e3b91c77a
11 changed files with 397 additions and 671 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/rpm-ostree-2024.3.tar.xz
SOURCES/rpm-ostree-2024.7.tar.xz

View File

@ -1 +1 @@
dc6e0ea9f33f162b5ca2d1ea1cb79ec7f9f7d71c SOURCES/rpm-ostree-2024.3.tar.xz
d9cceab814a10d116e41911a00ca5d5134715da1 SOURCES/rpm-ostree-2024.7.tar.xz

View File

@ -1,56 +0,0 @@
From d02993e30078db2a04820065ccbf22bd56d0d064 Mon Sep 17 00:00:00 2001
From: Jonathan Lebon <jonathan@jlebon.com>
Date: Thu, 22 Feb 2024 14:44:50 -0500
Subject: [PATCH] cliwrap/rpm: mark `--eval`/`-E` as safe
This is sometimes used in scripts to query aspects of the host system.
E.g. this is used by Fedora's pkg-config:
https://src.fedoraproject.org/rpms/pkgconf/blob/95c0bbee/f/pkg-config.in#_6
This in turn gets hit by kdump which runs dracut which has modules that
runs `pkgconf` to query some directory paths.
---
rust/src/cliwrap/rpm.rs | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/rust/src/cliwrap/rpm.rs b/rust/src/cliwrap/rpm.rs
index c6ed5901..3332f76c 100644
--- a/rust/src/cliwrap/rpm.rs
+++ b/rust/src/cliwrap/rpm.rs
@@ -19,6 +19,12 @@ fn new_rpm_app() -> Command {
.long("version")
.action(clap::ArgAction::Version),
)
+ .arg(
+ Arg::new("eval")
+ .long("eval")
+ .short('E')
+ .action(clap::ArgAction::Set),
+ )
.arg(
Arg::new("package")
.help("package")
@@ -130,6 +136,19 @@ mod tests {
Ok(())
}
+ #[test]
+ fn test_eval() -> Result<()> {
+ assert_eq!(
+ disposition(SystemHostType::OstreeHost, &["-E", "%{_target_cpu}"])?,
+ RunDisposition::Ok
+ );
+ assert_eq!(
+ disposition(SystemHostType::OstreeHost, &["--eval=%{_target_cpu}}"])?,
+ RunDisposition::Ok
+ );
+ Ok(())
+ }
+
#[test]
fn test_query_file() -> Result<()> {
assert_eq!(
--
2.43.2

View File

@ -0,0 +1,33 @@
From 96ddae1acba59cf5249dcfff1157e44b5ed69650 Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Thu, 15 Aug 2024 11:41:43 -0400
Subject: [PATCH 1/1] core: Fix Coverity WRAPPER_ESCAPE
This should fix:
```
32. rpm-ostree-2024.7/src/libpriv/rpmostree-core.cxx:1786:15: use_after_free: Using internal representation of destroyed object temporary of type "std::string".
```
Signed-off-by: Colin Walters <walters@verbum.org>
---
src/libpriv/rpmostree-core.cxx | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/libpriv/rpmostree-core.cxx b/src/libpriv/rpmostree-core.cxx
index a2de7262..615e2636 100644
--- a/src/libpriv/rpmostree-core.cxx
+++ b/src/libpriv/rpmostree-core.cxx
@@ -1782,7 +1782,8 @@ rpmostree_context_prepare (RpmOstreeContext *self, gboolean enable_filelists,
auto pkg = "";
for (auto &pkg_str : packages)
{
- pkg = std::string (pkg_str).c_str ();
+ auto pkg_buf = std::string (pkg_str);
+ pkg = pkg_buf.c_str ();
char *query = strchr ((char *)pkg, '/');
if (query)
{
--
2.46.0

View File

@ -1,83 +0,0 @@
From ef2638c1ffd77bc6fd9a80a92c965b06a8f284df Mon Sep 17 00:00:00 2001
From: Jonathan Lebon <jonathan@jlebon.com>
Date: Tue, 19 Mar 2024 15:20:43 -0400
Subject: [PATCH 1/3] passwd: create `/etc/[g]shadow` with mode 0
Because of how our composes work, we need to manually inject
passwd-related things before installing packages. A somewhat recent
regression in that area made it so that the `/etc/shadow` and
`/etc/gshadow` files were created with default permissions (0644), which
meant they were world readable.
Fix this by explicitly setting their modes to 0. Ideally, we would rely
on the canonical permissions set in the `setup` package here, but it's
tricky to fix that without reworking how we install `setup` and handle
`passwd` treefile options.
Fixes fdb879c8 ("passwd: sync `etc/{,g}shadow` according to
`etc/{passwd,group}`").
Fixes #4401
---
rust/src/passwd.rs | 14 ++++++++++++++
tests/compose/libbasic-test.sh | 5 +++++
2 files changed, 19 insertions(+)
diff --git a/rust/src/passwd.rs b/rust/src/passwd.rs
index 821497d8..a64f6468 100644
--- a/rust/src/passwd.rs
+++ b/rust/src/passwd.rs
@@ -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 => {
@@ -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}"))?;
@@ -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}"))?;
diff --git a/tests/compose/libbasic-test.sh b/tests/compose/libbasic-test.sh
index 78ad72b1..df790e89 100644
--- a/tests/compose/libbasic-test.sh
+++ b/tests/compose/libbasic-test.sh
@@ -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
--
2.44.0

View File

@ -0,0 +1,332 @@
From aeb048ce390fcd82e568ba25c0047099b8892979 Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Tue, 1 Oct 2024 17:56:38 -0400
Subject: [PATCH 1/1] treefile: Add ignore-devices
We hit another case where people are pulling a container image
with devices in `/dev` in the tar stream; they're then trying
to commit this to an ostree.
There's much better ways to fix this:
- Change the image to stop including devices as there's no reason
to do so
- Switch to logically bound images instead of physically bound
- Use the composefs backend for c/storage
Eventually I may look at "quoting" generally in ostree, but
it's fairly invasive: https://github.com/ostreedev/ostree/issues/2568
In practice today, simply ignoring the files will happen to work
for "podman run" of such images; podman will just use overlayfs
to stitch together the `diff` directories, and doesn't try to do
any validation of their contents today.
(Queue the composefs integration, which *would* do that but would
also fix this anwyays)
Signed-off-by: Colin Walters <walters@verbum.org>
---
docs/treefile.md | 4 ++
rpmostree-cxxrs.cxx | 11 ++--
rpmostree-cxxrs.h | 5 +-
rust/src/composepost.rs | 74 +++++++++++++++++++--------
rust/src/lib.rs | 2 +-
rust/src/treefile.rs | 7 +++
src/libpriv/rpmostree-postprocess.cxx | 2 +-
tests/compose/test-installroot.sh | 8 +++
8 files changed, 84 insertions(+), 29 deletions(-)
diff --git a/docs/treefile.md b/docs/treefile.md
index 9839589e..49e193d1 100644
--- a/docs/treefile.md
+++ b/docs/treefile.md
@@ -36,6 +36,10 @@ It supports the following parameters:
* `selinux`: boolean, optional: Defaults to `true`. If `false`, then
no SELinux labeling will be performed on the server side.
+ * `ignore-devices`: boolean, optional: Defaults to `true`. If `true`, then
+ all character and block device files found in the target root (except overlayfs
+ whiteouts, which are automatically "quoted") will be ignored.
+
* `ima`: boolean, optional: Defaults to `false`. Propagate any
IMA signatures in input RPMs into the final OSTree commit.
diff --git a/rpmostree-cxxrs.cxx b/rpmostree-cxxrs.cxx
index 649d1b7b..2a4cb12c 100644
--- a/rpmostree-cxxrs.cxx
+++ b/rpmostree-cxxrs.cxx
@@ -192,6 +192,8 @@ public:
Slice () noexcept;
Slice (T *, std::size_t count) noexcept;
+ template <typename C> explicit Slice (C &c) : Slice (c.data (), c.size ()) {}
+
Slice &operator= (const Slice<T> &) &noexcept = default;
Slice &operator= (Slice<T> &&) &noexcept = default;
@@ -2206,8 +2208,8 @@ extern "C"
::std::int32_t rootfs_dfd, ::rpmostreecxx::Treefile &treefile, ::rust::Str next_version,
bool unified_core) noexcept;
- ::rust::repr::PtrLen
- rpmostreecxx$cxxbridge1$compose_postprocess_final_pre (::std::int32_t rootfs_dfd) noexcept;
+ ::rust::repr::PtrLen rpmostreecxx$cxxbridge1$compose_postprocess_final_pre (
+ ::std::int32_t rootfs_dfd, ::rpmostreecxx::Treefile const &treefile) noexcept;
::rust::repr::PtrLen rpmostreecxx$cxxbridge1$compose_postprocess_final (
::std::int32_t rootfs_dfd, ::rpmostreecxx::Treefile const &treefile) noexcept;
@@ -4011,9 +4013,10 @@ compose_postprocess (::std::int32_t rootfs_dfd, ::rpmostreecxx::Treefile &treefi
}
void
-compose_postprocess_final_pre (::std::int32_t rootfs_dfd)
+compose_postprocess_final_pre (::std::int32_t rootfs_dfd, ::rpmostreecxx::Treefile const &treefile)
{
- ::rust::repr::PtrLen error$ = rpmostreecxx$cxxbridge1$compose_postprocess_final_pre (rootfs_dfd);
+ ::rust::repr::PtrLen error$
+ = rpmostreecxx$cxxbridge1$compose_postprocess_final_pre (rootfs_dfd, treefile);
if (error$.ptr)
{
throw ::rust::impl< ::rust::Error>::error (error$);
diff --git a/rpmostree-cxxrs.h b/rpmostree-cxxrs.h
index d38fd1db..9d62380e 100644
--- a/rpmostree-cxxrs.h
+++ b/rpmostree-cxxrs.h
@@ -191,6 +191,8 @@ public:
Slice () noexcept;
Slice (T *, std::size_t count) noexcept;
+ template <typename C> explicit Slice (C &c) : Slice (c.data (), c.size ()) {}
+
Slice &operator= (const Slice<T> &) &noexcept = default;
Slice &operator= (Slice<T> &&) &noexcept = default;
@@ -1867,7 +1869,8 @@ void composepost_nsswitch_altfiles (::std::int32_t rootfs_dfd);
void compose_postprocess (::std::int32_t rootfs_dfd, ::rpmostreecxx::Treefile &treefile,
::rust::Str next_version, bool unified_core);
-void compose_postprocess_final_pre (::std::int32_t rootfs_dfd);
+void compose_postprocess_final_pre (::std::int32_t rootfs_dfd,
+ ::rpmostreecxx::Treefile const &treefile);
void compose_postprocess_final (::std::int32_t rootfs_dfd,
::rpmostreecxx::Treefile const &treefile);
diff --git a/rust/src/composepost.rs b/rust/src/composepost.rs
index 1a5ae869..8049d502 100644
--- a/rust/src/composepost.rs
+++ b/rust/src/composepost.rs
@@ -295,40 +295,69 @@ fn is_overlay_whiteout(meta: &cap_std::fs::Metadata) -> bool {
(meta.mode() & libc::S_IFMT) == libc::S_IFCHR && meta.rdev() == 0
}
-/// Auto-synthesize embedded overlayfs whiteouts; for more information
-/// see https://github.com/ostreedev/ostree/pull/2722/commits/0085494e350c72599fc5c0e00422885d80b3c660
-#[context("Postprocessing embedded overlayfs")]
-fn postprocess_embedded_ovl_whiteouts(root: &Dir) -> Result<()> {
+/// Automatically "quote" embeded overlayfs whiteouts as regular files, and
+/// if configured error out on devices or ignore them.
+/// For more on overlayfs, see https://github.com/ostreedev/ostree/pull/2722/commits/0085494e350c72599fc5c0e00422885d80b3c660
+#[context("Postprocessing devices")]
+fn postprocess_devices(root: &Dir, treefile: &Treefile) -> Result<()> {
const OSTREE_WHITEOUT_PREFIX: &str = ".ostree-wh.";
- fn recurse(root: &Dir, path: &Utf8Path) -> Result<u32> {
- let mut n = 0;
+ let mut n_overlay = 0u64;
+ let mut n_devices = 0u64;
+ fn recurse(
+ root: &Dir,
+ path: &Utf8Path,
+ ignore_devices: bool,
+ n_overlay: &mut u64,
+ n_devices: &mut u64,
+ ) -> Result<()> {
for entry in root.read_dir(path)? {
let entry = entry?;
let meta = entry.metadata()?;
let name = PathBuf::from(entry.file_name());
let name: Utf8PathBuf = name.try_into()?;
if meta.is_dir() {
- n += recurse(root, &path.join(name))?;
+ recurse(root, &path.join(name), ignore_devices, n_overlay, n_devices)?;
continue;
}
- if !is_overlay_whiteout(&meta) {
+ let is_device = matches!(meta.mode() & libc::S_IFMT, libc::S_IFCHR | libc::S_IFBLK);
+ if !is_device {
continue;
- };
+ }
let srcpath = path.join(&name);
- let targetname = format!("{OSTREE_WHITEOUT_PREFIX}{name}");
- let destpath = path.join(&targetname);
- root.remove_file(srcpath)?;
- root.atomic_write_with_perms(destpath, "", meta.permissions())?;
- n += 1;
+ if is_overlay_whiteout(&meta) {
+ let targetname = format!("{OSTREE_WHITEOUT_PREFIX}{name}");
+ let destpath = path.join(&targetname);
+ root.remove_file(srcpath)?;
+ root.atomic_write_with_perms(destpath, "", meta.permissions())?;
+ *n_overlay += 1;
+ continue;
+ }
+ if ignore_devices {
+ root.remove_file(srcpath)?;
+ *n_devices += 1;
+ } else {
+ anyhow::bail!("Unsupported device file: {srcpath}")
+ }
}
- Ok(n)
+ Ok(())
}
- let n = recurse(root, ".".into())?;
- if n > 0 {
- println!("Processed {n} embedded whiteouts");
+ recurse(
+ root,
+ ".".into(),
+ treefile.get_ignore_devices(),
+ &mut n_overlay,
+ &mut n_devices,
+ )?;
+ if n_overlay > 0 {
+ println!("Processed {n_overlay} embedded whiteouts");
} else {
println!("No embedded whiteouts found");
}
+ if n_devices > 0 {
+ println!("Ignored {n_devices} device files");
+ } else {
+ println!("No device files found");
+ }
Ok(())
}
@@ -420,7 +449,7 @@ pub(crate) fn postprocess_cleanup_rpmdb(rootfs_dfd: i32) -> CxxResult<()> {
/// it as the bits of that function that we've chosen to implement in Rust.
/// It takes care of all things that are really required to use rpm-ostree
/// on the target host.
-pub fn compose_postprocess_final_pre(rootfs_dfd: i32) -> CxxResult<()> {
+pub fn compose_postprocess_final_pre(rootfs_dfd: i32, treefile: &Treefile) -> CxxResult<()> {
let rootfs_dfd = unsafe { &crate::ffiutil::ffi_dirfd(rootfs_dfd)? };
// These tasks can safely run in parallel, so just for fun we do so via rayon.
let tasks = [
@@ -430,7 +459,7 @@ pub fn compose_postprocess_final_pre(rootfs_dfd: i32) -> CxxResult<()> {
];
tasks.par_iter().try_for_each(|f| f(rootfs_dfd))?;
// This task recursively traverses the filesystem and hence should be serial.
- postprocess_embedded_ovl_whiteouts(rootfs_dfd)?;
+ postprocess_devices(rootfs_dfd, treefile)?;
Ok(())
}
@@ -1533,11 +1562,12 @@ OSTREE_VERSION='33.4'
// We don't actually test creating whiteout devices here as that
// may not work.
let td = cap_tempfile::tempdir(cap_std::ambient_authority())?;
+ let tf = crate::treefile::tests::new_test_tf_basic("")?;
// Verify no-op case
- postprocess_embedded_ovl_whiteouts(&td).unwrap();
+ postprocess_devices(&td, &tf).unwrap();
td.create("foo")?;
td.symlink("foo", "bar")?;
- postprocess_embedded_ovl_whiteouts(&td).unwrap();
+ postprocess_devices(&td, &tf).unwrap();
assert!(td.try_exists("foo")?);
assert!(td.try_exists("bar")?);
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 56d8b57f..5356dc8c 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -299,7 +299,7 @@ pub mod ffi {
next_version: &str,
unified_core: bool,
) -> Result<()>;
- fn compose_postprocess_final_pre(rootfs_dfd: i32) -> Result<()>;
+ fn compose_postprocess_final_pre(rootfs_dfd: i32, treefile: &Treefile) -> Result<()>;
fn compose_postprocess_final(rootfs_dfd: i32, treefile: &Treefile) -> Result<()>;
fn convert_var_to_tmpfiles_d(rootfs_dfd: i32, cancellable: &GCancellable) -> Result<()>;
fn rootfs_prepare_links(
diff --git a/rust/src/treefile.rs b/rust/src/treefile.rs
index da6c0ca7..51dfff6d 100644
--- a/rust/src/treefile.rs
+++ b/rust/src/treefile.rs
@@ -394,6 +394,7 @@ fn treefile_merge(dest: &mut TreeComposeConfig, src: &mut TreeComposeConfig) {
rojig,
selinux,
selinux_label_version,
+ ignore_devices,
ima,
gpg_key,
include,
@@ -1245,6 +1246,10 @@ impl Treefile {
self.parsed.base.selinux.unwrap_or(true)
}
+ pub(crate) fn get_ignore_devices(&self) -> bool {
+ self.parsed.base.ignore_devices.unwrap_or(true)
+ }
+
pub(crate) fn get_selinux_label_version(&self) -> u32 {
self.parsed.base.selinux_label_version.unwrap_or_default()
}
@@ -2414,6 +2419,8 @@ pub(crate) struct BaseComposeConfigFields {
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) selinux: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
+ pub(crate) ignore_devices: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
pub(crate) selinux_label_version: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) ima: Option<bool>,
diff --git a/src/libpriv/rpmostree-postprocess.cxx b/src/libpriv/rpmostree-postprocess.cxx
index 311de70f..c086bcdd 100644
--- a/src/libpriv/rpmostree-postprocess.cxx
+++ b/src/libpriv/rpmostree-postprocess.cxx
@@ -381,7 +381,7 @@ postprocess_final (int rootfs_dfd, rpmostreecxx::Treefile &treefile, gboolean un
auto selinux = treefile.get_selinux ();
- ROSCXX_TRY (compose_postprocess_final_pre (rootfs_dfd), error);
+ ROSCXX_TRY (compose_postprocess_final_pre (rootfs_dfd, treefile), error);
if (selinux)
{
diff --git a/tests/compose/test-installroot.sh b/tests/compose/test-installroot.sh
index 3e40f679..90a11ee3 100755
--- a/tests/compose/test-installroot.sh
+++ b/tests/compose/test-installroot.sh
@@ -7,6 +7,8 @@ dn=$(cd "$(dirname "$0")" && pwd)
# This is used to test postprocessing with treefile vs not
treefile_set "boot-location" '"new"'
+# On by default now:
+# treefile_set "ignore-devices" 'True'
# This test is a bit of a degenerative case of the supermin abstration. We need
# to be able to interact with the compose output directly, feed it back to
@@ -56,6 +58,7 @@ testdate=$(date)
runasroot sh -xec "
# https://github.com/ostreedev/ostree/pull/2717/commits/e234b630f85b97e48ecf45d5aaba9b1aa64e6b54
mknod -m 000 ${instroot}-directcommit/usr/share/foowhiteout c 0 0
+mknod -m 000 ${instroot}-directcommit/usr/share/devzero c 1 5
echo \"${testdate}\" > ${instroot}-directcommit/usr/share/rpm-ostree-composetest-split.txt
! test -f ${instroot}-directcommit/${integrationconf}
rpm-ostree compose commit --repo=${repo} ${treefile} ${instroot}-directcommit
@@ -69,6 +72,11 @@ ostree --repo=${repo} ls ${treeref} /usr/share
ostree --repo=${repo} ls ${treeref} /usr/share/.ostree-wh.foowhiteout >out.txt
grep -Ee '^-00000' out.txt
+# And the devzero should have been ignored
+if ostree --repo=${repo} ls ${treeref} /usr/share/devzero; then
+ echo \"found devzero\" 1>&2; exit 1
+fi
+
ostree --repo=${repo} cat ${treeref} /usr/share/rpm-ostree-composetest-split.txt >out.txt
grep \"${testdate}\" out.txt
ostree --repo=${repo} cat ${treeref} /${integrationconf}
--
2.47.0

View File

@ -1,79 +0,0 @@
From 715298d909551b7d6b42ee6f9c38675f22034dde Mon Sep 17 00:00:00 2001
From: jbtrystram <jbtrystram@redhat.com>
Date: Thu, 21 Mar 2024 17:27:21 +0100
Subject: [PATCH 2/3] unit: chmod /etc/[g]shadow[-] to 0000
fdb879c introduced a regression where /etc/[g]shadow[-] files where
created with default permissions: 0644
This unit chmods /etc/shadow, /etc/gshadow and backup copies to 0000
before interactive login is allowed on a system.
This will fix the systems that were deployed with the above issue.
We keep the stamp in /etc to account for the case where a deployment
with this unit is rolled back. If we used /var, the stamp would have
stayed but the fix would not be re-applied on the next update.
---
Makefile-daemon.am | 1 +
packaging/rpm-ostree.spec.in | 5 +++++
src/daemon/rpm-ostree-fix-shadow-mode.service | 19 +++++++++++++++++++
3 files changed, 25 insertions(+)
create mode 100644 src/daemon/rpm-ostree-fix-shadow-mode.service
diff --git a/Makefile-daemon.am b/Makefile-daemon.am
index 4233d90d..f96f49a9 100644
--- a/Makefile-daemon.am
+++ b/Makefile-daemon.am
@@ -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))
diff --git a/packaging/rpm-ostree.spec.in b/packaging/rpm-ostree.spec.in
index e83db7f3..cbe3e031 100644
--- a/packaging/rpm-ostree.spec.in
+++ b/packaging/rpm-ostree.spec.in
@@ -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
diff --git a/src/daemon/rpm-ostree-fix-shadow-mode.service b/src/daemon/rpm-ostree-fix-shadow-mode.service
new file mode 100644
index 00000000..4aea7462
--- /dev/null
+++ b/src/daemon/rpm-ostree-fix-shadow-mode.service
@@ -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
--
2.44.0

View File

@ -1,314 +0,0 @@
From 1ec5618144e2d5e76caedba9cdcddb2d7ca1d8f7 Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Fri, 12 Apr 2024 12:59:54 -0400
Subject: [PATCH 3/3] shadow: Adjust all deployments
It was pointed out that in the previous change here we missed
the fact that the previous deployments were accessible.
- Move the logic into Rust, adding unit tests
- Change the code to iterate over all deployments
- Add an integration test too
Note: A likely future enhancement here will be to finally
deny unprivileged access to non-default roots; cc
https://github.com/ostreedev/ostree/issues/3211
---
rust/src/lib.rs | 2 +-
rust/src/main.rs | 1 +
rust/src/passwd.rs | 124 ++++++++++++++++++
src/daemon/rpm-ostree-fix-shadow-mode.service | 12 +-
tests/kolainst/destructive/shadow | 80 +++++++++++
5 files changed, 214 insertions(+), 5 deletions(-)
create mode 100755 tests/kolainst/destructive/shadow
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index e244158b..a65e669b 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -979,7 +979,7 @@ mod normalization;
mod origin;
mod ostree_prepareroot;
pub(crate) use self::origin::*;
-mod passwd;
+pub mod passwd;
use passwd::*;
mod console_progress;
pub(crate) use self::console_progress::*;
diff --git a/rust/src/main.rs b/rust/src/main.rs
index 5a3c04d0..bf10d45d 100644
--- a/rust/src/main.rs
+++ b/rust/src/main.rs
@@ -28,6 +28,7 @@ async fn inner_async_main(args: Vec<String>) -> Result<i32> {
match *arg {
// Add custom Rust commands here, and also in `libmain.cxx` if user-visible.
"countme" => rpmostree_rust::countme::entrypoint(args).map(|_| 0),
+ "fix-shadow-perms" => rpmostree_rust::passwd::fix_shadow_perms_entrypoint(args).map(|_| 0),
"cliwrap" => rpmostree_rust::cliwrap::entrypoint(args).map(|_| 0),
// A hidden wrapper to intercept some binaries in RPM scriptlets.
"scriptlet-intercept" => builtins::scriptlet_intercept::entrypoint(args).map(|_| 0),
diff --git a/rust/src/passwd.rs b/rust/src/passwd.rs
index a64f6468..f0a6da31 100644
--- a/rust/src/passwd.rs
+++ b/rust/src/passwd.rs
@@ -30,6 +30,10 @@ const DEFAULT_MODE: u32 = 0o644;
static DEFAULT_PERMS: Lazy<Permissions> = Lazy::new(|| Permissions::from_mode(DEFAULT_MODE));
static PWGRP_SHADOW_FILES: &[&str] = &["shadow", "gshadow", "subuid", "subgid"];
static USRLIB_PWGRP_FILES: &[&str] = &["passwd", "group"];
+// This stamp file signals the original fix which only changed the booted deployment
+const SHADOW_MODE_FIXED_STAMP_OLD: &str = "etc/.rpm-ostree-shadow-mode-fixed.stamp";
+// And this one is written by the newer logic that changes all deployments
+const SHADOW_MODE_FIXED_STAMP: &str = "etc/.rpm-ostree-shadow-mode-fixed2.stamp";
// Lock/backup files that should not be in the base commit (TODO fix).
static PWGRP_LOCK_AND_BACKUP_FILES: &[&str] = &[
@@ -363,6 +367,86 @@ 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<bool> {
+ let zero_perms = Permissions::from_mode(0);
+ let mut changed = false;
+ for path in ["etc/shadow", "etc/shadow-", "etc/gshadow", "etc/gshadow-"] {
+ let metadata = if let Some(meta) = root
+ .symlink_metadata_optional(path)
+ .context("Querying metadata")?
+ {
+ meta
+ } else {
+ tracing::debug!("No path {path}");
+ continue;
+ };
+ let mode = metadata.mode() & !libc::S_IFMT;
+ // Don't touch the file if it's already correct
+ if mode == 0 {
+ continue;
+ }
+ let f = root.open(path).with_context(|| format!("Opening {path}"))?;
+ f.set_permissions(zero_perms.clone())
+ .with_context(|| format!("chmod: {path}"))?;
+ println!("Adjusted mode for {path}");
+ changed = true;
+ }
+ // Write our stamp file
+ root.write(SHADOW_MODE_FIXED_STAMP, "")
+ .context(SHADOW_MODE_FIXED_STAMP)?;
+ // And clean up the old one
+ root.remove_file_optional(SHADOW_MODE_FIXED_STAMP_OLD)
+ .with_context(|| format!("Removing old {SHADOW_MODE_FIXED_STAMP_OLD}"))?;
+ Ok(changed)
+}
+
+/// Due to a prior bug, the build system had some deployments with a world-readable
+/// shadow file. This fixes all deployments.
+pub(crate) fn fix_shadow_perms_in_sysroot(sysroot: &ostree::Sysroot) -> Result<bool> {
+ let deployments = sysroot.deployments();
+ // TODO add a nicer api for this to ostree-rs
+ let sysroot_fd =
+ Dir::reopen_dir(unsafe { &std::os::fd::BorrowedFd::borrow_raw(sysroot.fd()) })?;
+ let mut changed = false;
+ for deployment in deployments {
+ let path = sysroot.deployment_dirpath(&deployment);
+ let dir = sysroot_fd.open_dir(&path)?;
+ if fix_shadow_perms_in_root(&dir)
+ .with_context(|| format!("Deployment index={}", deployment.index()))?
+ {
+ println!(
+ "Adjusted shadow files in deployment index={} {}.{}",
+ deployment.index(),
+ deployment.csum(),
+ deployment.bootserial()
+ );
+ changed = true;
+ }
+ }
+ Ok(changed)
+}
+
+/// The main entrypoint for updating /etc/{,g}shadow permissions across
+/// all deployments.
+pub fn fix_shadow_perms_entrypoint(_args: &[&str]) -> Result<()> {
+ let cancellable = gio::Cancellable::NONE;
+ let sysroot = ostree::Sysroot::new_default();
+ sysroot.set_mount_namespace_in_use();
+ sysroot.lock()?;
+ sysroot.load(cancellable)?;
+ let changed = fix_shadow_perms_in_sysroot(&sysroot)?;
+ if changed {
+ // We already printed per deployment, so this one is just
+ // a debug-level log.
+ tracing::debug!("Updated shadow/gshadow permissions");
+ }
+ sysroot.unlock();
+ Ok(())
+}
+
// This function writes the static passwd/group data from the treefile to the
// target root filesystem.
fn write_data_from_treefile(
@@ -1070,3 +1154,43 @@ impl PasswdEntries {
Ok(())
}
}
+
+#[test]
+fn test_shadow_perms() -> Result<()> {
+ let root = &cap_tempfile::tempdir(cap_std::ambient_authority())?;
+ root.create_dir("etc")?;
+ root.write("etc/shadow", "some shadow")?;
+ root.write("etc/gshadow", "some gshadow")?;
+ root.set_permissions("etc/gshadow", Permissions::from_mode(0))?;
+
+ assert!(fix_shadow_perms_in_root(root)?);
+ assert!(!root.try_exists(SHADOW_MODE_FIXED_STAMP_OLD)?);
+ assert!(root.try_exists(SHADOW_MODE_FIXED_STAMP)?);
+ // Verify idempotence
+ assert!(!fix_shadow_perms_in_root(root)?);
+ assert!(!root.try_exists(SHADOW_MODE_FIXED_STAMP_OLD)?);
+ assert!(root.try_exists(SHADOW_MODE_FIXED_STAMP)?);
+
+ Ok(())
+}
+
+#[test]
+/// Verify the scenario of updating from a previously fixed root
+fn test_shadow_perms_from_orig_fix() -> Result<()> {
+ let root = &cap_tempfile::tempdir(cap_std::ambient_authority())?;
+ root.create_dir("etc")?;
+ root.write("etc/shadow", "some shadow")?;
+ root.set_permissions("etc/shadow", Permissions::from_mode(0))?;
+ root.write("etc/gshadow", "some gshadow")?;
+ root.set_permissions("etc/gshadow", Permissions::from_mode(0))?;
+ // Write the original stamp file
+ root.write(SHADOW_MODE_FIXED_STAMP_OLD, "")?;
+
+ // No changes
+ assert!(!fix_shadow_perms_in_root(root)?);
+ // Except we should have updated to the new stamp file
+ assert!(!root.try_exists(SHADOW_MODE_FIXED_STAMP_OLD)?);
+ assert!(root.try_exists(SHADOW_MODE_FIXED_STAMP)?);
+
+ Ok(())
+}
diff --git a/src/daemon/rpm-ostree-fix-shadow-mode.service b/src/daemon/rpm-ostree-fix-shadow-mode.service
index 4aea7462..121bc74e 100644
--- a/src/daemon/rpm-ostree-fix-shadow-mode.service
+++ b/src/daemon/rpm-ostree-fix-shadow-mode.service
@@ -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
+# This new stamp file is written by the Rust code, and obsoletes
+# the old /etc/.rpm-ostree-shadow-mode-fixed.stamp
+ConditionPathExists=!/etc/.rpm-ostree-shadow-mode-fixed2.stamp
ConditionPathExists=/run/ostree-booted
+# Because we read the sysroot
+RequiresMountsFor=/boot
# 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=rpm-ostree fix-shadow-perms
RemainAfterExit=yes
+# So we can remount /sysroot writable in our own namespace
+MountFlags=slave
[Install]
WantedBy=multi-user.target
diff --git a/tests/kolainst/destructive/shadow b/tests/kolainst/destructive/shadow
new file mode 100755
index 00000000..7caf84c0
--- /dev/null
+++ b/tests/kolainst/destructive/shadow
@@ -0,0 +1,80 @@
+#!/bin/bash
+#
+# Copyright (C) 2024 Red Hat Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+set -euo pipefail
+
+. ${KOLA_EXT_DATA}/libtest.sh
+
+set -x
+
+cd $(mktemp -d)
+
+service=rpm-ostree-fix-shadow-mode.service
+stamp=/etc/.rpm-ostree-shadow-mode-fixed2.stamp
+
+case "${AUTOPKGTEST_REBOOT_MARK:-}" in
+"")
+
+libtest_prepare_fully_offline
+libtest_enable_repover 0
+
+systemctl status ${service} || true
+rm -vf /etc/.rpm-ostree-shadow-mode*
+chmod 0644 /etc/gshadow
+
+# Verify running the service once fixes things
+systemctl restart $service
+assert_has_file "${stamp}"
+assert_streq "$(stat -c '%f' /etc/gshadow)" 8000
+
+# Now *undo* the fix, so that the current (then old) deployment
+# is broken still, and ensure after reboot that it's fixed
+# in both.
+
+chmod 0644 /etc/gshadow
+rm -vf /etc/.rpm-ostree*
+
+booted_commit=$(rpm-ostree status --json | jq -r '.deployments[0].checksum')
+ostree refs ${booted_commit} --create vmcheck2
+rpm-ostree rebase :vmcheck2
+
+/tmp/autopkgtest-reboot "1"
+;;
+"1")
+
+systemctl status $service
+assert_has_file "${stamp}"
+
+verified=0
+for f in $(ls /ostree/deploy/*/deploy/*/etc/{,g}shadow{,-}); do
+ verified=$(($verified + 1))
+ assert_streq "$(stat -c '%f' $f)" 8000
+ echo "ok ${f}"
+done
+assert_streq "$verified" 8
+
+journalctl -b -u $service --grep="Adjusted shadow files in deployment" | tee out.txt
+assert_streq "$(wc -l < out.txt)" 2
+
+echo "ok shadow"
+
+;;
+*) echo "unexpected mark: ${AUTOPKGTEST_REBOOT_MARK}"; exit 1;;
+
+esac
--
2.44.0

View File

@ -1,91 +0,0 @@
From 6714c34bae041c036277ddb509af2b4135b759d5 Mon Sep 17 00:00:00 2001
From: Jonathan Lebon <jonathan@jlebon.com>
Date: Tue, 7 May 2024 10:05:03 -0400
Subject: [PATCH 1/1] core: also wrap `kernel-install` for scriptlets
It's confusing right now how specifically for the kernel, one has to use
this obscure `rpm-ostree cliwrap install-to-root /` command to make it
work. Let's just always enable it: in the client-side layering case, we
don't run kernel scriptlets anyway so the wrapper is unused, and in the
container case, this will allow users to not have to enable cliwrap and
have it leak into their derived image.
I guess in theory, this should also allow us to *stop* ignoring kernel
scriptlets and rely on this instead, though let's leave that for a
separate investigation.
Closes: #4949
---
rust/src/core.rs | 18 +++++++++++++++++-
src/libpriv/kernel-install-wrapper.sh | 9 +++++++++
2 files changed, 26 insertions(+), 1 deletion(-)
create mode 100644 src/libpriv/kernel-install-wrapper.sh
diff --git a/rust/src/core.rs b/rust/src/core.rs
index 8cd1ee03..ec24ed99 100644
--- a/rust/src/core.rs
+++ b/rust/src/core.rs
@@ -44,6 +44,8 @@ const USERADD_PATH: &str = "usr/sbin/useradd";
const USERADD_WRAPPER: &[u8] = include_bytes!("../../src/libpriv/useradd-wrapper.sh");
const USERMOD_PATH: &str = "usr/sbin/usermod";
const USERMOD_WRAPPER: &[u8] = include_bytes!("../../src/libpriv/usermod-wrapper.sh");
+const KERNEL_INSTALL_PATH: &str = "usr/bin/kernel-install";
+const KERNEL_INSTALL_WRAPPER: &[u8] = include_bytes!("../../src/libpriv/kernel-install-wrapper.sh");
const RPMOSTREE_CORE_STAGED_RPMS_DIR: &str = "rpm-ostree/staged-rpms";
@@ -143,6 +145,7 @@ impl FilesystemScriptPrep {
(SYSTEMCTL_PATH, SYSTEMCTL_WRAPPER),
(USERADD_PATH, USERADD_WRAPPER),
(USERMOD_PATH, USERMOD_WRAPPER),
+ (KERNEL_INSTALL_PATH, KERNEL_INSTALL_WRAPPER),
];
fn saved_name(name: &str) -> String {
@@ -436,7 +439,7 @@ mod test {
// Replaced usermod.
{
let original_usermod = "original usermod";
- d.atomic_write_with_perms(super::USERMOD_PATH, original_usermod, mode)?;
+ d.atomic_write_with_perms(super::USERMOD_PATH, original_usermod, mode.clone())?;
let contents = d.read_to_string(super::USERMOD_PATH)?;
assert_eq!(contents, original_usermod);
let mut g = super::prepare_filesystem_script_prep(d.as_raw_fd())?;
@@ -446,6 +449,19 @@ mod test {
let contents = d.read_to_string(super::USERMOD_PATH)?;
assert_eq!(contents, original_usermod);
}
+ // Replaced kernel-install.
+ {
+ let original_kernel_install = "original kernel_install";
+ d.atomic_write_with_perms(super::KERNEL_INSTALL_PATH, original_kernel_install, mode)?;
+ let contents = d.read_to_string(super::KERNEL_INSTALL_PATH)?;
+ assert_eq!(contents, original_kernel_install);
+ let mut g = super::prepare_filesystem_script_prep(d.as_raw_fd())?;
+ let contents = d.read_to_string(super::KERNEL_INSTALL_PATH)?;
+ assert_eq!(contents.as_bytes(), super::KERNEL_INSTALL_WRAPPER);
+ g.undo()?;
+ let contents = d.read_to_string(super::KERNEL_INSTALL_PATH)?;
+ assert_eq!(contents, original_kernel_install);
+ }
Ok(())
}
diff --git a/src/libpriv/kernel-install-wrapper.sh b/src/libpriv/kernel-install-wrapper.sh
new file mode 100644
index 00000000..4cfb605b
--- /dev/null
+++ b/src/libpriv/kernel-install-wrapper.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/bash
+# Used in the container layering path to make kernel replacements Just Work
+# without having to enable cliwrap first. If cliwrap is enabled, then this will
+# technically override the cliwrap wrapper, but the script is exactly the same.
+# This wrapper is technically also installed when doing client-side layering,
+# but we already ignore kernel scriptlets there anyway.
+# See also https://github.com/coreos/rpm-ostree/issues/4949
+
+exec /usr/bin/rpm-ostree cliwrap kernel-install "$@"
--
2.45.0

View File

@ -1,27 +0,0 @@
From 82cfc5491b3c670dd3d0abc0b30758622c958299 Mon Sep 17 00:00:00 2001
From: Joseph Marrero Corchado <jmarrero@redhat.com>
Date: Thu, 2 May 2024 08:57:45 -0400
Subject: [PATCH] rpm-ostree-fix-shadow-mode.service: don't run if OS is not
installed
Co-authored-by: Jonathan Lebon <jonathan@jlebon.com>
---
src/daemon/rpm-ostree-fix-shadow-mode.service | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/daemon/rpm-ostree-fix-shadow-mode.service b/src/daemon/rpm-ostree-fix-shadow-mode.service
index 121bc74e..f2983032 100644
--- a/src/daemon/rpm-ostree-fix-shadow-mode.service
+++ b/src/daemon/rpm-ostree-fix-shadow-mode.service
@@ -7,6 +7,8 @@ Documentation=https://github.com/coreos/rpm-ostree-ghsa-2m76-cwhg-7wv6
# the old /etc/.rpm-ostree-shadow-mode-fixed.stamp
ConditionPathExists=!/etc/.rpm-ostree-shadow-mode-fixed2.stamp
ConditionPathExists=/run/ostree-booted
+# Filter out non-traditional ostree setups (e.g. live boots)
+ConditionKernelCommandLine=ostree
# Because we read the sysroot
RequiresMountsFor=/boot
# Make sure this is started before any unprivileged (interactive) user has access to the system.
--
2.45.2

View File

@ -3,20 +3,16 @@
Summary: Hybrid image/package system
Name: rpm-ostree
Version: 2024.3
Release: 5%{?dist}
Version: 2024.7
Release: 3%{?dist}
License: LGPLv2+
URL: https://github.com/coreos/rpm-ostree
# This tarball is generated via "cd packaging && make -f Makefile.dist-packaging dist-snapshot"
# in the upstream git. It also contains vendored Rust sources.
Source0: https://github.com/coreos/rpm-ostree/releases/download/v%{version}/rpm-ostree-%{version}.tar.xz
Patch0: 0001-cliwrap-rpm-mark-eval-E-as-safe.patch
Patch1: 0001-passwd-create-etc-g-shadow-with-mode-0.patch
Patch2: 0002-unit-chmod-etc-g-shadow-to-0000.patch
Patch3: 0003-shadow-Adjust-all-deployments.patch
Patch4: 0004-core-also-wrap-kernel-install-for-scriptlets.patch
Patch5: 0005-rpm-ostree-fix-shadow-mode.service-don-t-run-if-OS-i.patch
Patch0: 0001-core-Fix-Coverity-WRAPPER_ESCAPE.patch
Patch1: 0001-treefile-Add-ignore-devices.patch
ExclusiveArch: %{rust_arches}
@ -251,21 +247,36 @@ fi
%files devel -f files.devel
%changelog
* Tue Aug 20 2024 Huijing Hei <hhei@fedoraproject.org> - 2024.3-5
- Backport https://github.com/coreos/rpm-ostree/pull/4944
Resolves: #RHEL-55249
* Thu Oct 17 2024 Joseph Marrero <jmarrero@fedoraproject.org> - 2024.7-3
- Backport https://github.com/coreos/rpm-ostree/pull/5051
Resolves: #RHEL-59716
* Fri May 10 2024 Joseph Marrero <jmarrero@fedoraproject.org> - 2024.3-4
- Backport https://github.com/coreos/rpm-ostree/pull/4950
Resolves: #RHEL-36085
* Thu Aug 15 2024 Joseph Marrero <jmarrero@fedoraproject.org> - 2024.7-2
- Backport https://github.com/coreos/rpm-ostree/pull/5051
Resolves: #RHEL-53871
* Tue Apr 16 2024 Joseph Marrero <jmarrero@fedoraproject.org> - 2024.3-3
* Tue Aug 09 2024 Joseph Marrero <jmarrero@fedoraproject.org> - 2024.7-1
- Rebase to 2024.7
Resolves: #RHEL-53871
* Tue May 21 2024 Joseph Marrero <jmarrero@fedoraproject.org> - 2024.5-1
- Rebase to 2024.6
Resolves: #RHEL-29339
* Mon Apr 15 2024 Joseph Marrero <jmarrero@fedoraproject.org> - 2024.5-1
- Rebase to 2024.5
Adds fix for https://github.com/coreos/rpm-ostree/security/advisories/GHSA-2m76-cwhg-7wv6
Resolves: #RHEL-30415
* Tue Apr 09 2024 Joseph Marrero <jmarrero@fedoraproject.org> - 2024.4-4
- Backport https://github.com/coreos/rpm-ostree/security/advisories/GHSA-2m76-cwhg-7wv6
Resolves: #RHEL-31852
* Fri Apr 05 2024 Joseph Marrero <jmarrero@fedoraproject.org> - 2024.3-2
- Backport https://github.com/coreos/rpm-ostree/security/advisories/GHSA-2m76-cwhg-7wv6
Resolves: #RHEL-31852
* Thu Mar 21 2024 Colin Walters <walters@verbum.org> - 2024.4-3
- Backport patch to fix https://issues.redhat.com/browse/RHEL-29559
* Fri Mar 15 2024 Colin Walters <walters@verbum.org> - 2024.4-2
- https://github.com/coreos/rpm-ostree/releases/tag/v2024.4
Resolves: #RHEL-29339
* Sun Feb 25 2024 Joseph Marrero <jmarrero@fedoraproject.org> - 2024.3-1
- https://github.com/coreos/rpm-ostree/releases/tag/v2024.3