From 765d6a291a063a095b2db35a7b4d466204420496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Kijewski?= Date: Thu, 15 Jun 2023 18:33:53 +0200 Subject: [PATCH] Implement for aarch64 This PR is based on by [Aaron Dewes](mailto:aaron.dewes@protonmail.com). --- README.md | 2 +- src/builtins/basic.rs | 1 + src/builtins/danger_zone.rs | 14 +++++++++---- src/builtins/network.rs | 22 +++++++++++++++----- src/builtins/systemio.rs | 40 +++++++++++++++++++++++++++---------- src/lib.rs | 9 +++++---- 6 files changed, 64 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index c6ecca9..cf91621 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ If you're developing a library, there are three things you can do: You don't want to use extrasafe directly in your library because you don't know what other functionality your dependents will be using. -**Currently extrasafe only supports `x86_64`. If you'd like to help support other archs please open an issue.** +**Currently extrasafe only supports `x86_64` and `aarch64`. If you'd like to help support other archs please open an issue.** ## Other uses diff --git a/src/builtins/basic.rs b/src/builtins/basic.rs index a7aaaf2..8022adf 100644 --- a/src/builtins/basic.rs +++ b/src/builtins/basic.rs @@ -44,6 +44,7 @@ impl RuleSet for BasicCapabilities { // Readlink isn't dangerous because you still need to be able to open the file to do // anything with the resolved name. + #[cfg(target_arch = "x86_64")] Sysno::readlink, // Getpid/tid is fine. diff --git a/src/builtins/danger_zone.rs b/src/builtins/danger_zone.rs index 837ce87..5172ce8 100644 --- a/src/builtins/danger_zone.rs +++ b/src/builtins/danger_zone.rs @@ -93,10 +93,16 @@ pub struct ForkAndExec; impl RuleSet for ForkAndExec { fn simple_rules(&self) -> Vec { vec![ - Sysno::fork, Sysno::vfork, - Sysno::execve, Sysno::execveat, - Sysno::wait4, Sysno::waitid, - Sysno::clone, Sysno::clone3, + #[cfg(target_arch = "x86_64")] + Sysno::fork, + #[cfg(target_arch = "x86_64")] + Sysno::vfork, + Sysno::execve, + Sysno::execveat, + Sysno::wait4, + Sysno::waitid, + Sysno::clone, + Sysno::clone3, ] } diff --git a/src/builtins/network.rs b/src/builtins/network.rs index f4e6942..2af3b3b 100644 --- a/src/builtins/network.rs +++ b/src/builtins/network.rs @@ -12,15 +12,27 @@ use crate::{Rule, RuleSet}; // TODO: add io_uring const NET_IO_SYSCALLS: &[Sysno] = &[ - Sysno::epoll_create, Sysno::epoll_create1, - Sysno::epoll_ctl, Sysno::epoll_wait, Sysno::epoll_pwait, Sysno::epoll_pwait2, - Sysno::select, Sysno::pselect6, - Sysno::poll, Sysno::ppoll, + #[cfg(target_arch = "x86_64")] + Sysno::epoll_create, + Sysno::epoll_create1, + Sysno::epoll_ctl, + #[cfg(target_arch = "x86_64")] + Sysno::epoll_wait, + Sysno::epoll_pwait, + Sysno::epoll_pwait2, + #[cfg(target_arch = "x86_64")] + Sysno::select, + Sysno::pselect6, + #[cfg(target_arch = "x86_64")] + Sysno::poll, + Sysno::ppoll, Sysno::accept, Sysno::accept4, // used in reqwest::blocking I guess to notify when blocking reads finish? - Sysno::eventfd, Sysno::eventfd2, + #[cfg(target_arch = "x86_64")] + Sysno::eventfd, + Sysno::eventfd2, // Used to set tcp_nodelay Sysno::fcntl, Sysno::ioctl, diff --git a/src/builtins/systemio.rs b/src/builtins/systemio.rs index 13f19fd..e10ef70 100644 --- a/src/builtins/systemio.rs +++ b/src/builtins/systemio.rs @@ -13,13 +13,30 @@ use super::YesReally; const IO_READ_SYSCALLS: &[Sysno] = &[Sysno::read, Sysno::readv, Sysno::preadv, Sysno::preadv2, Sysno::pread64, Sysno::lseek]; const IO_WRITE_SYSCALLS: &[Sysno] = &[Sysno::write, Sysno::writev, Sysno::pwritev, Sysno::pwritev2, Sysno::pwrite64, Sysno::fsync, Sysno::fdatasync, Sysno::lseek]; -const IO_OPEN_SYSCALLS: &[Sysno] = &[Sysno::open, Sysno::openat, Sysno::openat2]; +const IO_OPEN_SYSCALLS: &[Sysno] = &[ + #[cfg(target_arch = "x86_64")] + Sysno::open, + Sysno::openat, + Sysno::openat2, +]; const IO_IOCTL_SYSCALLS: &[Sysno] = &[Sysno::ioctl, Sysno::fcntl]; // TODO: may want to separate fd-based and filename-based? -const IO_METADATA_SYSCALLS: &[Sysno] = &[Sysno::stat, Sysno::fstat, Sysno::newfstatat, - Sysno::lstat, Sysno::statx, - Sysno::getdents, Sysno::getdents64, - Sysno::getcwd]; +const IO_METADATA_SYSCALLS: &[Sysno] = &[ + #[cfg(target_arch = "x86_64")] + Sysno::stat, + Sysno::fstat, + #[cfg(target_arch = "aarch64")] + Sysno::fstatat, + #[cfg(target_arch = "x86_64")] + Sysno::newfstatat, + #[cfg(target_arch = "x86_64")] + Sysno::lstat, + Sysno::statx, + #[cfg(target_arch = "x86_64")] + Sysno::getdents, + Sysno::getdents64, + Sysno::getcwd, +]; const IO_CLOSE_SYSCALLS: &[Sysno] = &[Sysno::close, Sysno::close_range]; /// A [`RuleSet`] representing syscalls that perform IO - open/close/read/write/seek/stat. @@ -106,11 +123,14 @@ impl SystemIO { const WRITECREATE: u64 = O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_EXCL;// | O_TMPFILE; // flags are the second argument for open but the third for openat - let rule = Rule::new(Sysno::open) - .and_condition(scmp_cmp!($arg1 & WRITECREATE == 0)); - self.custom.entry(Sysno::open) - .or_insert_with(Vec::new) - .push(rule); + #[cfg(target_arch = "x86_64")] + { + let rule = Rule::new(Sysno::open) + .and_condition(scmp_cmp!($arg1 & WRITECREATE == 0)); + self.custom.entry(Sysno::open) + .or_insert_with(Vec::new) + .push(rule); + } let rule = Rule::new(Sysno::openat) .and_condition(scmp_cmp!($arg2 & WRITECREATE == 0)); diff --git a/src/lib.rs b/src/lib.rs index b266c03..771e5c0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -102,10 +102,11 @@ impl SafetyContext { /// [`apply_to_current_thread`](Self::apply_to_current_thread) or /// [`apply_to_all_threads`](Self::apply_to_all_threads) is called. pub fn new() -> SafetyContext { - #[cfg(not(target_arch = "x86_64"))] - { - compile_error!("Extrasafe currently only supports the x86_64 architecture. You will likely see other errors about Sysno enum variants not existing; this is why."); - } + #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] + compile_error!( + "Extrasafe currently only supports the x86_64 and aarch64 architectures. \ + If you'd like to help support other archs please open an issue.", + ); SafetyContext { rules: HashMap::new(),