Files
agent-sandbox/tests/e2e/modes.rs
T
2026-04-25 15:10:42 +02:00

201 lines
5.9 KiB
Rust

use crate::common::*;
#[test]
fn whitelist_hides_home_contents() {
let output = sandbox(&["--whitelist"])
.args(["--", "bash", "-c", "ls ~/Documents 2>&1 || echo hidden"])
.output()
.expect("agent-sandbox binary failed to execute");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout.contains("hidden"),
"expected ~/Documents to be hidden, got: {stdout}"
);
}
#[test]
fn whitelist_sys_is_readable() {
let output = sandbox(&["--whitelist"])
.args(["--", "bash", "-c", "cat /sys/class/net/lo/address"])
.output()
.expect("agent-sandbox binary failed to execute");
let stdout = String::from_utf8_lossy(&output.stdout).trim().to_string();
assert_eq!(
stdout, "00:00:00:00:00:00",
"expected loopback address from /sys, got: {stdout}"
);
}
#[test]
fn blacklist_run_is_tmpfs() {
let output = sandbox(&[])
.args([
"--",
"bash",
"-c",
"touch /run/test_canary 2>&1 && echo WRITABLE || echo BLOCKED",
])
.output()
.expect("agent-sandbox binary failed to execute");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout.contains("WRITABLE"),
"expected /run to be a writable tmpfs in blacklist mode, got: {stdout}"
);
}
#[test]
fn blacklist_run_dbus_socket_accessible() {
let output = sandbox(&[])
.args([
"--",
"bash",
"-c",
"test -e /run/dbus/system_bus_socket && echo EXISTS || echo MISSING",
])
.output()
.expect("agent-sandbox binary failed to execute");
let stdout = String::from_utf8_lossy(&output.stdout).trim().to_string();
assert_eq!(
stdout, "EXISTS",
"expected /run/dbus/system_bus_socket to be accessible in blacklist mode"
);
}
#[test]
fn blacklist_runuser_is_tmpfs() {
let run_user = agent_sandbox::require_run_user().expect("failed to determine XDG_RUNTIME_DIR");
let script = format!("ls -A {} | grep -v '^bus$'", run_user);
let output = sandbox(&[])
.args(["--", "bash", "-c", &script])
.output()
.expect("agent-sandbox binary failed to execute");
let stdout = String::from_utf8_lossy(&output.stdout).trim().to_string();
assert!(
stdout.is_empty(),
"expected only 'bus' (or empty) in {}, got unexpected entries: {stdout}",
run_user
);
}
#[test]
fn blacklist_dev_input_hidden() {
let output = sandbox(&[])
.args(["--", "bash", "-c", "ls /dev/input/ 2>/dev/null | wc -l"])
.output()
.expect("agent-sandbox binary failed to execute");
let stdout = String::from_utf8_lossy(&output.stdout).trim().to_string();
assert_eq!(
stdout, "0",
"expected /dev/input/ to be empty in blacklist mode, got {stdout} entries"
);
}
#[test]
fn blacklist_root_is_readonly() {
let output = sandbox(&[])
.args([
"--",
"bash",
"-c",
"touch /rootfile 2>&1 && echo WRITABLE || echo READONLY; \
mkdir /newdir 2>&1 && echo MKDIR_OK || echo MKDIR_FAIL",
])
.output()
.expect("agent-sandbox binary failed to execute");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout.contains("READONLY"),
"expected root to be read-only in blacklist mode, got: {stdout}"
);
assert!(
stdout.contains("MKDIR_FAIL"),
"expected mkdir at root to fail in blacklist mode, got: {stdout}"
);
}
#[test]
fn whitelist_root_is_readonly() {
let output = sandbox(&["--whitelist"])
.args([
"--",
"bash",
"-c",
"touch /rootfile 2>&1 && echo WRITABLE || echo READONLY; \
mkdir /newdir 2>&1 && echo MKDIR_OK || echo MKDIR_FAIL",
])
.output()
.expect("agent-sandbox binary failed to execute");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout.contains("READONLY"),
"expected root to be read-only in whitelist mode, got: {stdout}"
);
assert!(
stdout.contains("MKDIR_FAIL"),
"expected mkdir at root to fail in whitelist mode, got: {stdout}"
);
}
#[test]
fn whitelist_mountpoint_parents_are_readonly() {
let output = sandbox(&["--whitelist"])
.args([
"--",
"bash",
"-c",
"echo pwned > /home/testfile 2>&1 && echo HOME_WRITABLE || echo HOME_READONLY; \
touch /etc/newfile 2>&1 && echo ETC_WRITABLE || echo ETC_READONLY; \
touch /var/newfile 2>&1 && echo VAR_WRITABLE || echo VAR_READONLY",
])
.output()
.expect("agent-sandbox binary failed to execute");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout.contains("HOME_READONLY"),
"expected /home to be read-only in whitelist mode, got: {stdout}"
);
assert!(
stdout.contains("ETC_READONLY"),
"expected /etc to be read-only in whitelist mode, got: {stdout}"
);
assert!(
stdout.contains("VAR_READONLY"),
"expected /var to be read-only in whitelist mode, got: {stdout}"
);
}
#[test]
fn whitelist_tmp_still_writable() {
let output = sandbox(&["--whitelist"])
.args([
"--",
"bash",
"-c",
"touch /tmp/ok 2>&1 && echo TMP_WRITABLE || echo TMP_READONLY; \
touch /var/tmp/ok 2>&1 && echo VARTMP_WRITABLE || echo VARTMP_READONLY",
])
.output()
.expect("agent-sandbox binary failed to execute");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout.contains("TMP_WRITABLE"),
"expected /tmp to remain writable in whitelist mode, got: {stdout}"
);
assert!(
stdout.contains("VARTMP_WRITABLE"),
"expected /var/tmp to remain writable in whitelist mode, got: {stdout}"
);
}