aboutsummaryrefslogtreecommitdiff
path: root/nix-rust/src/util
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2019-12-13 18:11:37 +0100
committerEelco Dolstra <edolstra@gmail.com>2019-12-13 19:05:26 +0100
commit5a6d6da7aea23a48126a77f98612518af66bc203 (patch)
treed21796b9843e5d87c0786b49acf70fe9ee92eca7 /nix-rust/src/util
parent4581159e3f5a1cc38aa8e90dfd45f0a63354be44 (diff)
Validate tarball components
Diffstat (limited to 'nix-rust/src/util')
-rw-r--r--nix-rust/src/util/tarfile.rs18
1 files changed, 14 insertions, 4 deletions
diff --git a/nix-rust/src/util/tarfile.rs b/nix-rust/src/util/tarfile.rs
index 379d9098f..74d60692c 100644
--- a/nix-rust/src/util/tarfile.rs
+++ b/nix-rust/src/util/tarfile.rs
@@ -2,18 +2,28 @@ use crate::{foreign::Source, Error};
use std::fs;
use std::io;
use std::os::unix::fs::OpenOptionsExt;
-use std::path::Path;
+use std::path::{Component, Path};
use tar::Archive;
-pub fn unpack_tarfile(source: Source, dest_dir: &str) -> Result<(), Error> {
- let dest_dir = Path::new(dest_dir);
+pub fn unpack_tarfile(source: Source, dest_dir: &Path) -> Result<(), Error> {
+ fs::create_dir_all(dest_dir)?;
let mut tar = Archive::new(source);
for file in tar.entries()? {
let mut file = file?;
- let dest_file = dest_dir.join(file.path()?);
+ let path = file.path()?;
+
+ for i in path.components() {
+ if let Component::Prefix(_) | Component::RootDir | Component::ParentDir = i {
+ return Err(Error::BadTarFileMemberName(
+ file.path()?.to_str().unwrap().to_string(),
+ ));
+ }
+ }
+
+ let dest_file = dest_dir.join(path);
fs::create_dir_all(dest_file.parent().unwrap())?;