diff --git a/SPECS/trident/CVE-2026-33055.patch b/SPECS/trident/CVE-2026-33055.patch new file mode 100644 index 00000000000..fd8cf74925d --- /dev/null +++ b/SPECS/trident/CVE-2026-33055.patch @@ -0,0 +1,42 @@ +From f4826f2a2283222e87f8cef2c252342c05484268 Mon Sep 17 00:00:00 2001 +From: AllSpark +Date: Thu, 26 Mar 2026 11:59:06 +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/src/archive.rs | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/vendor/tar/src/archive.rs b/vendor/tar/src/archive.rs +index 924e54a..3051dbb 100644 +--- a/vendor/tar/src/archive.rs ++++ b/vendor/tar/src/archive.rs +@@ -339,10 +339,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/trident/CVE-2026-33056.patch b/SPECS/trident/CVE-2026-33056.patch new file mode 100644 index 00000000000..b385c22fa93 --- /dev/null +++ b/SPECS/trident/CVE-2026-33056.patch @@ -0,0 +1,150 @@ +From fa569268d51347b587d9d2bd171b6c37bd196273 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 924e54a..17938a8 100644 +--- a/vendor/tar/src/archive.rs ++++ b/vendor/tar/src/archive.rs +@@ -92,9 +92,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 b6b48b4..c9f3b9f 100644 +--- a/vendor/tar/src/entry.rs ++++ b/vendor/tar/src/entry.rs +@@ -212,8 +212,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 + /// +@@ -446,7 +447,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 4d612e2..92c11f6 100644 +--- a/vendor/tar/tests/entry.rs ++++ b/vendor/tar/tests/entry.rs +@@ -409,3 +409,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/trident/trident.spec b/SPECS/trident/trident.spec index 6f6c225d3b7..006f0ef3480 100644 --- a/SPECS/trident/trident.spec +++ b/SPECS/trident/trident.spec @@ -10,7 +10,7 @@ Summary: Declarative, security-first OS lifecycle agent designed primaril Name: trident # Use hard-coded versions for distro build Version: 0.21.0 -Release: 1%{?dist} +Release: 2%{?dist} License: MIT Vendor: Microsoft Corporation Group: Applications/System @@ -31,6 +31,8 @@ Source0: https://github.com/microsoft/trident/archive/refs/tags/v%{versio Source1: %{name}-%{version}-cargo.tar.gz %else Source1: osmodifier +Patch0: CVE-2026-33055.patch +Patch1: CVE-2026-33056.patch %endif BuildRequires: openssl-devel @@ -300,6 +302,9 @@ mkdir -p "$pcrlockroot" ) %changelog +* Thu Mar 26 2026 Azure Linux Security Servicing Account - 0.21.0-2 +- Patch for CVE-2026-33056, CVE-2026-33055 + * Mon Mar 2 2026 Brian Fjeldstad 0.21.0-1 - Original version for Azure Linux (license: MIT). - License verified.