-
Notifications
You must be signed in to change notification settings - Fork 649
[AutoPR- Security] Patch rpm-ostree for CVE-2026-33055, CVE-2026-33056 [MEDIUM] #16354
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
kgodara912
merged 8 commits into
microsoft:main
from
azurelinux-security:azure-autosec/rpm-ostree/2.0/1082072
Apr 27, 2026
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
356da76
Patch rpm-ostree for CVE-2026-33055
azurelinux-security a1abc70
Patch rpm-ostree for CVE-2026-33056
azurelinux-security 5ac0e3b
Added changes to checksums
SumitJenaHCL 7caee8e
Fixed ptests failure
SumitJenaHCL 1c2de8b
Update patch for CVE-2026-33055
SumitJenaHCL be1247a
updated checksum
SumitJenaHCL 0885df5
Updated Checksum
SumitJenaHCL cc69da9
Update checksums for toml file.
SumitJenaHCL File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,240 @@ | ||
| From cc80cb086125efb7a0c7a1f615074406c4480af7 Mon Sep 17 00:00:00 2001 | ||
| From: AllSpark <allspark@microsoft.com> | ||
| Date: Mon, 30 Mar 2026 11:50:49 +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 <walters@verbum.org> | ||
| Co-authored-by: Colin Walters <walters@verbum.org> | ||
| Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> | ||
| Upstream-reference: AI Backport of https://github.com/alexcrichton/tar-rs/commit/de1a5870e603758f430073688691165f21a33946.patch | ||
| --- | ||
| vendor/tar/.cargo-checksum.json | 2 +- | ||
| vendor/tar/Cargo.toml | 10 +++ | ||
| vendor/tar/src/archive.rs | 9 +- | ||
| vendor/tar/tests/all.rs | 151 ++++++++++++++++++++++++++++++++ | ||
| 4 files changed, 167 insertions(+), 5 deletions(-) | ||
|
|
||
| diff --git a/vendor/tar/.cargo-checksum.json b/vendor/tar/.cargo-checksum.json | ||
| index 508f784e..1f3abaf5 100644 | ||
| --- a/vendor/tar/.cargo-checksum.json | ||
| +++ b/vendor/tar/.cargo-checksum.json | ||
| @@ -1 +1 @@ | ||
| -{"files":{"Cargo.lock":"9872bf9e41b9cadee45b688c9537030a993ca49a266fc7859029d8c74810d1d5","Cargo.toml":"8353c71aa4d394efa7aaeac3004d0a16fd0c7124b7bd57ea91ba87a7b2015f15","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"71079f1a0962c2cf288058f38d24735bddabd1427ac2dee72ec18cc5ae4bceed","examples/extract_file.rs":"dc487f6631d824175afc3ee33de99e80718a8ca3f9e57fddd7cac0a46c07d3ae","examples/list.rs":"36e412205eaffea8ab7f39be4173594b74e36acb369e091362b1975ee4a7a14b","examples/raw_list.rs":"0a735576ac354457d6d5a4d395d044fae99bf67a7c69960ca784a6f6a1743651","examples/write.rs":"419ac3e4155035e32b52cd8e6ae987a2d99cf82f60abbfb315c2a2c4f8e8fd19","src/archive.rs":"85a0091e02690c62379137988cd9b2689009536a0b941f1ab0581db26e9ebce6","src/builder.rs":"2914f394d44c133557532bf5765fe63e0def30ec0b447f8f2bc620e932a2036a","src/entry.rs":"705016636f7fdcad4fe20d7d2672be2b94cc53bb05e47628f5212b89e17a40fe","src/entry_type.rs":"0786688729a96b4a3135b28d40b95c3d4feaad66b9574c490cbea14814ab975f","src/error.rs":"a20813fbc52f1f2e3a79654f62de6001759f6504a06acee5b0819d4865398587","src/header.rs":"fb2b1fa943c19635826b3f2becfb82527be7d08fdac115af840da3ff06152908","src/lib.rs":"5468e413205c907c367c35d28a528389103d68fd6a5b5979bbedba7c9e6b6c99","src/pax.rs":"54002e31151f9c50e02a3da26b3cacd1d3c9a3902daee008ab76d112cf5a2430","tests/all.rs":"567a05d54e369d22efe40f3507a26e21f7878b95bd05c811250b2c350761791b","tests/entry.rs":"c1411ee09da9edb659b508867f0960e804966dfd33801f4a7afaefda331479dd","tests/header/mod.rs":"02b05639f63c39a47559650c7209817bb60282deb4f679d5b001ed936343d9de"},"package":"4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6"} | ||
| \ No newline at end of file | ||
| +{"files":{"Cargo.lock":"9872bf9e41b9cadee45b688c9537030a993ca49a266fc7859029d8c74810d1d5","Cargo.toml":"6000e6f99d39717fb9eb65ca1b03ad2b5499a4831a52d4b83f9a8c77e41368b3","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"71079f1a0962c2cf288058f38d24735bddabd1427ac2dee72ec18cc5ae4bceed","examples/extract_file.rs":"dc487f6631d824175afc3ee33de99e80718a8ca3f9e57fddd7cac0a46c07d3ae","examples/list.rs":"36e412205eaffea8ab7f39be4173594b74e36acb369e091362b1975ee4a7a14b","examples/raw_list.rs":"0a735576ac354457d6d5a4d395d044fae99bf67a7c69960ca784a6f6a1743651","examples/write.rs":"419ac3e4155035e32b52cd8e6ae987a2d99cf82f60abbfb315c2a2c4f8e8fd19","src/archive.rs":"4100bd92149fdb2a331eb84810ac317f59ef2b81925011a9ea44e3fa5dea3dba","src/builder.rs":"2914f394d44c133557532bf5765fe63e0def30ec0b447f8f2bc620e932a2036a","src/entry.rs":"705016636f7fdcad4fe20d7d2672be2b94cc53bb05e47628f5212b89e17a40fe","src/entry_type.rs":"0786688729a96b4a3135b28d40b95c3d4feaad66b9574c490cbea14814ab975f","src/error.rs":"a20813fbc52f1f2e3a79654f62de6001759f6504a06acee5b0819d4865398587","src/header.rs":"fb2b1fa943c19635826b3f2becfb82527be7d08fdac115af840da3ff06152908","src/lib.rs":"5468e413205c907c367c35d28a528389103d68fd6a5b5979bbedba7c9e6b6c99","src/pax.rs":"54002e31151f9c50e02a3da26b3cacd1d3c9a3902daee008ab76d112cf5a2430","tests/all.rs":"2e23cb167407eb50acdec21f3693fcfa744be577a912b50466933251be404932","tests/entry.rs":"c1411ee09da9edb659b508867f0960e804966dfd33801f4a7afaefda331479dd","tests/header/mod.rs":"02b05639f63c39a47559650c7209817bb60282deb4f679d5b001ed936343d9de"},"package":"4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6"} | ||
| \ No newline at end of file | ||
| diff --git a/vendor/tar/Cargo.toml b/vendor/tar/Cargo.toml | ||
| index 23771b56..3606d283 100644 | ||
| --- a/vendor/tar/Cargo.toml | ||
| +++ b/vendor/tar/Cargo.toml | ||
| @@ -27,6 +27,16 @@ version = "0.2.8" | ||
| [dev-dependencies.tempfile] | ||
| version = "3" | ||
|
|
||
| +[dev-dependencies.astral-tokio-tar] | ||
| +version = "0.5" | ||
| + | ||
| +[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, | ||
| diff --git a/vendor/tar/tests/all.rs b/vendor/tar/tests/all.rs | ||
| index 11103bd6..f7cceaf2 100644 | ||
| --- a/vendor/tar/tests/all.rs | ||
| +++ b/vendor/tar/tests/all.rs | ||
| @@ -1385,3 +1385,154 @@ fn header_size_overflow() { | ||
| err | ||
| ); | ||
| } | ||
| + | ||
| +/// Build the PAX size smuggling archive described in the original report. | ||
| +/// | ||
| +/// A PAX extended header declares `size=2048` for a regular file whose | ||
| +/// actual header size field is 8. A symlink entry is hidden inside the | ||
| +/// inflated region. A correct parser honours the PAX size and skips over | ||
| +/// the symlink; a buggy one reads only the header size and exposes it. | ||
| +fn build_pax_smuggle_archive() -> Vec<u8> { | ||
| + const B: usize = 512; | ||
| + const INFLATED: usize = 2048; | ||
| + let end_of_archive = || std::iter::repeat(0u8).take(B * 2); | ||
| + | ||
| + let mut ar: Vec<u8> = Vec::new(); | ||
| + | ||
| + // PAX extended header declaring size=2048 for the next entry. | ||
| + let pax_rec = format!("13 size={INFLATED}\n"); | ||
| + let mut pax_hdr = Header::new_ustar(); | ||
| + pax_hdr.set_path("./PaxHeaders/regular").unwrap(); | ||
| + pax_hdr.set_size(pax_rec.as_bytes().len() as u64); | ||
| + pax_hdr.set_entry_type(EntryType::XHeader); | ||
| + pax_hdr.set_cksum(); | ||
| + ar.extend_from_slice(pax_hdr.as_bytes()); | ||
| + ar.extend_from_slice(pax_rec.as_bytes()); | ||
| + ar.resize(ar.len().next_multiple_of(B), 0); | ||
| + | ||
| + // Regular file whose header says size=8, but PAX says 2048. | ||
| + let content = b"regular\n"; | ||
| + let mut file_hdr = Header::new_ustar(); | ||
| + file_hdr.set_path("regular.txt").unwrap(); | ||
| + file_hdr.set_size(content.len() as u64); | ||
| + file_hdr.set_entry_type(EntryType::Regular); | ||
| + file_hdr.set_cksum(); | ||
| + ar.extend_from_slice(file_hdr.as_bytes()); | ||
| + let mark = ar.len(); | ||
| + ar.extend_from_slice(content); | ||
| + ar.resize(ar.len().next_multiple_of(B), 0); | ||
| + | ||
| + // Smuggled symlink hidden in the inflated region. | ||
| + let mut sym_hdr = Header::new_ustar(); | ||
| + sym_hdr.set_path("smuggled").unwrap(); | ||
| + sym_hdr.set_size(0); | ||
| + sym_hdr.set_entry_type(EntryType::Symlink); | ||
| + sym_hdr.set_link_name("/etc/shadow").unwrap(); | ||
| + sym_hdr.set_cksum(); | ||
| + ar.extend_from_slice(sym_hdr.as_bytes()); | ||
| + ar.extend(end_of_archive()); | ||
| + | ||
| + // Pad to fill the inflated window. | ||
| + let used = ar.len() - mark; | ||
| + let pad = INFLATED.saturating_sub(used); | ||
| + ar.extend(std::iter::repeat(0u8).take(pad.next_multiple_of(B))); | ||
| + | ||
| + // End-of-archive. | ||
| + ar.extend(end_of_archive()); | ||
| + ar | ||
| +} | ||
| + | ||
| +/// Regression test for PAX size smuggling. | ||
| +/// | ||
| +/// A crafted archive uses a PAX extended header to declare a file size (2048) | ||
| +/// larger than the header's octal size field (8). Before the fix, `tar-rs` | ||
| +/// only applied the PAX size override when the header size was 0, so it would | ||
| +/// read the small header size, advance too little, and expose a symlink entry | ||
| +/// hidden in the "padding" area. After the fix, the PAX size unconditionally | ||
| +/// overrides the header size, causing the parser to skip over the smuggled | ||
| +/// symlink — matching the behavior of compliant parsers. | ||
| +#[test] | ||
| +fn pax_size_smuggled_symlink() { | ||
| + let data = build_pax_smuggle_archive(); | ||
| + | ||
| + let mut archive = Archive::new(random_cursor_reader(&data[..])); | ||
| + let entries: Vec<_> = archive | ||
| + .entries() | ||
| + .unwrap() | ||
| + .map(|e| { | ||
| + let e = e.unwrap(); | ||
| + let path = e.path().unwrap().to_path_buf(); | ||
| + let kind = e.header().entry_type(); | ||
| + let link = e.link_name().unwrap().map(|l| l.to_path_buf()); | ||
| + (path, kind, link) | ||
| + }) | ||
| + .collect(); | ||
| + | ||
| + // With the fix applied, only "regular.txt" should be visible. | ||
| + // The smuggled symlink must NOT appear. | ||
| + let expected: Vec<(PathBuf, EntryType, Option<PathBuf>)> = | ||
| + vec![(PathBuf::from("regular.txt"), EntryType::Regular, None)]; | ||
| + assert_eq!( | ||
| + entries, expected, | ||
| + "smuggled symlink visible or unexpected entries\n\ | ||
| + got: {entries:?}" | ||
| + ); | ||
| +} | ||
| + | ||
| +/// Cross-validate that `tar` and `astral-tokio-tar` parse the PAX size | ||
| +/// smuggling archive identically, guarding against parsing differentials. | ||
| +#[tokio::test] | ||
| +async fn pax_size_smuggle_matches_astral_tokio_tar() { | ||
| + use tokio_stream::StreamExt; | ||
| + | ||
| + let data = build_pax_smuggle_archive(); | ||
| + | ||
| + // Parse with sync tar. | ||
| + let sync_entries: Vec<_> = { | ||
| + let mut ar = Archive::new(&data[..]); | ||
| + ar.entries() | ||
| + .unwrap() | ||
| + .map(|e| { | ||
| + let e = e.unwrap(); | ||
| + let path = e.path().unwrap().to_path_buf(); | ||
| + let kind = e.header().entry_type(); | ||
| + let link = e.link_name().unwrap().map(|l| l.to_path_buf()); | ||
| + (path, kind, link) | ||
| + }) | ||
| + .collect() | ||
| + }; | ||
| + | ||
| + // Parse with async astral-tokio-tar. | ||
| + let async_entries: Vec<_> = { | ||
| + let mut ar = tokio_tar::Archive::new(&data[..]); | ||
| + let mut entries = ar.entries().unwrap(); | ||
| + let mut result = Vec::new(); | ||
| + while let Some(e) = entries.next().await { | ||
| + let e = e.unwrap(); | ||
| + let entry_type = e.header().entry_type(); | ||
| + result.push(( | ||
| + e.path().unwrap().to_path_buf(), | ||
| + // Map through the raw byte so the two crates' EntryTypes compare. | ||
| + EntryType::new(entry_type.as_byte()), | ||
| + e.link_name().unwrap().map(|l| l.to_path_buf()), | ||
| + )); | ||
| + } | ||
| + result | ||
| + }; | ||
| + | ||
| + // Assert exact expected content for both parsers independently, | ||
| + // so we verify correctness — not just mutual agreement. | ||
| + let expected: Vec<(PathBuf, EntryType, Option<PathBuf>)> = | ||
| + vec![(PathBuf::from("regular.txt"), EntryType::Regular, None)]; | ||
| + | ||
| + assert_eq!( | ||
| + sync_entries, expected, | ||
| + "tar-rs produced unexpected entries (smuggled symlink visible?)\n\ | ||
| + got: {sync_entries:?}" | ||
| + ); | ||
| + assert_eq!( | ||
| + async_entries, expected, | ||
| + "astral-tokio-tar produced unexpected entries (smuggled symlink visible?)\n\ | ||
| + got: {async_entries:?}" | ||
| + ); | ||
| +} | ||
| -- | ||
| 2.45.4 | ||
|
|
||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where is this build_pax_smuggle_archive() defined ?
Could you please check the patch and update accordingly. Thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the patch.