Skip to content

Commit

Permalink
Fix tests leaking symlinks
Browse files Browse the repository at this point in the history
This patch changes our test handling so ZERO temporary files are leaked
to the filesystem after running Birdcage's tests.

Closes #66.
  • Loading branch information
cd-work committed Nov 30, 2023
1 parent ba30f64 commit a3f96bb
Show file tree
Hide file tree
Showing 24 changed files with 93 additions and 84 deletions.
3 changes: 2 additions & 1 deletion integration/canonicalize.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use std::fs;
use std::path::PathBuf;

use birdcage::{Birdcage, Exception, Sandbox};

use crate::TestSetup;

pub fn setup() -> TestSetup {
pub fn setup(_tempdir: PathBuf) -> TestSetup {
let mut sandbox = Birdcage::new();
sandbox.add_exception(Exception::Read("./".into())).unwrap();

Expand Down
3 changes: 2 additions & 1 deletion integration/consistent_id_mappings.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::path::PathBuf;
use birdcage::{Birdcage, Sandbox};
use serde::{Deserialize, Serialize};

Expand All @@ -11,7 +12,7 @@ struct TestData {
egid: u32,
}

pub fn setup() -> TestSetup {
pub fn setup(_tempdir: PathBuf) -> TestSetup {
let uid = unsafe { libc::getuid() };
let gid = unsafe { libc::getgid() };
let euid = unsafe { libc::geteuid() };
Expand Down
3 changes: 2 additions & 1 deletion integration/delete_before_lockdown.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use std::path::PathBuf;

use birdcage::{Birdcage, Exception, Sandbox};
use tempfile::NamedTempFile;

use crate::TestSetup;

pub fn setup() -> TestSetup {
pub fn setup(_tempdir: PathBuf) -> TestSetup {
// Create temporary file.
let tempfile = NamedTempFile::new().unwrap();

Expand Down
3 changes: 2 additions & 1 deletion integration/env.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use std::path::PathBuf;
use std::env;

use birdcage::{Birdcage, Exception, Sandbox};

use crate::TestSetup;

pub fn setup() -> TestSetup {
pub fn setup(_tempdir: PathBuf) -> TestSetup {
// Setup our environment variables
env::set_var("PUBLIC", "GOOD");
env::set_var("PRIVATE", "BAD");
Expand Down
3 changes: 2 additions & 1 deletion integration/exec.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use std::path::PathBuf;
use std::fs;
use std::process::Command;

use birdcage::{Birdcage, Exception, Sandbox};

use crate::TestSetup;

pub fn setup() -> TestSetup {
pub fn setup(_tempdir: PathBuf) -> TestSetup {
let mut sandbox = Birdcage::new();
sandbox.add_exception(Exception::ExecuteAndRead("/usr/bin/true".into())).unwrap();

Expand Down
3 changes: 1 addition & 2 deletions integration/exec_symlinked_dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ struct TestData {
symlink_dir: PathBuf,
}

pub fn setup() -> TestSetup {
pub fn setup(tempdir: PathBuf) -> TestSetup {
// Create symlinked executable dir.
let tempdir = tempfile::tempdir().unwrap().into_path();
let symlink_dir = tempdir.join("bin");
unixfs::symlink("/usr/bin", &symlink_dir).unwrap();

Expand Down
3 changes: 1 addition & 2 deletions integration/exec_symlinked_dirs_exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ struct TestData {
symlink_dir_exec: PathBuf,
}

pub fn setup() -> TestSetup {
pub fn setup(tempdir: PathBuf) -> TestSetup {
// Create symlinked executable dir.
let tempdir = tempfile::tempdir().unwrap().into_path();
let symlink_dir = tempdir.join("bin");
let symlink_dir_exec = symlink_dir.join("true");
unixfs::symlink("/usr/bin", &symlink_dir).unwrap();
Expand Down
3 changes: 1 addition & 2 deletions integration/exec_symlinked_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ struct TestData {
symlink_exec: PathBuf,
}

pub fn setup() -> TestSetup {
pub fn setup(tempdir: PathBuf) -> TestSetup {
// Create symlinked executable.
let tempdir = tempfile::tempdir().unwrap().into_path();
let exec_dir = tempdir.join("bin");
fs::create_dir(&exec_dir).unwrap();
let symlink_exec = exec_dir.join("true");
Expand Down
7 changes: 3 additions & 4 deletions integration/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use std::path::PathBuf;

use birdcage::{Birdcage, Exception, Sandbox};
use serde::{Deserialize, Serialize};
use tempfile::NamedTempFile;

use crate::TestSetup;

Expand All @@ -15,11 +14,11 @@ struct TestData {
private_path: PathBuf,
}

pub fn setup() -> TestSetup {
pub fn setup(tempdir: PathBuf) -> TestSetup {
// Setup our test files.
let private_path = NamedTempFile::new().unwrap().into_temp_path().keep().unwrap();
let private_path = tempdir.join("private");
fs::write(&private_path, FILE_CONTENT.as_bytes()).unwrap();
let public_path = NamedTempFile::new().unwrap().into_temp_path().keep().unwrap();
let public_path = tempdir.join("public");
fs::write(&public_path, FILE_CONTENT.as_bytes()).unwrap();

// Setup sandbox exceptions.
Expand Down
21 changes: 12 additions & 9 deletions integration/fs_broken_symlink.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use std::fs;
use std::fs::{self, File};
use std::os::unix::fs as unixfs;
use std::path::PathBuf;

use birdcage::error::Error;
use birdcage::{Birdcage, Exception, Sandbox};
use serde::{Deserialize, Serialize};
use tempfile::NamedTempFile;

use crate::TestSetup;

Expand All @@ -14,14 +13,18 @@ struct TestData {
symlink: PathBuf,
}

pub fn setup() -> TestSetup {
// Setup a symlink without target.
let tempfile = NamedTempFile::new().unwrap();
let tempfile_path = tempfile.path().to_path_buf();
let symlink_str = tempfile_path.to_string_lossy() + "_tmpfile";
pub fn setup(tempdir: PathBuf) -> TestSetup {
// Create a target for the symlink.
let tempfile_path = tempdir.join("broken_target");
File::create(&tempfile_path).unwrap();

// Setup a symlink to the target file.
let symlink_str = tempfile_path.to_string_lossy() + "_symlink";
let symlink = PathBuf::from(symlink_str.as_ref());
unixfs::symlink(&tempfile, &symlink).unwrap();
drop(tempfile);
unixfs::symlink(&tempfile_path, &symlink).unwrap();

// Remove the target, breaking the symlink.
fs::remove_file(&tempfile_path).unwrap();
assert!(!tempfile_path.exists());

// Sandbox exception fails with invalid path error.
Expand Down
3 changes: 2 additions & 1 deletion integration/fs_null.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use std::path::PathBuf;
use std::fs;

use birdcage::{Birdcage, Exception, Sandbox};

use crate::TestSetup;

pub fn setup() -> TestSetup {
pub fn setup(_tempdir: PathBuf) -> TestSetup {
// Activate our sandbox.
let mut sandbox = Birdcage::new();
sandbox.add_exception(Exception::WriteAndRead("/dev/null".into())).unwrap();
Expand Down
5 changes: 2 additions & 3 deletions integration/fs_readonly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use std::path::PathBuf;

use birdcage::{Birdcage, Exception, Sandbox};
use serde::{Deserialize, Serialize};
use tempfile::NamedTempFile;

use crate::TestSetup;

Expand All @@ -14,9 +13,9 @@ struct TestData {
file: PathBuf,
}

pub fn setup() -> TestSetup {
pub fn setup(tempdir: PathBuf) -> TestSetup {
// Setup the test file.
let file = NamedTempFile::new().unwrap().into_temp_path().keep().unwrap();
let file = tempdir.join("fs_readonly");
fs::write(&file, FILE_CONTENT.as_bytes()).unwrap();

// Activate our sandbox.
Expand Down
3 changes: 1 addition & 2 deletions integration/fs_restrict_child.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ struct TestData {
tempdir: PathBuf,
}

pub fn setup() -> TestSetup {
pub fn setup(tempdir: PathBuf) -> TestSetup {
// Setup our test tree.
let tempdir = tempfile::tempdir().unwrap().into_path();
let tempfile = tempdir.join("target-file");
fs::write(&tempfile, FILE_CONTENT.as_bytes()).unwrap();

Expand Down
7 changes: 3 additions & 4 deletions integration/fs_symlink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use std::path::PathBuf;

use birdcage::{Birdcage, Exception, Sandbox};
use serde::{Deserialize, Serialize};
use tempfile::NamedTempFile;

use crate::TestSetup;

Expand All @@ -16,11 +15,11 @@ struct TestData {
public: PathBuf,
}

pub fn setup() -> TestSetup {
pub fn setup(tempdir: PathBuf) -> TestSetup {
// Setup our test files.
let private_path = NamedTempFile::new().unwrap().into_temp_path().keep().unwrap();
let private_path = tempdir.join("private");
fs::write(&private_path, FILE_CONTENT.as_bytes()).unwrap();
let public_path = NamedTempFile::new().unwrap().into_temp_path().keep().unwrap();
let public_path = tempdir.join("public");
fs::write(&public_path, FILE_CONTENT.as_bytes()).unwrap();

// Create symlinks for the files.
Expand Down
19 changes: 9 additions & 10 deletions integration/fs_symlink_dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,29 @@ use std::path::PathBuf;

use birdcage::{Birdcage, Exception, Sandbox};
use serde::{Deserialize, Serialize};
use tempfile::TempDir;

use crate::TestSetup;

const FILE_CONTENT: &str = "expected content";

#[derive(Serialize, Deserialize)]
struct TestData {
symlink_path: PathBuf,
symlink: PathBuf,
}

pub fn setup() -> TestSetup {
pub fn setup(tempdir: PathBuf) -> TestSetup {
// Setup our test directory.
let tempdir = TempDir::new().unwrap().into_path();
let symlink_str = tempdir.to_string_lossy() + "_tmpfile";
let symlink_path = PathBuf::from(symlink_str.as_ref());
unixfs::symlink(&tempdir, &symlink_path).unwrap();
let symlink_target = tempdir.join("target");
fs::create_dir(symlink_target).unwrap();
let symlink = tempdir.join("symlink");
unixfs::symlink(&tempdir, &symlink).unwrap();

// Activate our sandbox.
let mut sandbox = Birdcage::new();
sandbox.add_exception(Exception::WriteAndRead(symlink_path.clone())).unwrap();
sandbox.add_exception(Exception::WriteAndRead(symlink.clone())).unwrap();

// Serialize test data.
let data = TestData { symlink_path };
let data = TestData { symlink };
let data = serde_json::to_string(&data).unwrap();

TestSetup { sandbox, data }
Expand All @@ -38,7 +37,7 @@ pub fn validate(data: String) {
let data: TestData = serde_json::from_str(&data).unwrap();

// Try to create a file in the symlinked directory.
let path = data.symlink_path.join("tmpfile");
let path = data.symlink.join("tmpfile");
fs::write(&path, FILE_CONTENT.as_bytes()).unwrap();
let content = fs::read_to_string(&path).unwrap();
assert_eq!(content, FILE_CONTENT);
Expand Down
4 changes: 1 addition & 3 deletions integration/fs_symlink_dir_separate_perms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use std::path::PathBuf;

use birdcage::{Birdcage, Exception, Sandbox};
use serde::{Deserialize, Serialize};
use tempfile::TempDir;

use crate::TestSetup;

Expand All @@ -15,9 +14,8 @@ struct TestData {
symlink_src: PathBuf,
}

pub fn setup() -> TestSetup {
pub fn setup(tempdir: PathBuf) -> TestSetup {
// Setup our test directories.
let tempdir = TempDir::new().unwrap().into_path();
let symlink_src = tempdir.join("src");
fs::create_dir(&symlink_src).unwrap();
let symlink_dst = tempdir.join("dst");
Expand Down
18 changes: 9 additions & 9 deletions integration/fs_write_also_read.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
use std::fs;
use std::fs::{self, File};
use std::path::PathBuf;

use birdcage::{Birdcage, Exception, Sandbox};
use serde::{Deserialize, Serialize};
use tempfile::NamedTempFile;

use crate::TestSetup;

const FILE_CONTENT: &str = "expected content";

#[derive(Serialize, Deserialize)]
struct TestData {
file: PathBuf,
path: PathBuf,
}

pub fn setup() -> TestSetup {
pub fn setup(tempdir: PathBuf) -> TestSetup {
// Setup our test files.
let file = NamedTempFile::new().unwrap().into_temp_path().keep().unwrap();
let path = tempdir.join("fs_write_also_read");
File::create(&path).unwrap();

// Activate our sandbox.
let mut sandbox = Birdcage::new();
sandbox.add_exception(Exception::WriteAndRead(file.clone())).unwrap();
sandbox.add_exception(Exception::WriteAndRead(path.clone())).unwrap();

// Serialize test data.
let data = TestData { file };
let data = TestData { path };
let data = serde_json::to_string(&data).unwrap();

TestSetup { sandbox, data }
Expand All @@ -34,9 +34,9 @@ pub fn validate(data: String) {
let data: TestData = serde_json::from_str(&data).unwrap();

// Write access is allowed.
fs::write(&data.file, FILE_CONTENT.as_bytes()).unwrap();
fs::write(&data.path, FILE_CONTENT.as_bytes()).unwrap();

// Read access is allowed.
let content = fs::read_to_string(data.file).unwrap();
let content = fs::read_to_string(data.path).unwrap();
assert_eq!(content, FILE_CONTENT);
}
3 changes: 2 additions & 1 deletion integration/full_env.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use std::path::PathBuf;
use std::env;

use birdcage::{Birdcage, Exception, Sandbox};

use crate::TestSetup;

pub fn setup() -> TestSetup {
pub fn setup(_tempdir: PathBuf) -> TestSetup {
// Setup our environment variables
env::set_var("PUBLIC", "GOOD");

Expand Down
5 changes: 2 additions & 3 deletions integration/full_sandbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use std::{env, fs};

use birdcage::{Birdcage, Sandbox};
use serde::{Deserialize, Serialize};
use tempfile::NamedTempFile;

use crate::TestSetup;

Expand All @@ -14,11 +13,11 @@ struct TestData {
path: PathBuf,
}

pub fn setup() -> TestSetup {
pub fn setup(tempdir: PathBuf) -> TestSetup {
const FILE_CONTENT: &str = "expected content";

// Create testfile.
let path = NamedTempFile::new().unwrap().into_temp_path().keep().unwrap();
let path = tempdir.join("full_sandbox");

// Ensure non-sandboxed write works.
fs::write(&path, FILE_CONTENT.as_bytes()).unwrap();
Expand Down
Loading

0 comments on commit a3f96bb

Please sign in to comment.