diff --git a/Cargo.lock b/Cargo.lock
index 9a53e0168728b9..e856b6fb976d57 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2506,9 +2506,9 @@ dependencies = [
[[package]]
name = "matches"
-version = "0.1.8"
+version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
+checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]]
name = "maybe-uninit"
@@ -6225,9 +6225,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "tar"
-version = "0.4.35"
+version = "0.4.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d779dc6aeff029314570f666ec83f19df7280bb36ef338442cfa8c604021b80"
+checksum = "d6f5515d3add52e0bbdcad7b83c388bb36ba7b754dda3b5f5bc2d38640cdba5c"
dependencies = [
"filetime",
"libc",
diff --git a/download-utils/Cargo.toml b/download-utils/Cargo.toml
index 0f9d84b14e7f3f..995457566b3006 100644
--- a/download-utils/Cargo.toml
+++ b/download-utils/Cargo.toml
@@ -17,7 +17,7 @@ log = "0.4.14"
reqwest = { version = "0.11.4", default-features = false, features = ["blocking", "rustls-tls", "json"] }
solana-sdk = { path = "../sdk", version = "=1.8.0" }
solana-runtime = { path = "../runtime", version = "=1.8.0" }
-tar = "0.4.35"
+tar = "0.4.37"
[lib]
crate-type = ["lib"]
diff --git a/install/Cargo.toml b/install/Cargo.toml
index 7bf65f4ce710d2..df61a8b6a64946 100644
--- a/install/Cargo.toml
+++ b/install/Cargo.toml
@@ -32,7 +32,7 @@ solana-logger = { path = "../logger", version = "=1.8.0" }
solana-sdk = { path = "../sdk", version = "=1.8.0" }
solana-version = { path = "../version", version = "=1.8.0" }
semver = "1.0.4"
-tar = "0.4.35"
+tar = "0.4.37"
tempfile = "3.2.0"
url = "2.2.2"
diff --git a/programs/bpf/Cargo.lock b/programs/bpf/Cargo.lock
index 07afc1fec6be80..fe699b0da5f4a9 100644
--- a/programs/bpf/Cargo.lock
+++ b/programs/bpf/Cargo.lock
@@ -3486,9 +3486,9 @@ dependencies = [
[[package]]
name = "tar"
-version = "0.4.35"
+version = "0.4.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d779dc6aeff029314570f666ec83f19df7280bb36ef338442cfa8c604021b80"
+checksum = "d6f5515d3add52e0bbdcad7b83c388bb36ba7b754dda3b5f5bc2d38640cdba5c"
dependencies = [
"filetime",
"libc",
diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml
index 1dd0ab6c9913bd..e8b9da0db68f8c 100644
--- a/runtime/Cargo.toml
+++ b/runtime/Cargo.toml
@@ -49,7 +49,7 @@ solana-secp256k1-program = { path = "../programs/secp256k1", version = "=1.8.0"
solana-stake-program = { path = "../programs/stake", version = "=1.8.0" }
solana-vote-program = { path = "../programs/vote", version = "=1.8.0" }
symlink = "0.1.0"
-tar = "0.4.35"
+tar = "0.4.37"
tempfile = "3.2.0"
thiserror = "1.0"
zstd = "0.9.0"
diff --git a/runtime/src/hardened_unpack.rs b/runtime/src/hardened_unpack.rs
index fdaa424f6c2515..7580ab4b10e61d 100644
--- a/runtime/src/hardened_unpack.rs
+++ b/runtime/src/hardened_unpack.rs
@@ -9,7 +9,7 @@ use {
fs::{self, File},
io::{BufReader, Read},
path::{
- Component::{CurDir, Normal},
+ Component::{self, CurDir, Normal},
Path, PathBuf,
},
time::Instant,
@@ -161,9 +161,14 @@ where
)?;
total_count = checked_total_count_increment(total_count, limit_count)?;
- // unpack_in does its own sanitization
- // ref: https://docs.rs/tar/*/tar/struct.Entry.html#method.unpack_in
- check_unpack_result(entry.unpack_in(unpack_dir)?, path_str)?;
+ let target = sanitize_path(&entry.path()?, unpack_dir)?; // ? handles file system errors
+ if target.is_none() {
+ continue; // skip it
+ }
+ let target = target.unwrap();
+
+ let unpack = entry.unpack(target);
+ check_unpack_result(unpack.map(|_unpack| true)?, path_str)?;
// Sanitize permissions.
let mode = match entry.header().entry_type() {
@@ -199,6 +204,80 @@ where
}
}
+// return Err on file system error
+// return Some(path) if path is good
+// return None if we should skip this file
+fn sanitize_path(entry_path: &Path, dst: &Path) -> Result