diff --git a/.buildkite/custom-tests.json b/.buildkite/custom-tests.json index 3c11ea4e..afb78f93 100644 --- a/.buildkite/custom-tests.json +++ b/.buildkite/custom-tests.json @@ -1,5 +1,21 @@ { "tests": [ + { + "test_name": "build-gnu-json", + "command": "RUSTFLAGS=\"-D warnings\" cargo build --release --features=json", + "platform": [ + "x86_64", + "aarch64" + ] + }, + { + "test_name": "build-musl-json", + "command": "RUSTFLAGS=\"-D warnings\" cargo build --release --features=json --target {target_platform}-unknown-linux-musl", + "platform": [ + "x86_64", + "aarch64" + ] + }, { "test_name": "validate-syscall-tables", "command": "tools/generate_syscall_tables.sh --test", diff --git a/Cargo.toml b/Cargo.toml index 9c5288b6..5f4781f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,10 @@ keywords = ["seccomp", "jail", "sandbox"] license = "Apache-2.0 OR BSD-3-Clause" edition = "2018" +[features] +json = ["serde", "serde_json"] + [dependencies] libc = ">=0.2.39" -serde = { version = ">=1.0.27", features = ["derive"] } -serde_json = ">=1.0.9" +serde = { version = ">=1.0.27", features = ["derive"], optional = true} +serde_json = {version = ">=1.0.9", optional = true} diff --git a/README.md b/README.md index ff12b0a9..31d4864e 100644 --- a/README.md +++ b/README.md @@ -259,6 +259,9 @@ categories to BPF programs. pub type BpfMap = HashMap; ``` +Note that, in order to use the JSON functionality, you need to add the `json` +feature when importing the library. + For **Rust filters**, it’s enough to perform a `try_into()` cast, from a `SeccompFilter` to a `BpfProgram`: diff --git a/coverage_config_aarch64.json b/coverage_config_aarch64.json index 1c4cd754..a28ea5a1 100644 --- a/coverage_config_aarch64.json +++ b/coverage_config_aarch64.json @@ -1,5 +1,5 @@ { "coverage_score": 0, - "exclude_path": "tests/integration_tests.rs", - "crate_features": "" + "exclude_path": "tests/integration_tests.rs,tests/json.rs", + "crate_features": "json" } diff --git a/coverage_config_x86_64.json b/coverage_config_x86_64.json index 8d2d7508..78d72a35 100644 --- a/coverage_config_x86_64.json +++ b/coverage_config_x86_64.json @@ -1,5 +1,5 @@ { - "coverage_score": 87.3, - "exclude_path": "tests/integration_tests.rs", - "crate_features": "" + "coverage_score": 93.3, + "exclude_path": "tests/integration_tests.rs,tests/json.rs", + "crate_features": "json" } diff --git a/src/backend/mod.rs b/src/backend/mod.rs index a22d2618..48707c6f 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -13,8 +13,10 @@ pub use condition::SeccompCondition; pub use filter::SeccompFilter; pub use rule::SeccompRule; -use core::fmt::Formatter; +#[cfg(feature = "json")] use serde::Deserialize; + +use core::fmt::Formatter; use std::convert::TryFrom; use std::fmt::Display; @@ -102,8 +104,12 @@ impl TryFrom<&str> for TargetArch { } /// Comparison to perform when matching a condition. -#[derive(Clone, Debug, PartialEq, Deserialize)] -#[serde(rename_all = "snake_case")] +#[cfg_attr( + feature = "json", + derive(Deserialize), + serde(rename_all = "snake_case") +)] +#[derive(Clone, Debug, PartialEq)] pub enum SeccompCmpOp { /// Argument value is equal to the specified value. Eq, @@ -122,8 +128,8 @@ pub enum SeccompCmpOp { } /// Seccomp argument value length. -#[derive(Clone, Debug, PartialEq, Deserialize)] -#[serde(rename_all = "lowercase")] +#[cfg_attr(feature = "json", derive(Deserialize), serde(rename_all = "lowercase"))] +#[derive(Clone, Debug, PartialEq)] pub enum SeccompCmpArgLen { /// Argument value length is 4 bytes. Dword, @@ -132,8 +138,12 @@ pub enum SeccompCmpArgLen { } /// Actions that a seccomp filter can return for a syscall. -#[derive(Clone, Debug, PartialEq, Deserialize)] -#[serde(rename_all = "snake_case")] +#[cfg_attr( + feature = "json", + derive(Deserialize), + serde(rename_all = "snake_case") +)] +#[derive(Clone, Debug, PartialEq)] pub enum SeccompAction { /// Allows syscall. Allow, diff --git a/src/lib.rs b/src/lib.rs index 560ad104..2afcccdb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -108,11 +108,13 @@ //! ``` //! //! -//! This second example defines and installs an equivalent JSON filter: +//! This second example defines and installs an equivalent JSON filter (uses the `json` feature): //! //! ``` -//! use std::convert::TryInto; +//! # #[cfg(feature = "json")] +//! # { //! use seccompiler::BpfMap; +//! use std::convert::TryInto; //! //! let json_input = r#"{ //! "main_thread": { @@ -164,6 +166,8 @@ //! let filter = filter_map.get("main_thread").unwrap(); //! //! seccompiler::apply_filter(&filter).unwrap(); +//! +//! # } //! ``` //! //! [`SeccompFilter`]: struct.SeccompFilter.html @@ -173,14 +177,21 @@ //! mod backend; +#[cfg(feature = "json")] mod frontend; +#[cfg(feature = "json")] mod syscall_table; -use std::collections::HashMap; +#[cfg(feature = "json")] use std::convert::TryInto; +#[cfg(feature = "json")] +use std::io::Read; + +use std::collections::HashMap; use std::fmt::{Display, Formatter}; -use std::io::{self, Read}; +use std::io; +#[cfg(feature = "json")] use frontend::json::{Error as JsonFrontendError, JsonCompiler}; // Re-export the IR public types. @@ -213,6 +224,7 @@ pub enum Error { /// System error related to calling `prctl`. Prctl(io::Error), /// Json Frontend Error. + #[cfg(feature = "json")] JsonFrontend(JsonFrontendError), } @@ -230,6 +242,7 @@ impl Display for Error { Prctl(errno) => { write!(f, "Error calling `prctl`: {}", errno) } + #[cfg(feature = "json")] JsonFrontend(error) => { write!(f, "Json Frontend error: {}", error) } @@ -287,6 +300,7 @@ pub fn apply_filter(bpf_filter: BpfProgramRef) -> Result<()> { /// * `arch` - target architecture of the filter. /// /// [`BpfProgram`]: type.BpfProgram.html +#[cfg(feature = "json")] pub fn compile_from_json(reader: R, arch: TargetArch) -> Result { // Run the frontend. let seccomp_filters: HashMap = JsonCompiler::new(arch) diff --git a/tests/json.rs b/tests/json.rs index 92bdea7a..a39a7b4c 100644 --- a/tests/json.rs +++ b/tests/json.rs @@ -1,3 +1,5 @@ +#![cfg(feature = "json")] + use seccompiler::{apply_filter, compile_from_json, BpfProgram}; use std::convert::TryInto; use std::env::consts::ARCH;