summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Bridle <ben@derelict.engineering>2025-07-07 21:49:48 +1200
committerBen Bridle <ben@derelict.engineering>2025-07-07 21:49:48 +1200
commita702893fd1e1e59b5bfc770c5088120e8c3ece56 (patch)
treeab0d40be922c47d053367f32b15d3e8fc16f005f
parent0d9bfa0731259edfe9496e90c7f41820442cb130 (diff)
downloadbedrock-pc-a702893fd1e1e59b5bfc770c5088120e8c3ece56.zip
Sandbox the file device
Unless the --trust-files switch is used, the file device will be sandboxed to a program-specific config folder placed according to the conventions of the operating system.
-rw-r--r--Cargo.lock79
-rw-r--r--Cargo.toml2
-rw-r--r--src/bin/br/main.rs20
-rw-r--r--src/devices/file_device.rs31
-rw-r--r--src/emulators/graphical_emulator.rs2
-rw-r--r--src/emulators/headless_emulator.rs2
-rw-r--r--src/emulators/mod.rs3
7 files changed, 125 insertions, 14 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 288668e..4050f85 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -9,7 +9,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
dependencies = [
"cfg-if",
- "getrandom",
+ "getrandom 0.3.3",
"once_cell",
"version_check",
"zerocopy",
@@ -108,12 +108,14 @@ dependencies = [
"bedrock-asm",
"bedrock-core",
"chrono",
+ "dirs-next",
"geometry",
"gilrs",
"inked",
"log 2.0.0",
"phosphor",
"switchboard",
+ "vagabond",
"windows 0.58.0",
]
@@ -368,6 +370,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f"
[[package]]
+name = "dirs-next"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf36e65a80337bea855cd4ef9b8401ffce06a7baedf2e85ec467b1ac3f6e82b6"
+dependencies = [
+ "cfg-if",
+ "dirs-sys-next",
+]
+
+[[package]]
+name = "dirs-sys-next"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
+dependencies = [
+ "libc",
+ "redox_users",
+ "winapi",
+]
+
+[[package]]
name = "dispatch"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -510,6 +533,17 @@ dependencies = [
[[package]]
name = "getrandom"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi 0.11.1+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "getrandom"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
@@ -517,7 +551,7 @@ dependencies = [
"cfg-if",
"libc",
"r-efi",
- "wasi",
+ "wasi 0.14.2+wasi-0.2.4",
]
[[package]]
@@ -666,7 +700,7 @@ version = "0.1.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a"
dependencies = [
- "getrandom",
+ "getrandom 0.3.3",
"libc",
]
@@ -1212,6 +1246,17 @@ dependencies = [
]
[[package]]
+name = "redox_users"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
+dependencies = [
+ "getrandom 0.2.16",
+ "libredox",
+ "thiserror",
+]
+
+[[package]]
name = "rustix"
version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1508,6 +1553,12 @@ dependencies = [
[[package]]
name = "wasi"
+version = "0.11.1+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
+
+[[package]]
+name = "wasi"
version = "0.14.2+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
@@ -1716,6 +1767,22 @@ dependencies = [
]
[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
name = "winapi-util"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1725,6 +1792,12 @@ dependencies = [
]
[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
name = "windows"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 8309a1f..bfec877 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,9 +13,11 @@ geometry = { git = "git://benbridle.com/geometry", tag = "v1.0.0" }
inked = { git = "git://benbridle.com/inked", tag = "v1.0.0" }
log = { git = "git://benbridle.com/log", tag = "v2.0.0" }
switchboard = { git = "git://benbridle.com/switchboard", tag = "v2.1.0" }
+vagabond = { git = "git://benbridle.com/vagabond", tag = "v1.1.1" }
chrono = { version = "0.4.38" }
gilrs = "0.11.0"
+dirs-next = "1.0.2"
[target.'cfg(target_os = "windows")'.dependencies]
windows = { version = "0.58.0", features = ["Win32_Storage_FileSystem"] }
diff --git a/src/bin/br/main.rs b/src/bin/br/main.rs
index 81c5ec9..f4d79fa 100644
--- a/src/bin/br/main.rs
+++ b/src/bin/br/main.rs
@@ -55,6 +55,7 @@ fn main() {
args.named("size").short('s');
args.named("decode-stdin").short('i');
args.named("encode-stdout").short('o');
+ args.named("trust-files");
args.raise_errors();
let source = args.get("source").as_path_opt();
@@ -71,6 +72,7 @@ fn main() {
};
let decode_stdin = args.get("decode-stdin").as_bool();
let encode_stdout = args.get("encode-stdout").as_bool();
+ let trust_files = args.get("trust-files").as_bool();
// -----------------------------------------------------------------------
@@ -78,7 +80,9 @@ fn main() {
let mut title = String::from("Bedrock program");
let mut icon = None;
- if let Some(metadata) = Metadata::from(&bytecode) {
+ let metadata = Metadata::from(&bytecode);
+
+ if let Some(ref metadata) = metadata {
let name = metadata.name().unwrap_or("unnamed".to_string());
let authors = metadata.authors().unwrap_or_else(Vec::new);
let mut metadata_string = format!("Program is '{name}'");
@@ -110,10 +114,20 @@ fn main() {
path.add_extension("sym"); path
});
+ let name = metadata.and_then(|m| m.name()).and_then(|n| match n.split_once('/') {
+ Some((name, _)) => Some(name.to_string()),
+ None => Some(n),
+ });
+ let identifier = name.as_ref().and_then(
+ |n| Some(n.to_lowercase().chars().filter_map(
+ |c| c.is_alphanumeric().then_some(c)
+ ).collect())
+ );
+
let config = EmulatorConfig {
dimensions, fullscreen, zoom, palette, show_cursor,
- decode_stdin, encode_stdout,
- symbols_path, title, icon,
+ decode_stdin, encode_stdout, trust_files,
+ symbols_path, name, identifier, title, icon,
};
if let Ok(phosphor) = Phosphor::new() {
diff --git a/src/devices/file_device.rs b/src/devices/file_device.rs
index ff5629b..43bb239 100644
--- a/src/devices/file_device.rs
+++ b/src/devices/file_device.rs
@@ -16,6 +16,7 @@ pub struct FileDevice {
pub pointer_write: u32,
pub length_write: u32,
+ pub enable: bool,
pub enable_read: bool,
pub enable_write: bool,
pub enable_create: bool,
@@ -26,6 +27,7 @@ pub struct FileDevice {
impl Device for FileDevice {
fn read(&mut self, port: u8) -> u8 {
+ if !self.enable { return 0x00; }
match port {
0x0 => read_b!(self.entry.is_some()),
0x1 => read_b!(self.success),
@@ -48,6 +50,7 @@ impl Device for FileDevice {
}
fn write(&mut self, port: u8, value: u8) -> Option<Signal> {
+ if !self.enable { return None; }
match port {
0x0 => self.write_to_entry_port(value),
0x1 => self.write_to_action_port(value),
@@ -81,20 +84,35 @@ impl Device for FileDevice {
impl FileDevice {
- pub fn new() -> Self {
+ pub fn new(config: &EmulatorConfig) -> Self {
#[cfg(target_family = "unix")]
let default_base: PathBuf = PathBuf::from("/");
#[cfg(target_family = "windows")]
let default_base: PathBuf = PathBuf::from("");
+ let current_dir = match std::env::current_dir() {
+ Ok(dir) => PathBuf::from(dir),
+ Err(_) => PathBuf::from(""),
+ };
+
+ let (enable, base_path, default_path) = if config.trust_files {
+ (true, default_base, current_dir)
+ } else if let Some(config_dir) = dirs_next::config_dir() {
+ let bedrock_dir = config_dir.join("bedrock");
+ let identifier = config.identifier.clone().unwrap_or("default".to_string());
+ let sandbox_dir = bedrock_dir.join(identifier);
+ vagabond::make_directory(&sandbox_dir).unwrap();
+ (true, sandbox_dir.clone(), sandbox_dir)
+ } else {
+ error!("Could not determine sandbox path for file device");
+ (false, default_base, current_dir)
+ };
+
// TODO: I'm not at all confident that the default path is correct
// when not being set as the current directory.
Self {
- base_path: default_base,
- default_path: match std::env::current_dir() {
- Ok(dir) => PathBuf::from(dir),
- Err(_) => PathBuf::from(""),
- },
+ base_path,
+ default_path,
entry_buffer: BedrockPathBuffer::new(),
action_buffer: BedrockPathBuffer::new(),
@@ -107,6 +125,7 @@ impl FileDevice {
pointer_write: 0,
length_write: 0,
+ enable,
enable_read: true,
enable_write: true,
enable_create: true,
diff --git a/src/emulators/graphical_emulator.rs b/src/emulators/graphical_emulator.rs
index 2680d3f..03e3057 100644
--- a/src/emulators/graphical_emulator.rs
+++ b/src/emulators/graphical_emulator.rs
@@ -112,7 +112,7 @@ impl GraphicalDeviceBus {
input: InputDevice::new(),
screen: ScreenDevice::new(&config),
stream: StreamDevice::new(&config),
- file: FileDevice::new(),
+ file: FileDevice::new(&config),
wake_queue: WakeQueue::new(),
}
}
diff --git a/src/emulators/headless_emulator.rs b/src/emulators/headless_emulator.rs
index cac58cf..770bae3 100644
--- a/src/emulators/headless_emulator.rs
+++ b/src/emulators/headless_emulator.rs
@@ -70,7 +70,7 @@ impl HeadlessDeviceBus {
math: MathDevice::new(),
clock: ClockDevice::new(),
stream: StreamDevice::new(&config),
- file: FileDevice::new(),
+ file: FileDevice::new(&config),
wake_queue: WakeQueue::new(),
}
}
diff --git a/src/emulators/mod.rs b/src/emulators/mod.rs
index 8f04e4d..d4a58f9 100644
--- a/src/emulators/mod.rs
+++ b/src/emulators/mod.rs
@@ -15,7 +15,10 @@ pub struct EmulatorConfig {
pub show_cursor: bool,
pub decode_stdin: bool,
pub encode_stdout: bool,
+ pub trust_files: bool,
pub symbols_path: Option<PathBuf>,
+ pub name: Option<String>,
+ pub identifier: Option<String>,
pub title: String,
pub icon: Option<Icon>,
}