Files
poky/meta/recipes-devtools/rust/files/CVE-2026-5223.patch
Anil Dongare 7aad94e82e cargo: Fix CVE-2026-5223
This patch applies the upstream fix as referenced in [2], using the commit shown in [1].

[1] 285cebf589
[2] https://security-tracker.debian.org/tracker/CVE-2026-5223

(From OE-Core rev: 9a7fa66844042347a01347538c221115eb40856b)

Signed-off-by: Anil Dongare <adongare@cisco.com>
Signed-off-by: Yoann Congal <yoann.congal@smile.fr>
Signed-off-by: Paul Barker <paul@pbarker.dev>
2026-07-20 09:04:32 +01:00

115 lines
4.4 KiB
Diff

From 285cebf58911eca5b7f177f5d0b1c53e1f646577 Mon Sep 17 00:00:00 2001
From: Josh Triplett <josh@joshtriplett.org>
Date: Mon, 30 Mar 2026 10:35:55 -0700
Subject: [PATCH] CVE-2026-5223: prohibit unpacking symlinks and other
unexpected entries
Cargo has historically not allowed creating .crate packages containing
symlinks. (It packages the symlink target in place of the symlink,
instead.) So, any package containing a symlink would have to be
hand-constructed. Such packages are also not allowed on crates.io, so it
could only come from an alternate registry.
Rather than dealing with symlink traversal attacks when unpacking a
crate, just prohibit symlinks entirely.
In the process, also prohibit other kinds of unusual entries. As an
exception, allow character devices but warn about them, because some
exist in crates on crates.io.
CVE: CVE-2026-5223
Upstream-Status: Backport [https://github.com/rust-lang/cargo/commit/285cebf58911eca5b7f177f5d0b1c53e1f646577]
Backport Changes:
- Adapted to Cargo 0.76.0 in Rust 1.75.0, where unpack_package() still carries
the extraction loop directly and the newer smuggled-symlink regression test
is not present.
(cherry picked from commit 285cebf58911eca5b7f177f5d0b1c53e1f646577)
Signed-off-by: Anil Dongare <adongare@cisco.com>
---
src/tools/cargo/src/cargo/sources/registry/mod.rs | 9 ++++++++-
src/tools/cargo/tests/testsuite/registry.rs | 31 ++++++++++++-----------
2 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/src/tools/cargo/src/cargo/sources/registry/mod.rs b/src/tools/cargo/src/cargo/sources/registry/mod.rs
index 7ee461e..c97d96d 100644
--- a/src/tools/cargo/src/cargo/sources/registry/mod.rs
+++ b/src/tools/cargo/src/cargo/sources/registry/mod.rs
@@ -197,7 +197,7 @@ use cargo_util::paths::{self, exclude_from_backups_and_indexing};
use flate2::read::GzDecoder;
use serde::Deserialize;
use serde::Serialize;
-use tar::Archive;
+use tar::{Archive, EntryType};
use tracing::debug;
use crate::core::dependency::Dependency;
@@ -636,6 +636,13 @@ impl<'cfg> RegistrySource<'cfg> {
prefix
)
}
+ // Prevent unpacking symlinks and other unexpected entry types.
+ match entry.header().entry_type() {
+ EntryType::Regular | EntryType::Directory => {}
+ t => anyhow::bail!(
+ "invalid tarball downloaded, contains an entry at {entry_path:?} with invalid type {t:?}",
+ ),
+ }
// Prevent unpacking the lockfile from the crate itself.
if entry_path
.file_name()
diff --git a/src/tools/cargo/tests/testsuite/registry.rs b/src/tools/cargo/tests/testsuite/registry.rs
index b5dff27..178bfff 100644
--- a/src/tools/cargo/tests/testsuite/registry.rs
+++ b/src/tools/cargo/tests/testsuite/registry.rs
@@ -2550,8 +2550,7 @@ fn package_lock_inside_package_is_overwritten() {
}
#[cargo_test]
-fn package_lock_as_a_symlink_inside_package_is_overwritten() {
- let registry = registry::init();
+fn package_lock_as_a_symlink_inside_package_is_invalid() {
let p = project()
.file(
"Cargo.toml",
@@ -2573,21 +2572,23 @@ fn package_lock_as_a_symlink_inside_package_is_overwritten() {
.symlink(".cargo-ok", "src/lib.rs")
.publish();
- p.cargo("check").run();
+ p.cargo("check")
+ .with_status(101)
+ .with_stderr_data(str![[r#"
+[UPDATING] `dummy-registry` index
+[LOCKING] 1 package to latest compatible version
+[DOWNLOADING] crates ...
+[DOWNLOADED] bar v0.0.1 (registry `dummy-registry`)
+[ERROR] failed to download replaced source registry `crates-io`
- let id = SourceId::for_registry(registry.index_url()).unwrap();
- let hash = cargo::util::hex::short_hash(&id);
- let pkg_root = cargo_home()
- .join("registry")
- .join("src")
- .join(format!("-{}", hash))
- .join("bar-0.0.1");
- let ok = pkg_root.join(".cargo-ok");
- let librs = pkg_root.join("src/lib.rs");
+Caused by:
+ failed to unpack package `bar v0.0.1 (registry `dummy-registry`)`
- // Is correctly overwritten and doesn't affect the file linked to
- assert_eq!(ok.metadata().unwrap().len(), 7);
- assert_eq!(fs::read_to_string(librs).unwrap(), "pub fn f() {}");
+Caused by:
+ invalid tarball downloaded, contains an entry at "bar-0.0.1/.cargo-ok" with invalid type Symlink
+
+"#]])
+ .run();
}
#[cargo_test]
--
2.44.4