From 7ef5ee6df2f72bea27bba09f53d16650bc4569fc Mon Sep 17 00:00:00 2001 From: Azure Linux Security Servicing Account Date: Thu, 26 Mar 2026 08:35:12 +0000 Subject: [PATCH] Patch rpm-ostree for CVE-2026-33056, CVE-2026-33055 --- SPECS/rpm-ostree/CVE-2026-33055.patch | 73 +++++++++++++ SPECS/rpm-ostree/CVE-2026-33056.patch | 150 ++++++++++++++++++++++++++ SPECS/rpm-ostree/rpm-ostree.spec | 7 +- 3 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 SPECS/rpm-ostree/CVE-2026-33055.patch create mode 100644 SPECS/rpm-ostree/CVE-2026-33056.patch diff --git a/SPECS/rpm-ostree/CVE-2026-33055.patch b/SPECS/rpm-ostree/CVE-2026-33055.patch new file mode 100644 index 00000000000..b951c076041 --- /dev/null +++ b/SPECS/rpm-ostree/CVE-2026-33055.patch @@ -0,0 +1,73 @@ +From bbf89c7d2c7647feda9e8e67280b771cf8de44f3 Mon Sep 17 00:00:00 2001 +From: AllSpark +Date: Thu, 26 Mar 2026 08:27:31 +0000 +Subject: [PATCH] archive: Unconditionally honor PAX size (#441) + +This synchronizes our behavior with most other tar parsers +(including astral-tokio-tar and Go archive/tar) ensuring +that we don't parse things differently. + +The problem with parsing size in particular differently is +it's easy to craft a tar archive that appears completely differently +between two parsers. This is the case with e.g. crates.io where +astral-tokio-tar is used for validation server side, but cargo uses +the crate to upload. + +With this, the two projects agree. + +Signed-off-by: Colin Walters +Co-authored-by: Colin Walters +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: AI Backport of https://github.com/alexcrichton/tar-rs/commit/de1a5870e603758f430073688691165f21a33946.patch +--- + vendor/tar/Cargo.toml | 10 ++++++++++ + vendor/tar/src/archive.rs | 9 +++++---- + 2 files changed, 15 insertions(+), 4 deletions(-) + +diff --git a/vendor/tar/Cargo.toml b/vendor/tar/Cargo.toml +index 23771b56..e55390bd 100644 +--- a/vendor/tar/Cargo.toml ++++ b/vendor/tar/Cargo.toml +@@ -24,9 +24,19 @@ license = "MIT/Apache-2.0" + repository = "https://github.com/alexcrichton/tar-rs" + [dependencies.filetime] + version = "0.2.8" ++[dev-dependencies.astral-tokio-tar] ++version = "0.5" ++ + [dev-dependencies.tempfile] + version = "3" + ++[dev-dependencies.tokio] ++version = "1" ++features = ["macros", "rt"] ++ ++[dev-dependencies.tokio-stream] ++version = "0.1" ++ + [features] + default = ["xattr"] + [target."cfg(unix)".dependencies.libc] +diff --git a/vendor/tar/src/archive.rs b/vendor/tar/src/archive.rs +index 1bed5124..221d1551 100644 +--- a/vendor/tar/src/archive.rs ++++ b/vendor/tar/src/archive.rs +@@ -290,10 +290,11 @@ impl<'a> EntriesFields<'a> { + + let file_pos = self.next; + let mut size = header.entry_size()?; +- if size == 0 { +- if let Some(pax_size) = pax_size { +- size = pax_size; +- } ++ // If this exists, it must override the header size. Disagreement among ++ // parsers allows construction of malicious archives that appear different ++ // when parsed. ++ if let Some(pax_size) = pax_size { ++ size = pax_size; + } + let ret = EntryFields { + size: size, +-- +2.45.4 + diff --git a/SPECS/rpm-ostree/CVE-2026-33056.patch b/SPECS/rpm-ostree/CVE-2026-33056.patch new file mode 100644 index 00000000000..dea5a178eb7 --- /dev/null +++ b/SPECS/rpm-ostree/CVE-2026-33056.patch @@ -0,0 +1,150 @@ +From aa3c496809405b04ad02a9f9a48d75dce43ef364 Mon Sep 17 00:00:00 2001 +From: Alex Crichton +Date: Thu, 19 Mar 2026 16:58:05 -0500 +Subject: [PATCH] archive: Prevent symlink-directory collision chmod attack + (#442) + +When unpacking a tarball containing a symlink followed by a directory +entry with the same path, unpack_dir previously used fs::metadata() +which follows symlinks. This allowed an attacker to modify permissions +on arbitrary directories outside the extraction path. + +The fix uses fs::symlink_metadata() to detect symlinks and refuse to +treat them as valid existing directories. + +Document more exhaustively+consistently security caveats. + +Reported-by: Sergei Zimmerman +Assisted-by: OpenCode (Claude claude-opus-4-5) + +Signed-off-by: Colin Walters +Co-authored-by: Colin Walters +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://github.com/alexcrichton/tar-rs/commit/17b1fd84e632071cb8eef9d3709bf347bd266446.patch +--- + vendor/tar/src/archive.rs | 18 ++++++++++--- + vendor/tar/src/entry.rs | 7 ++--- + vendor/tar/tests/entry.rs | 56 +++++++++++++++++++++++++++++++++++++++ + 3 files changed, 75 insertions(+), 6 deletions(-) + +diff --git a/vendor/tar/src/archive.rs b/vendor/tar/src/archive.rs +index 1bed5124..056eb71a 100644 +--- a/vendor/tar/src/archive.rs ++++ b/vendor/tar/src/archive.rs +@@ -88,9 +88,21 @@ impl Archive { + /// extracting each file in turn to the location specified by the entry's + /// path name. + /// +- /// This operation is relatively sensitive in that it will not write files +- /// outside of the path specified by `dst`. Files in the archive which have +- /// a '..' in their path are skipped during the unpacking process. ++ /// # Security ++ /// ++ /// A best-effort is made to prevent writing files outside `dst` (paths ++ /// containing `..` are skipped, symlinks are validated). However, there ++ /// have been historical bugs in this area, and more may exist. For this ++ /// reason, when processing untrusted archives, stronger sandboxing is ++ /// encouraged: e.g. the [`cap-std`] crate and/or OS-level ++ /// containerization/virtualization. ++ /// ++ /// If `dst` does not exist, it is created. Unpacking into an existing ++ /// directory merges content. This function assumes `dst` is not ++ /// concurrently modified by untrusted processes. Protecting against ++ /// TOCTOU races is out of scope for this crate. ++ /// ++ /// [`cap-std`]: https://docs.rs/cap-std/ + /// + /// # Examples + /// +diff --git a/vendor/tar/src/entry.rs b/vendor/tar/src/entry.rs +index 8f0b62ac..287d6890 100644 +--- a/vendor/tar/src/entry.rs ++++ b/vendor/tar/src/entry.rs +@@ -210,8 +210,9 @@ impl<'a, R: Read> Entry<'a, R> { + /// also be propagated to the path `dst`. Any existing file at the location + /// `dst` will be overwritten. + /// +- /// This function carefully avoids writing outside of `dst`. If the file has +- /// a '..' in its path, this function will skip it and return false. ++ /// # Security ++ /// ++ /// See [`Archive::unpack`]. + /// + /// # Examples + /// +@@ -430,7 +431,7 @@ impl<'a> EntryFields<'a> { + // If the directory already exists just let it slide + fs::create_dir(dst).or_else(|err| { + if err.kind() == ErrorKind::AlreadyExists { +- let prev = fs::metadata(dst); ++ let prev = fs::symlink_metadata(dst); + if prev.map(|m| m.is_dir()).unwrap_or(false) { + return Ok(()); + } +diff --git a/vendor/tar/tests/entry.rs b/vendor/tar/tests/entry.rs +index fa8eeaee..5e874fa5 100644 +--- a/vendor/tar/tests/entry.rs ++++ b/vendor/tar/tests/entry.rs +@@ -377,3 +377,59 @@ fn modify_symlink_just_created() { + t!(t!(File::open(&test)).read_to_end(&mut contents)); + assert_eq!(contents.len(), 0); + } ++ ++/// Test that unpacking a tarball with a symlink followed by a directory entry ++/// with the same name does not allow modifying permissions of arbitrary directories ++/// outside the extraction path. ++#[test] ++#[cfg(unix)] ++fn symlink_dir_collision_does_not_modify_external_dir_permissions() { ++ use ::std::fs; ++ use ::std::os::unix::fs::PermissionsExt; ++ ++ let td = Builder::new().prefix("tar").tempdir().unwrap(); ++ ++ let target_dir = td.path().join("target-dir"); ++ fs::create_dir(&target_dir).unwrap(); ++ fs::set_permissions(&target_dir, fs::Permissions::from_mode(0o700)).unwrap(); ++ let before_mode = fs::metadata(&target_dir).unwrap().permissions().mode() & 0o7777; ++ assert_eq!(before_mode, 0o700); ++ ++ let extract_dir = td.path().join("extract-dir"); ++ fs::create_dir(&extract_dir).unwrap(); ++ ++ let mut ar = tar::Builder::new(Vec::new()); ++ ++ let mut header = tar::Header::new_gnu(); ++ header.set_size(0); ++ header.set_entry_type(tar::EntryType::Symlink); ++ header.set_path("foo").unwrap(); ++ header.set_link_name(&target_dir).unwrap(); ++ header.set_mode(0o777); ++ header.set_cksum(); ++ ar.append(&header, &[][..]).unwrap(); ++ ++ let mut header = tar::Header::new_gnu(); ++ header.set_size(0); ++ header.set_entry_type(tar::EntryType::Directory); ++ header.set_path("foo").unwrap(); ++ header.set_mode(0o777); ++ header.set_cksum(); ++ ar.append(&header, &[][..]).unwrap(); ++ ++ let bytes = ar.into_inner().unwrap(); ++ let mut ar = tar::Archive::new(&bytes[..]); ++ ++ let result = ar.unpack(&extract_dir); ++ assert!(result.is_err()); ++ ++ let symlink_path = extract_dir.join("foo"); ++ assert!(symlink_path ++ .symlink_metadata() ++ .unwrap() ++ .file_type() ++ .is_symlink()); ++ ++ let after_mode = fs::metadata(&target_dir).unwrap().permissions().mode() & 0o7777; ++ assert_eq!(after_mode, 0o700); ++} +-- +2.45.4 + diff --git a/SPECS/rpm-ostree/rpm-ostree.spec b/SPECS/rpm-ostree/rpm-ostree.spec index 5659f2a37c1..89104323edf 100644 --- a/SPECS/rpm-ostree/rpm-ostree.spec +++ b/SPECS/rpm-ostree/rpm-ostree.spec @@ -1,7 +1,7 @@ Summary: Commit RPMs to an OSTree repository Name: rpm-ostree Version: 2022.1 -Release: 8%{?dist} +Release: 9%{?dist} License: LGPLv2+ Vendor: Microsoft Corporation Distribution: Mariner @@ -14,6 +14,8 @@ Patch3: rpm-ostree-drop-lint-which-treats-warning-as-error.patch Patch4: CVE-2022-47085.patch Patch5: CVE-2023-26964.patch Patch6: CVE-2025-58160.patch +Patch7: CVE-2026-33055.patch +Patch8: CVE-2026-33056.patch BuildRequires: attr-devel BuildRequires: autoconf @@ -160,6 +162,9 @@ make check %{_datadir}/gir-1.0/*-1.0.gir %changelog +* Thu Mar 26 2026 Azure Linux Security Servicing Account - 2022.1-9 +- Patch for CVE-2026-33056, CVE-2026-33055 + * Wed Jan 07 2026 BinduSri Adabala - 2022.1-8 - Patch for CVE-2025-58160