### Define and Install Seccomp Filter from JSON Source: https://docs.rs/seccompiler/0.5.0/src/seccompiler/lib.rs.html This example demonstrates defining and installing a seccomp filter using a JSON input. It requires the 'json' feature to be enabled. The JSON specifies rules for the main thread, including mismatch and match actions, and specific syscall filters. ```rust use seccompiler::BpfMap; use std::convert::TryInto; let json_input = r#"{ "main_thread": { "mismatch_action": "allow", "match_action": "trap", "filter": [ { "syscall": "accept4" }, { "syscall": "fcntl", "args": [ { "index": 1, "type": "dword", "op": "eq", "val": 2, "comment": "F_SETFD" }, { "index": 2, "type": "dword", "op": "eq", "val": 1, "comment": "FD_CLOEXEC" } ] }, { "syscall": "fcntl", "args": [ { "index": 1, "type": "dword", "op": "eq", "val": 1, "comment": "F_GETFD" } ] } ] } }"#; let filter_map: BpfMap = seccompiler::compile_from_json( json_input.as_bytes(), std::env::consts::ARCH.try_into().unwrap(), ) .unwrap(); let filter = filter_map.get("main_thread").unwrap(); seccompiler::apply_filter(&filter).unwrap(); ``` -------------------------------- ### JSON Seccomp Filter Example Source: https://docs.rs/seccompiler/0.5.0/seccompiler This example defines and installs an equivalent JSON filter (uses the `json` feature). It achieves the same result as the Rust code example but uses a JSON configuration. ```APIDOC ## JSON Seccomp Filter Example This second example defines and installs an equivalent JSON filter (uses the `json` feature): ```json { "main_thread": { "mismatch_action": "allow", "match_action": "trap", "filter": [ { "syscall": "accept4" }, { "syscall": "fcntl", "args": [ { "index": 1, "type": "dword", "op": "eq", "val": 2, "comment": "F_SETFD" }, { "index": 2, "type": "dword", "op": "eq", "val": 1, "comment": "FD_CLOEXEC" } ] }, { "syscall": "fcntl", "args": [ { "index": 1, "type": "dword", "op": "eq", "val": 1, "comment": "F_GETFD" } ] } ] } } ``` ```rust use seccompiler::BpfMap; use std::convert::TryInto; let json_input = r#"{ "main_thread": { "mismatch_action": "allow", "match_action": "trap", "filter": [ { "syscall": "accept4" }, { "syscall": "fcntl", "args": [ { "index": 1, "type": "dword", "op": "eq", "val": 2, "comment": "F_SETFD" }, { "index": 2, "type": "dword", "op": "eq", "val": 1, "comment": "FD_CLOEXEC" } ] }, { "syscall": "fcntl", "args": [ { "index": 1, "type": "dword", "op": "eq", "val": 1, "comment": "F_GETFD" } ] } ] } }"#; let filter_map: BpfMap = seccompiler::compile_from_json( json_input.as_bytes(), std::env::consts::ARCH.try_into().unwrap(), ) .unwrap(); let filter = filter_map.get("main_thread").unwrap(); seccompiler::apply_filter(&filter).unwrap(); ``` ``` -------------------------------- ### Rust Seccomp Filter Example Source: https://docs.rs/seccompiler/0.5.0/seccompiler This example defines and installs a simple Rust filter that sends SIGSYS for `accept4`, `fcntl(any, F_SETFD, FD_CLOEXEC, ..)` and `fcntl(any, F_GETFD, ...)`. It allows any other syscalls. ```APIDOC ## Rust Seccomp Filter Example This example defines and installs a simple Rust filter that sends SIGSYS for `accept4`, `fcntl(any, F_SETFD, FD_CLOEXEC, ..)` and `fcntl(any, F_GETFD, ...)`. It allows any other syscalls. ```rust use seccompiler::{ BpfProgram, SeccompAction, SeccompCmpArgLen, SeccompCmpOp, SeccompCondition, SeccompFilter, SeccompRule, }; use std::convert::TryInto; let filter: BpfProgram = SeccompFilter::new( vec![ (libc::SYS_accept4, vec![]), ( libc::SYS_fcntl, vec![ SeccompRule::new(vec![SeccompCondition::new( 1, SeccompCmpArgLen::Dword, SeccompCmpOp::Eq, libc::F_SETFD as u64, ).unwrap()) .unwrap(), SeccompRule::new(vec![SeccompCondition::new( 2, SeccompCmpArgLen::Dword, SeccompCmpOp::Eq, libc::FD_CLOEXEC as u64, ).unwrap()]) .unwrap(), SeccompRule::new(vec![SeccompCondition::new( 1, SeccompCmpArgLen::Dword, SeccompCmpOp::Eq, libc::F_GETFD as u64, ).unwrap()]) .unwrap(), ], ), ] .into_iter() .collect(), SeccompAction::Allow, SeccompAction::Trap, std::env::consts::ARCH.try_into().unwrap(), ) .unwrap() .try_into() .unwrap(); seccompiler::apply_filter(&filter).unwrap(); ``` ``` -------------------------------- ### Define and Install a Rust Seccomp Filter Source: https://docs.rs/seccompiler/0.5.0/src/seccompiler/lib.rs.html This example demonstrates how to define a seccomp filter using Rust code. It sets up rules to trap specific `fcntl` calls and allow all other syscalls. Ensure necessary imports are present. ```rust use seccompiler::{ BpfProgram, SeccompAction, SeccompCmpArgLen, SeccompCmpOp, SeccompCondition, SeccompFilter, SeccompRule, }; use std::convert::TryInto; let filter: BpfProgram = SeccompFilter::new( vec![ (libc::SYS_accept4, vec![]), ( libc::SYS_fcntl, vec![ SeccompRule::new(vec![ SeccompCondition::new( 1, SeccompCmpArgLen::Dword, SeccompCmpOp::Eq, libc::F_SETFD as u64, ) .unwrap(), SeccompCondition::new( 2, SeccompCmpArgLen::Dword, SeccompCmpOp::Eq, libc::FD_CLOEXEC as u64, ) .unwrap(), ]) .unwrap(), SeccompRule::new(vec![SeccompCondition::new( 1, SeccompCmpArgLen::Dword, SeccompCmpOp::Eq, libc::F_GETFD as u64, ) .unwrap()]) .unwrap(), ], ), ] .into_iter() .collect(), SeccompAction::Allow, SeccompAction::Trap, ``` -------------------------------- ### GET /HashMap/default Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.BpfMap.html Creates an empty HashMap with the default hasher. ```APIDOC ## GET /HashMap/default ### Description Creates an empty `HashMap`, with the `Default` value for the hasher. ### Method GET ### Endpoint /HashMap/default ### Response #### Success Response (200) - **HashMap** (object) - An empty HashMap instance. ``` -------------------------------- ### Apply Seccomp Filter from BPF Program Source: https://docs.rs/seccompiler/0.5.0/src/seccompiler/lib.rs.html This example shows how to apply a seccomp filter directly from a BPF program. Ensure the BPF program is correctly compiled before applying. ```rust # #[cfg(feature = "json")] # { use seccompiler::BpfMap; use std::convert::TryInto; let json_input = r#"{ "main_thread": { "mismatch_action": "allow", "match_action": "trap", "filter": [ { "syscall": "accept4" }, { "syscall": "fcntl", "args": [ { "index": 1, "type": "dword", "op": "eq", "val": 2, "comment": "F_SETFD" }, { "index": 2, "type": "dword", "op": "eq", "val": 1, "comment": "FD_CLOEXEC" } ] }, { "syscall": "fcntl", "args": [ { "index": 1, "type": "dword", "op": "eq", "val": 1, "comment": "F_GETFD" } ] } ] } }"#; let filter_map: BpfMap = seccompiler::compile_from_json( json_input.as_bytes(), std::env::consts::ARCH.try_into().unwrap(), ) .unwrap(); let filter = filter_map.get("main_thread").unwrap(); seccompiler::apply_filter(&filter).unwrap(); # } ``` -------------------------------- ### Define and Install Seccomp Filter from JSON Source: https://docs.rs/seccompiler/0.5.0/index.html This snippet demonstrates how to define a seccomp filter using a JSON configuration, which is useful for externalizing filter definitions. It requires the `json` feature to be enabled for the seccompiler crate. ```rust use seccompiler::BpfMap; use std::convert::TryInto; let json_input = r#"{ "main_thread": { "mismatch_action": "allow", "match_action": "trap", "filter": [ { "syscall": "accept4" }, { "syscall": "fcntl", "args": [ { "index": 1, "type": "dword", "op": "eq", "val": 2, "comment": "F_SETFD" }, { "index": 2, "type": "dword", "op": "eq", "val": 1, "comment": "FD_CLOEXEC" } ] }, { "syscall": "fcntl", "args": [ { "index": 1, "type": "dword", "op": "eq", "val": 1, "comment": "F_GETFD" } ] } ] } }"#; let filter_map: BpfMap = seccompiler::compile_from_json( json_input.as_bytes(), std::env::consts::ARCH.try_into().unwrap(), ) .unwrap(); let filter = filter_map.get("main_thread").unwrap(); seccompiler::apply_filter(&filter).unwrap(); ``` -------------------------------- ### Apply BPF Filter to Thread Source: https://docs.rs/seccompiler/0.5.0/seccompiler/fn.apply_filter.html Installs a BPF filter for the calling thread. Ensure the BpfProgramRef is valid before calling. ```rust pub fn apply_filter(bpf_filter: BpfProgramRef<'_>) -> Result<()> ``` -------------------------------- ### Get a value from HashMap Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.BpfMap.html Use `get` to retrieve a reference to a value associated with a key. The key can be a borrowed form, but must implement `Hash` and `Eq`. ```rust use std::collections::HashMap; let mut map = HashMap::new(); map.insert(1, "a"); assert_eq!(map.get(&1), Some(&"a")); assert_eq!(map.get(&2), None); ``` -------------------------------- ### Deallocating Vec with ManuallyDrop Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.BpfProgram.html Example of manually deallocating a vector's backing memory using Box. ```rust use std::mem::{ManuallyDrop, MaybeUninit}; let mut v = ManuallyDrop::new(vec![0, 1, 2]); let ptr = v.as_mut_ptr(); let capacity = v.capacity(); let slice_ptr: *mut [MaybeUninit] = std::ptr::slice_from_raw_parts_mut(ptr.cast(), capacity); drop(unsafe { Box::from_raw(slice_ptr) }); ``` -------------------------------- ### Apply BPF Filter to Calling Thread Source: https://docs.rs/seccompiler/0.5.0/src/seccompiler/lib.rs.html Installs a BPF filter to the calling thread. Ensure the BpfProgram is valid before calling. ```rust pub fn apply_filter(bpf_filter: BpfProgramRef) -> Result<()> ``` -------------------------------- ### GET /api/hashmap/get Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.BpfMap.html Retrieves a reference to the value associated with a given key. ```APIDOC ## GET /api/hashmap/get ### Description Returns a reference to the value corresponding to the key. The key may be any borrowed form of the map’s key type, but `Hash` and `Eq` on the borrowed form must match those for the key type. ### Method GET ### Endpoint `/api/hashmap/get ### Parameters #### Query Parameters - **k** (Q) - Required - The key to look up. ### Response #### Success Response (200) - **V** (Option<&V>) - A reference to the value if the key exists, otherwise None. ### Request Example ```json { "k": "example_key" } ``` ### Response Example ```json { "value": "example_value" } ``` ``` -------------------------------- ### Define and Install Rust Seccomp Filter Source: https://docs.rs/seccompiler/0.5.0/index.html Use this snippet to define a seccomp filter programmatically in Rust. It requires importing necessary types from the seccompiler crate and specifies actions for allowed and disallowed syscalls. ```rust use seccompiler::{ BpfProgram, SeccompAction, SeccompCmpArgLen, SeccompCmpOp, SeccompCondition, SeccompFilter, SeccompRule, }; use std::convert::TryInto; let filter: BpfProgram = SeccompFilter::new( vec![ (libc::SYS_accept4, vec![]), ( libc::SYS_fcntl, vec![ SeccompRule::new(vec![ SeccompCondition::new( 1, SeccompCmpArgLen::Dword, SeccompCmpOp::Eq, libc::F_SETFD as u64, ) .unwrap(), SeccompCondition::new( 2, SeccompCmpArgLen::Dword, SeccompCmpOp::Eq, libc::FD_CLOEXEC as u64, ) .unwrap(), ]) .unwrap(), SeccompRule::new(vec![SeccompCondition::new( 1, SeccompCmpArgLen::Dword, SeccompCmpOp::Eq, libc::F_GETFD as u64, ) .unwrap()]) .unwrap(), ], ), ] .into_iter() .collect(), SeccompAction::Allow, SeccompAction::Trap, std::env::consts::ARCH.try_into().unwrap(), ) .unwrap() .try_into() .unwrap(); seccompiler::apply_filter(&filter).unwrap(); ``` -------------------------------- ### Into Ok Value (Never Panics) Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.Result.html Use `into_ok()` to get the contained `Ok` value. This method is guaranteed not to panic, making it a compile-time safeguard against potential panics. ```rust fn only_good_news() -> Result { Ok("this is fine".into()) } let s: String = only_good_news().into_ok(); println!("{s}"); ``` -------------------------------- ### From for BpfProgram Source: https://docs.rs/seccompiler/0.5.0/src/seccompiler/backend/rule.rs.html Converts a SeccompRule into a BpfProgram. Each rule starts with two jump statements to manage control flow within the seccomp filter. ```APIDOC ## From for BpfProgram ### Description Implements the `From` trait to convert a `SeccompRule` into a `BpfProgram`. Each rule starts with 2 jump statements: the first jump enters the rule for matching, and the second jumps out of the rule to the next rule or the default action if no rules were matched. ### Method `impl From for BpfProgram` ``` -------------------------------- ### Get Disjoint Unchecked Mutably Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.BpfMap.html Safely get mutable references to multiple disjoint entries in a HashMap. The keys must not overlap. Panics if keys overlap or are not found. ```rust use std::collections::HashMap; let mut libraries = HashMap::new(); libraries.insert("Bodleian Library".to_string(), 1602); libraries.insert("Athenæum".to_string(), 1807); libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691); libraries.insert("Library of Congress".to_string(), 1800); // SAFETY: The keys do not overlap. let [Some(a), Some(b)] = (unsafe { libraries.get_disjoint_unchecked_mut([ "Athenæum", "Bodleian Library", ]) }) else { panic!() }; // SAFETY: The keys do not overlap. let got = unsafe { libraries.get_disjoint_unchecked_mut([ "Athenæum", "Library of Congress", ]) }; assert_eq!( got, [ Some(&mut 1807), Some(&mut 1800), ], ); // SAFETY: The keys do not overlap. let got = unsafe { libraries.get_disjoint_unchecked_mut([ "Athenæum", "New York Public Library", ]) }; // Missing keys result in None assert_eq!(got, [Some(&mut 1807), None]); ``` -------------------------------- ### Generate and Compare BPF Instructions Source: https://docs.rs/seccompiler/0.5.0/src/seccompiler/backend/rule.rs.html This snippet demonstrates the generation of BPF instructions from a seccomp rule and asserts its equality with a predefined set of instructions. It's used for testing the correctness of the rule translation. ```rust bpf_stmt(BPF_ALU | BPF_AND | BPF_K, 0), bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, offset + 3), bpf_stmt(BPF_LD | BPF_W | BPF_ABS, 16 + lsb_offset), bpf_stmt(BPF_ALU | BPF_AND | BPF_K, 0), bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, offset), ]); } // Compares translated rule with hardcoded BPF instructions. let bpfprog: BpfProgram = rule.into(); assert_eq!(bpfprog, instructions); } } ``` -------------------------------- ### Create SeccompFilter with Rules Source: https://docs.rs/seccompiler/0.5.0/src/seccompiler/backend/filter.rs.html Use this function to create a new SeccompFilter. It takes a map of syscall numbers to SeccompRules, actions for matching and mismatching syscalls, and the target architecture. Ensure that the mismatch and match actions are not identical. ```rust use seccompiler::{ SeccompAction, SeccompCmpArgLen, SeccompCmpOp, SeccompCondition, SeccompFilter, SeccompRule, }; use std::convert::TryInto; let filter = SeccompFilter::new( vec![ (libc::SYS_accept4, vec![]), ( libc::SYS_fcntl, vec![ SeccompRule::new(vec![ SeccompCondition::new( 1, SeccompCmpArgLen::Dword, SeccompCmpOp::Eq, libc::F_SETFD as u64, ) .unwrap(), SeccompCondition::new( 2, SeccompCmpArgLen::Dword, SeccompCmpOp::Eq, libc::FD_CLOEXEC as u64, ) .unwrap(), ]) .unwrap(), SeccompRule::new(vec![SeccompCondition::new( 1, SeccompCmpArgLen::Dword, SeccompCmpOp::Eq, libc::F_GETFD as u64, ) .unwrap()]) .unwrap(), ], ), ] .into_iter() .collect(), SeccompAction::Trap, SeccompAction::Allow, std::env::consts::ARCH.try_into().unwrap(), ); ``` -------------------------------- ### Get multiple mutable references unchecked Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.BpfMap.html Use `get_disjoint_unchecked_mut` to attempt to get mutable references to multiple values without validating that the values are unique. This method is unsafe and calling it with overlapping keys results in undefined behavior. ```rust pub unsafe fn get_disjoint_unchecked_mut( &mut self, ks: [&Q; N], ) -> [Option<&mut V>; N] where K: Borrow, Q: Hash + Eq + ?Sized, Attempts to get mutable references to `N` values in the map at once, without validating that the values are unique. Returns an array of length `N` with the results of each query. `None` will be used if the key is missing. For a safe alternative see `get_disjoint_mut`. ##### §Safety Calling this method with overlapping keys is _undefined behavior_ even if the resulting references are not used. ``` -------------------------------- ### GET /HashMap/index Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.BpfMap.html Retrieves a reference to the value corresponding to a key. ```APIDOC ## GET /HashMap/index ### Description Returns a reference to the value corresponding to the supplied key. ### Method GET ### Endpoint /HashMap/index ### Query Parameters - **key** (string) - Required - The key to look up in the map. ### Response #### Success Response (200) - **value** (any) - The value associated with the key. #### Error Handling - Panics if the key is not present in the HashMap. ``` -------------------------------- ### Build BPF instructions Source: https://docs.rs/seccompiler/0.5.0/src/seccompiler/backend/bpf.rs.html Helper functions to construct jump and statement BPF instructions. ```rust #[inline(always)] pub(crate) fn bpf_jump(code: u16, k: u32, jt: u8, jf: u8) -> sock_filter { sock_filter { code, jt, jf, k } } #[inline(always)] pub(crate) fn bpf_stmt(code: u16, k: u32) -> sock_filter { sock_filter { code, jt: 0, jf: 0, k, } } ``` -------------------------------- ### Initialize HashMap Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.BpfMap.html Create an empty HashMap using new or with_capacity. ```rust use std::collections::HashMap; let mut map: HashMap<&str, i32> = HashMap::new(); ``` ```rust use std::collections::HashMap; let mut map: HashMap<&str, i32> = HashMap::with_capacity(10); ``` -------------------------------- ### Initializing Vec via as_mut_ptr Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.BpfProgram.html Shows how to initialize vector memory using a mutable raw pointer and set the length manually. ```rust // Allocate vector big enough for 4 elements. let size = 4; let mut x: Vec = Vec::with_capacity(size); let x_ptr = x.as_mut_ptr(); // Initialize elements via raw pointer writes, then set length. unsafe { for i in 0..size { *x_ptr.add(i) = i as i32; } x.set_len(size); } assert_eq!(&*x, &[0, 1, 2, 3]); ``` ```rust unsafe { let mut v = vec![0]; let ptr1 = v.as_mut_ptr(); ptr1.write(1); let ptr2 = v.as_mut_ptr(); ptr2.write(2); // Notably, the write to `ptr2` did *not* invalidate `ptr1`: ptr1.write(3); } ``` -------------------------------- ### GET /api/hashmap/get_key_value Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.BpfMap.html Retrieves the key-value pair for a given key. ```APIDOC ## GET /api/hashmap/get_key_value ### Description Returns the key-value pair corresponding to the supplied key. This is potentially useful for key types where non-identical keys can be considered equal, for getting the `&K` stored key value from a borrowed `&Q` lookup key, or for getting a reference to a key with the same lifetime as the collection. The supplied key may be any borrowed form of the map’s key type, but `Hash` and `Eq` on the borrowed form must match those for the key type. ### Method GET ### Endpoint `/api/hashmap/get_key_value ### Parameters #### Query Parameters - **k** (Q) - Required - The key to look up. ### Response #### Success Response (200) - **(K, V)** (Option<(&K, &V)>) - A tuple containing references to the key and value if the key exists, otherwise None. ### Request Example ```json { "k": "example_key" } ``` ### Response Example ```json { "key": "example_key", "value": "example_value" } ``` ``` -------------------------------- ### Get multiple mutable references safely Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.BpfMap.html Use `get_disjoint_mut` to attempt to get mutable references to multiple values at once. It returns an array of `Option<&mut V>`, ensuring that at most one mutable reference is returned per value. This method checks for duplicate keys and panics if any are found. ```rust use std::collections::HashMap; let mut libraries = HashMap::new(); libraries.insert("Bodleian Library".to_string(), 1602); libraries.insert("Athenæum".to_string(), 1807); libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691); libraries.insert("Library of Congress".to_string(), 1800); // Get Athenæum and Bodleian Library let [Some(a), Some(b)] = libraries.get_disjoint_mut([ "Athenæum", "Bodleian Library", ]) else { panic!() }; // Assert values of Athenæum and Library of Congress let got = libraries.get_disjoint_mut([ "Athenæum", "Library of Congress", ]); assert_eq!( got, [ Some(&mut 1807), Some(&mut 1800), ], ); // Missing keys result in None let got = libraries.get_disjoint_mut([ "Athenæum", "New York Public Library", ]); assert_eq!( got, [ Some(&mut 1807), None ] ); ``` ```rust use std::collections::HashMap; let mut libraries = HashMap::new(); libraries.insert("Athenæum".to_string(), 1807); // Duplicate keys panic! let got = libraries.get_disjoint_mut([ "Athenæum", "Athenæum", ]); ``` -------------------------------- ### Initialize HashMap with Hasher Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.BpfMap.html Create an empty HashMap using a custom hash builder. ```rust use std::collections::HashMap; use std::hash::RandomState; let s = RandomState::new(); let mut map = HashMap::with_hasher(s); map.insert(1, 2); ``` ```rust use std::collections::HashMap; use std::hash::RandomState; let s = RandomState::new(); let mut map = HashMap::with_capacity_and_hasher(10, s); map.insert(1, 2); ``` -------------------------------- ### POST /api/hashmap/get_disjoint_mut Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.BpfMap.html Attempts to get mutable references to multiple values in the map at once. ```APIDOC ## POST /api/hashmap/get_disjoint_mut ### Description Attempts to get mutable references to `N` values in the map at once. Returns an array of length `N` with the results of each query. For soundness, at most one mutable reference will be returned to any value. `None` will be used if the key is missing. This method performs a check to ensure there are no duplicate keys, which currently has a time-complexity of O(n^2), so be careful when passing many keys. ### Method POST ### Endpoint `/api/hashmap/get_disjoint_mut ### Parameters #### Request Body - **ks** (array of Q) - Required - An array of keys to look up. ### Response #### Success Response (200) - **results** (array of Option<&mut V>) - An array of mutable references to the values, or None if the key is missing. ### Request Example ```json { "ks": ["key1", "key2"] } ``` ### Response Example ```json { "results": [{"value": "value1"}, null] } ``` ### Panics Panics if any keys are overlapping. ``` -------------------------------- ### Create a new SeccompFilter Source: https://docs.rs/seccompiler/0.5.0/seccompiler/struct.SeccompFilter.html Use this function to create a new SeccompFilter. It requires a map of syscall numbers to SeccompRules, actions for matching and mismatching syscalls, and the target architecture. Ensure the target architecture is correctly converted. ```rust use seccompiler::{ SeccompAction, SeccompCmpArgLen, SeccompCmpOp, SeccompCondition, SeccompFilter, SeccompRule, }; use std::convert::TryInto; let filter = SeccompFilter::new( vec![ (libc::SYS_accept4, vec![]), ( libc::SYS_fcntl, vec![ SeccompRule::new(vec![ SeccompCondition::new( 1, SeccompCmpArgLen::Dword, SeccompCmpOp::Eq, libc::F_SETFD as u64, ) .unwrap(), SeccompCondition::new( 2, SeccompCmpArgLen::Dword, SeccompCmpOp::Eq, libc::F_GETFD as u64, ) .unwrap(), ]) .unwrap(), SeccompRule::new(vec![SeccompCondition::new( 1, SeccompCmpArgLen::Dword, SeccompCmpOp::Eq, libc::F_GETFD as u64, ) .unwrap()]) .unwrap(), ], ), ] .into_iter() .collect(), SeccompAction::Trap, SeccompAction::Allow, std::env::consts::ARCH.try_into().unwrap(), ); ``` -------------------------------- ### SeccompRule::new Source: https://docs.rs/seccompiler/0.5.0/seccompiler/struct.SeccompRule.html Creates a new SeccompRule. Rules with zero conditions are not permitted. ```APIDOC ## pub fn new(conditions: Vec) -> Result ### Description Creates a new rule. Rules with 0 conditions are not allowed; to match a syscall regardless of argument values, map the syscall number to an empty vector of rules when constructing the `SeccompFilter` instead. ### Method `pub fn new` ### Parameters #### Arguments - **conditions** (Vec) - Vector of `SeccompCondition`s that the syscall must match. ### Request Example ```rust use seccompiler::{SeccompCmpArgLen, SeccompCmpOp, SeccompCondition, SeccompRule}; let rule = SeccompRule::new(vec![ SeccompCondition::new(0, SeccompCmpArgLen::Dword, SeccompCmpOp::Eq, 1).unwrap(), SeccompCondition::new(1, SeccompCmpArgLen::Dword, SeccompCmpOp::Eq, 1).unwrap(), ]) .unwrap(); ``` ### Response #### Success Response - **Self** (SeccompRule) - A new `SeccompRule` instance. #### Error Response - **Error** - If the rule creation fails (e.g., due to invalid conditions). ``` -------------------------------- ### POST /api/hashmap/get_disjoint_unchecked_mut Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.BpfMap.html Attempts to get mutable references to multiple values without validating uniqueness. ```APIDOC ## POST /api/hashmap/get_disjoint_unchecked_mut ### Description Attempts to get mutable references to `N` values in the map at once, without validating that the values are unique. Returns an array of length `N` with the results of each query. `None` will be used if the key is missing. For a safe alternative see `get_disjoint_mut`. ### Method POST ### Endpoint `/api/hashmap/get_disjoint_unchecked_mut ### Parameters #### Request Body - **ks** (array of Q) - Required - An array of keys to look up. ### Response #### Success Response (200) - **results** (array of Option<&mut V>) - An array of mutable references to the values, or None if the key is missing. ### Request Example ```json { "ks": ["key1", "key2"] } ``` ### Response Example ```json { "results": [{"value": "value1"}, null] } ``` ### Safety Calling this method with overlapping keys is _undefined behavior_ even if the resulting references are not used. ``` -------------------------------- ### SeccompFilter::new Source: https://docs.rs/seccompiler/0.5.0/seccompiler/struct.SeccompFilter.html Creates a new SeccompFilter with specified rules, actions, and target architecture. ```APIDOC ## POST /seccompiler/SeccompFilter/new ### Description Creates a new filter with a set of rules, an on-match and default action. ### Method POST ### Endpoint /seccompiler/SeccompFilter/new ### Parameters #### Query Parameters - **rules** (BTreeMap>) - Required - Map containing syscall numbers and their respective `SeccompRule`s. - **mismatch_action** (SeccompAction) - Required - `SeccompAction` taken for all syscalls that do not match the filter. - **match_action** (SeccompAction) - Required - `SeccompAction` taken for system calls that match the filter. - **target_arch** (TargetArch) - Required - Target architecture of the generated BPF filter. ### Request Example ```json { "rules": { "311": [ { "conditions": [ { "arg_index": 1, "arg_len": "Dword", "op": "Eq", "value": 1 }, { "arg_index": 2, "arg_len": "Dword", "op": "Eq", "value": 1 } ] }, { "conditions": [ { "arg_index": 1, "arg_len": "Dword", "op": "Eq", "value": 0 } ] } ] }, "mismatch_action": "Trap", "match_action": "Allow", "target_arch": "x86_64" } ``` ### Response #### Success Response (200) - **SeccompFilter** (SeccompFilter) - The newly created SeccompFilter. #### Response Example ```json { "SeccompFilter": { "rules": { "311": [ { "conditions": [ { "arg_index": 1, "arg_len": "Dword", "op": "Eq", "value": 1 }, { "arg_index": 2, "arg_len": "Dword", "op": "Eq", "value": 1 } ] }, { "conditions": [ { "arg_index": 1, "arg_len": "Dword", "op": "Eq", "value": 0 } ] } ] }, "mismatch_action": "Trap", "match_action": "Allow", "target_arch": "x86_64" } } ``` ``` -------------------------------- ### Get TypeId of self Source: https://docs.rs/seccompiler/0.5.0/seccompiler/enum.BackendError.html Retrieves the TypeId of the current instance, used for runtime type checking. ```rust fn type_id(&self) -> TypeId ``` -------------------------------- ### Create Vec from external allocation Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.BpfProgram.html Shows how to initialize a Vec using memory allocated via a custom allocator instance. ```rust #![feature(allocator_api)] use std::alloc::{AllocError, Allocator, Global, Layout}; fn main() { let layout = Layout::array::(16).expect("overflow cannot happen"); let vec = unsafe { let mem = match Global.allocate(layout) { Ok(mem) => mem.cast::().as_ptr(), Err(AllocError) => return, }; mem.write(1_000_000); Vec::from_raw_parts_in(mem, 1, 16, Global) }; assert_eq!(vec, &[1_000_000]); assert_eq!(vec.capacity(), 16); } ``` -------------------------------- ### Unwrap Err Value Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.Result.html Use `unwrap_err()` to get the contained `Err` value. Panics if the `Result` is an `Ok`. ```rust let x: Result = Ok(2); x.unwrap_err(); // panics with `2` ``` ```rust let x: Result = Err("emergency failure"); assert_eq!(x.unwrap_err(), "emergency failure"); ``` -------------------------------- ### Unwrap Ok Value Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.Result.html Use `unwrap()` to get the contained `Ok` value. Panics if the `Result` is an `Err`. ```rust let x: Result = Ok(2); assert_eq!(x.unwrap(), 2); ``` -------------------------------- ### Reconstruct Vec from raw parts Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.BpfProgram.html Demonstrates how to manually manage a Vec's memory by extracting its components and rebuilding it using from_raw_parts_in. ```rust #![feature(allocator_api)] use std::alloc::System; use std::ptr; use std::mem; let mut v = Vec::with_capacity_in(3, System); v.push(1); v.push(2); v.push(3); // Prevent running `v`'s destructor so we are in complete control // of the allocation. let mut v = mem::ManuallyDrop::new(v); // Pull out the various important pieces of information about `v` let p = v.as_mut_ptr(); let len = v.len(); let cap = v.capacity(); let alloc = v.allocator(); unsafe { // Overwrite memory with 4, 5, 6 for i in 0..len { ptr::write(p.add(i), 4 + i); } // Put everything back together into a Vec let rebuilt = Vec::from_raw_parts_in(p, len, cap, alloc.clone()); assert_eq!(rebuilt, [4, 5, 6]); } ``` -------------------------------- ### BpfProgram Initialization Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.BpfProgram.html Methods for creating and managing the BpfProgram vector structure. ```APIDOC ## BpfProgram Initialization ### Description Methods to construct and manage the BpfProgram vector, which holds a sequence of BPF instructions. ### Methods - **new()**: Constructs a new, empty BpfProgram. - **with_capacity(capacity: usize)**: Constructs a new, empty BpfProgram with pre-allocated capacity. - **try_with_capacity(capacity: usize)**: Experimental method to construct a vector with capacity, returning a Result. - **from_raw_parts(ptr: *mut T, length: usize, capacity: usize)**: Unsafe method to create a vector from raw memory components. ### Parameters #### Path Parameters - **capacity** (usize) - Required - The initial capacity for the vector allocation. ### Request Example ```rust let mut program: BpfProgram = Vec::new(); let mut program_with_cap = Vec::with_capacity(10); ``` ### Response #### Success Response (200) - **Vec** (Object) - The initialized BpfProgram vector. ``` -------------------------------- ### Get HashMap Length Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.BpfMap.html The `len` method returns the number of elements currently stored in the HashMap. This operation is O(1). ```rust use std::collections::HashMap; let mut a = HashMap::new(); assert_eq!(a.len(), 0); a.insert(1, "a"); assert_eq!(a.len(), 1); ``` -------------------------------- ### TryFrom SeccompFilter to BpfProgram Source: https://docs.rs/seccompiler/0.5.0/src/seccompiler/backend/filter.rs.html Converts a `SeccompFilter` into a `BpfProgram`. This involves building the initial architecture validation sequence and then appending the compiled BPF programs for each syscall rule. It checks for the maximum BPF program length. ```rust fn try_from(filter: SeccompFilter) -> Result { // Initialize the result with the precursory architecture check. let mut result = build_arch_validation_sequence(filter.target_arch); // If no rules are set up, the filter will always return the default action, // so let's short-circuit the function. if filter.rules.is_empty() { result.extend(vec![bpf_stmt( BPF_RET | BPF_K, u32::from(filter.mismatch_action), )]); return Ok(result); } // The called syscall number is loaded. let mut accumulator = vec![vec![bpf_stmt( BPF_LD | BPF_W | BPF_ABS, u32::from(SECCOMP_DATA_NR_OFFSET), )]]; let mut iter = filter.rules.into_iter(); // For each syscall adds its rule chain to the filter. let mismatch_action = filter.mismatch_action; let match_action = filter.match_action; iter.try_for_each(|(syscall_number, chain)| { SeccompFilter::append_syscall_chain( syscall_number, chain, mismatch_action.clone(), match_action.clone(), &mut accumulator, ) })?; // The default action is once again appended, it is reached if all syscall number // comparisons fail. accumulator.push(vec![bpf_stmt(BPF_RET | BPF_K, mismatch_action.into())]); // Finally, builds the translated filter by consuming the accumulator. accumulator .into_iter() .for_each(|mut instructions| result.append(&mut instructions)); if result.len() >= BPF_MAX_LEN { return Err(Error::FilterTooLarge(result.len())); } Ok(result) } ``` -------------------------------- ### Reconstruct Vec from raw parts Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.BpfProgram.html Demonstrates how to manually manage memory by decomposing a Vec, modifying its contents, and rebuilding it using Vec::from_parts_in. ```rust #![feature(allocator_api, box_vec_non_null)] use std::alloc::System; use std::ptr::NonNull; use std::mem; let mut v = Vec::with_capacity_in(3, System); v.push(1); v.push(2); v.push(3); // Prevent running `v`'s destructor so we are in complete control // of the allocation. let mut v = mem::ManuallyDrop::new(v); // Pull out the various important pieces of information about `v` let p = unsafe { NonNull::new_unchecked(v.as_mut_ptr()) }; let len = v.len(); let cap = v.capacity(); let alloc = v.allocator(); unsafe { // Overwrite memory with 4, 5, 6 for i in 0..len { p.add(i).write(4 + i); } // Put everything back together into a Vec let rebuilt = Vec::from_parts_in(p, len, cap, alloc.clone()); assert_eq!(rebuilt, [4, 5, 6]); } ``` ```rust #![feature(allocator_api, box_vec_non_null)] use std::alloc::{AllocError, Allocator, Global, Layout}; fn main() { let layout = Layout::array::(16).expect("overflow cannot happen"); let vec = unsafe { let mem = match Global.allocate(layout) { Ok(mem) => mem.cast::(), Err(AllocError) => return, }; mem.write(1_000_000); Vec::from_parts_in(mem, 1, 16, Global) }; assert_eq!(vec, &[1_000_000]); assert_eq!(vec.capacity(), 16); } ``` -------------------------------- ### Get error cause (Deprecated) Source: https://docs.rs/seccompiler/0.5.0/seccompiler/enum.BackendError.html Retrieves the cause of the error. This method is deprecated and replaced by `Error::source` which supports downcasting. ```rust fn cause(&self) -> Option<&dyn Error> ``` -------------------------------- ### Create Vec with TryWithCapacity (Nightly) Source: https://docs.rs/seccompiler/0.5.0/seccompiler/type.BpfProgram.html Constructs a new, empty Vec with a specified minimum capacity, returning an error if allocation fails. This is a nightly-only experimental API. ```rust pub fn try_with_capacity(capacity: usize) -> Result, TryReserveError> ```