Skip to content

Commit

Permalink
feat: remove libseccomp rust dependency
Browse files Browse the repository at this point in the history
Replace `libseccomp` with in house binding.
This way we don't need to add another dependency
and allows us to have access the `seccomp_export_bpf_mem`
method, not exposed in the `libseccomp` crate.
This creates another issue though: the `seccomp_export_bpf_mem`
function needs to be exposed by the libseccomp library. This
is not an issue when `seccompiler` is build in the docker environment
because we build it from source. But version provided by
linux distribution might have this function not exposed.

Signed-off-by: Egor Lazarchuk <[email protected]>
  • Loading branch information
ShadowCurse committed Dec 9, 2024
1 parent 412c3d2 commit 95cdade
Show file tree
Hide file tree
Showing 6 changed files with 333 additions and 129 deletions.
25 changes: 0 additions & 25 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion src/seccompiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ bincode = "1.2.1"
clap = { version = "4.5.21", features = ["derive", "string"] }
displaydoc = "0.2.5"
libc = "0.2.167"
libseccomp = "0.3.0"
serde = { version = "1.0.215", features = ["derive"] }
serde_json = "1.0.133"
thiserror = "2.0.3"
Expand Down
1 change: 1 addition & 0 deletions src/seccompiler/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
// SPDX-License-Identifier: Apache-2.0

fn main() {
println!("cargo::rustc-link-search=/usr/local/lib");
println!("cargo::rustc-link-lib=seccomp");
}
174 changes: 174 additions & 0 deletions src/seccompiler/src/bindings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

#![allow(non_camel_case_types)]
#![allow(non_snake_case)]

//! Raw FFI bindings for libseccomp library
use std::os::raw::*;

pub const MINUS_EEXIST: i32 = -libc::EEXIST;

/// Filter context/handle (`*mut`)
pub type scmp_filter_ctx = *mut c_void;
/// Filter context/handle (`*const`)
pub type const_scmp_filter_ctx = *const c_void;

/// Comparison operators
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(C)]
pub enum scmp_compare {
_SCMP_CMP_MIN = 0,
/// not equal
SCMP_CMP_NE = 1,
/// less than
SCMP_CMP_LT = 2,
/// less than or equal
SCMP_CMP_LE = 3,
/// equal
SCMP_CMP_EQ = 4,
/// greater than or equal
SCMP_CMP_GE = 5,
/// greater than
SCMP_CMP_GT = 6,
/// masked equality
SCMP_CMP_MASKED_EQ = 7,
_SCMP_CMP_MAX,
}

/// Argument datum
pub type scmp_datum_t = u64;

/// Argument / Value comparison definition
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct scmp_arg_cmp {
/// argument number, starting at 0
pub arg: c_uint,
/// the comparison op, e.g. `SCMP_CMP_*`
pub op: scmp_compare,
pub datum_a: scmp_datum_t,
pub datum_b: scmp_datum_t,
}

pub const SCMP_ARCH_X86_64: u32 = 0xc000003e;
pub const SCMP_ARCH_AARCH64: u32 = 0xc00000b7;
/// Kill the process
pub const SCMP_ACT_KILL_PROCESS: u32 = 0x80000000;
/// Kill the thread
pub const SCMP_ACT_KILL_THREAD: u32 = 0x00000000;
/// Throw a `SIGSYS` signal
pub const SCMP_ACT_TRAP: u32 = 0x00030000;
/// Notifies userspace
pub const SCMP_ACT_ERRNO_MASK: u32 = 0x00050000;
/// Return the specified error code
#[must_use]
pub const fn SCMP_ACT_ERRNO(x: u16) -> u32 {
SCMP_ACT_ERRNO_MASK | x as u32
}

Check warning on line 69 in src/seccompiler/src/bindings.rs

View check run for this annotation

Codecov / codecov/patch

src/seccompiler/src/bindings.rs#L67-L69

Added lines #L67 - L69 were not covered by tests
pub const SCMP_ACT_TRACE_MASK: u32 = 0x7ff00000;
/// Notify a tracing process with the specified value
#[must_use]
pub const fn SCMP_ACT_TRACE(x: u16) -> u32 {
SCMP_ACT_TRACE_MASK | x as u32
}

Check warning on line 75 in src/seccompiler/src/bindings.rs

View check run for this annotation

Codecov / codecov/patch

src/seccompiler/src/bindings.rs#L73-L75

Added lines #L73 - L75 were not covered by tests
/// Allow the syscall to be executed after the action has been logged
pub const SCMP_ACT_LOG: u32 = 0x7ffc0000;
/// Allow the syscall to be executed
pub const SCMP_ACT_ALLOW: u32 = 0x7fff0000;

#[link(name = "seccomp")]
extern "C" {
/// Initialize the filter state
///
/// - `def_action`: the default filter action
///
/// This function initializes the internal seccomp filter state and should
/// be called before any other functions in this library to ensure the filter
/// state is initialized. Returns a filter context on success, `ptr::null()` on failure.
pub fn seccomp_init(def_action: u32) -> scmp_filter_ctx;

/// Adds an architecture to the filter
///
/// - `ctx`: the filter context
/// - `arch_token`: the architecture token, e.g. `SCMP_ARCH_*`
///
/// This function adds a new architecture to the given seccomp filter context.
/// Any new rules added after this function successfully returns will be added
/// to this architecture but existing rules will not be added to this
/// architecture. If the architecture token is [`SCMP_ARCH_NATIVE`] then the native
/// architecture will be assumed. Returns zero on success, `-libc::EEXIST` if
/// specified architecture is already present, other negative values on failure.
pub fn seccomp_arch_add(ctx: scmp_filter_ctx, arch_token: u32) -> c_int;

/// Resolve a syscall name to a number
///
/// - `name`: the syscall name
///
/// Resolve the given syscall name to the syscall number. Returns the syscall
/// number on success, including negative pseudo syscall numbers (e.g. `__PNR_*`);
/// returns [`__NR_SCMP_ERROR`] on failure.
pub fn seccomp_syscall_resolve_name(name: *const c_char) -> c_int;

/// Add a new rule to the filter
///
/// - `ctx`: the filter context
/// - `action`: the filter action
/// - `syscall`: the syscall number
/// - `arg_cnt`: the number of argument filters in the argument filter chain
/// - `...`: [`scmp_arg_cmp`] structs
///
/// This function adds a series of new argument/value checks to the seccomp
/// filter for the given syscall; multiple argument/value checks can be
/// specified and they will be chained together (AND'd together) in the filter.
/// If the specified rule needs to be adjusted due to architecture specifics it
/// will be adjusted without notification. Returns zero on success, negative
/// values on failure.
pub fn seccomp_rule_add(
ctx: scmp_filter_ctx,
action: u32,
syscall: c_int,
arg_cnt: c_uint,
...
) -> c_int;

/// Add a new rule to the filter
///
/// - `ctx`: the filter context
/// - `action`: the filter action
/// - `syscall`: the syscall number
/// - `arg_cnt`: the number of elements in the arg_array parameter
/// - `arg_array`: array of [`scmp_arg_cmp`] structs
///
/// This function adds a series of new argument/value checks to the seccomp
/// filter for the given syscall; multiple argument/value checks can be
/// specified and they will be chained together (AND'd together) in the filter.
/// If the specified rule needs to be adjusted due to architecture specifics it
/// will be adjusted without notification. Returns zero on success, negative
/// values on failure.
pub fn seccomp_rule_add_array(
ctx: scmp_filter_ctx,
action: u32,
syscall: c_int,
arg_cnt: c_uint,
arg_array: *const scmp_arg_cmp,
) -> c_int;

/// Generate seccomp Berkeley Packet Filter (BPF) code and export it to a buffer
///
/// - `ctx`: the filter context
/// - `buf`: the destination buffer
/// - `len`: on input the length of the buffer, on output the number of bytes in the program
///
/// This function generates seccomp Berkeley Packer Filter (BPF) code and writes
/// it to the given buffer. Returns zero on success, negative values on failure.
pub fn seccomp_export_bpf_mem(
ctx: const_scmp_filter_ctx,
buf: *mut c_void,
len: *mut usize,
) -> c_int;
}

/// Negative pseudo syscall number returned by some functions in case of an error
pub const __NR_SCMP_ERROR: c_int = -1;
Loading

0 comments on commit 95cdade

Please sign in to comment.