rust/CVE-2022-36114.patch
2024-06-27 16:27:22 +08:00

108 lines
3.9 KiB
Diff

Refer:
https://github.com/rust-lang/cargo/commit/2b68d3c07a4a056264dc006ecb9f1354a0679cd3
https://build.opensuse.org/package/show/SUSE:SLE-15-SP3:Update/rust1.62
From 2b68d3c07a4a056264dc006ecb9f1354a0679cd3 Mon Sep 17 00:00:00 2001
From: Josh Triplett <josh@joshtriplett.org>
Date: Thu, 18 Aug 2022 17:45:45 +0200
Subject: [PATCH] CVE-2022-36114: limit the maximum unpacked size of a crate to
512MB
This gives users of custom registries the same protections, using the
same size limit that crates.io uses.
`LimitErrorReader` code copied from crates.io.
---
.../cargo/src/cargo/sources/registry/mod.rs | 4 ++-
src/tools/cargo/src/cargo/util/io.rs | 27 +++++++++++++++++++
src/tools/cargo/src/cargo/util/mod.rs | 2 ++
3 files changed, 32 insertions(+), 1 deletion(-)
create mode 100644 src/tools/cargo/src/cargo/util/io.rs
diff --git a/src/tools/cargo/src/cargo/sources/registry/mod.rs b/src/tools/cargo/src/cargo/sources/registry/mod.rs
index 5357e9c..e2028d5 100644
--- a/src/tools/cargo/src/cargo/sources/registry/mod.rs
+++ b/src/tools/cargo/src/cargo/sources/registry/mod.rs
@@ -179,7 +179,7 @@ use crate::util::errors::CargoResultExt;
use crate::util::hex;
use crate::util::interning::InternedString;
use crate::util::into_url::IntoUrl;
-use crate::util::{restricted_names, CargoResult, Config, Filesystem};
+use crate::util::{restricted_names, CargoResult, Config, Filesystem, LimitErrorReader};
const PACKAGE_SOURCE_LOCK: &str = ".cargo-ok";
pub const CRATES_IO_INDEX: &str = "https://github.com/rust-lang/crates.io-index";
@@ -188,6 +188,7 @@ const CRATE_TEMPLATE: &str = "{crate}";
const VERSION_TEMPLATE: &str = "{version}";
const PREFIX_TEMPLATE: &str = "{prefix}";
const LOWER_PREFIX_TEMPLATE: &str = "{lowerprefix}";
+const MAX_UNPACK_SIZE: u64 = 512 * 1024 * 1024;
/// A "source" for a [local](local::LocalRegistry) or
/// [remote](remote::RemoteRegistry) registry.
@@ -583,6 +584,7 @@ impl<'cfg> RegistrySource<'cfg> {
}
}
let gz = GzDecoder::new(tarball);
+ let gz = LimitErrorReader::new(gz, MAX_UNPACK_SIZE);
let mut tar = Archive::new(gz);
let prefix = unpack_dir.file_name().unwrap();
let parent = unpack_dir.parent().unwrap();
diff --git a/src/tools/cargo/src/cargo/util/io.rs b/src/tools/cargo/src/cargo/util/io.rs
new file mode 100644
index 0000000..f62672d
--- /dev/null
+++ b/src/tools/cargo/src/cargo/util/io.rs
@@ -0,0 +1,27 @@
+use std::io::{self, Read, Take};
+
+#[derive(Debug)]
+pub struct LimitErrorReader<R> {
+ inner: Take<R>,
+}
+
+impl<R: Read> LimitErrorReader<R> {
+ pub fn new(r: R, limit: u64) -> LimitErrorReader<R> {
+ LimitErrorReader {
+ inner: r.take(limit),
+ }
+ }
+}
+
+impl<R: Read> Read for LimitErrorReader<R> {
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ match self.inner.read(buf) {
+ Ok(0) if self.inner.limit() == 0 => Err(io::Error::new(
+ io::ErrorKind::Other,
+ "maximum limit reached when reading",
+ )),
+ e => e,
+ }
+ }
+}
+
diff --git a/src/tools/cargo/src/cargo/util/mod.rs b/src/tools/cargo/src/cargo/util/mod.rs
index f0408d2..9e5f83e 100644
--- a/src/tools/cargo/src/cargo/util/mod.rs
+++ b/src/tools/cargo/src/cargo/util/mod.rs
@@ -13,6 +13,7 @@ pub use self::hasher::StableHasher;
pub use self::hex::{hash_u64, short_hash, to_hex};
pub use self::into_url::IntoUrl;
pub use self::into_url_with_base::IntoUrlWithBase;
+pub(crate) use self::io::LimitErrorReader;
pub use self::lev_distance::{closest, closest_msg, lev_distance};
pub use self::lockserver::{LockServer, LockServerClient, LockServerStarted};
pub use self::paths::{bytes2path, dylib_path, join_paths, path2bytes};
@@ -46,6 +47,7 @@ pub mod important_paths;
pub mod interning;
pub mod into_url;
mod into_url_with_base;
+mod io;
pub mod job;
pub mod lev_distance;
mod lockserver;
--
2.27.0