Skip to content

Commit

Permalink
tests: Add tests for Rust bindings
Browse files Browse the repository at this point in the history
Add the regression tests for the libseccomp crate that is Rust
language bindings for the libseccomp library.

You can run the tests as follows:

```sh
$ ./configure --enable-rust
$ make
$ cd tests && make check-build
$ ./regression -m rust
```

Signed-off-by: Manabu Sugimoto <Manabu.Sugimoto@sony.com>
Signed-off-by: mayank <mayank.mrinal@sony.com>
  • Loading branch information
ManaSugi committed Jun 27, 2023
1 parent f1c3196 commit e604063
Show file tree
Hide file tree
Showing 71 changed files with 3,993 additions and 5 deletions.
15 changes: 15 additions & 0 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,19 @@ runs:
shell: bash
- run: |
./autogen.sh
# Specify the temporary version of the libseccomp test library because some
# functions of the Rust bindings are restricted based on the version.
TEST_VERSION=2.100.100
sed -i "/^AC_INIT/ s/0.0.0/$TEST_VERSION/" configure.ac
# Create a dummy pkgconfig because the Rust bindings need it for the compilation.
# This can be removed when the Rust bindings drop <2.5.0 support.
mkdir -p src/.libs/pkgconfig
cat << EOF > src/.libs/pkgconfig/libseccomp.pc
Name: libseccomp
Description: The enhanced seccomp library
URL: https://github.com/seccomp/libseccomp
Version: ${TEST_VERSION}
Cflags: -I$(realpath ./include)
Libs: -L$(realpath ./src/.libs) -lseccomp
EOF
shell: bash
4 changes: 2 additions & 2 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
uses: ./.github/actions/setup
- name: Build libseccomp
run: |
./configure --enable-python
./configure --enable-python --enable-rust
make check-build
- name: Run tests
run: |
Expand All @@ -52,7 +52,7 @@ jobs:
uses: ./.github/actions/setup
- name: Build libseccomp
run: |
./configure --enable-python
./configure --enable-python --enable-rust
make check-build
- name: Run live tests
run: |
Expand Down
4 changes: 2 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ AM_MAKEFLAGS_1 =
AM_MAKEFLAGS_ = ${AM_MAKEFLAGS_0}
AM_MAKEFLAGS = ${AM_MAKEFLAGS_@AM_V@}

# enable python during distcheck
AM_DISTCHECK_CONFIGURE_FLAGS = --enable-python
# enable python and rust during distcheck
AM_DISTCHECK_CONFIGURE_FLAGS = --enable-python --enable-rust

check-build: all
${MAKE} ${AM_MAKEFLAGS} -C src check-build
Expand Down
30 changes: 30 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,36 @@ AC_DEFINE_UNQUOTED([ENABLE_PYTHON],
[$(test "$enable_python" = "yes" && echo 1 || echo 0)],
[Python bindings build flag.])

dnl ####
dnl rustc checks
dnl ####
AC_CHECK_PROGS(rustc, rustc, "no")
AS_IF([test "$rustc" != no], [
AS_ECHO("checking rustc version... $($rustc -V 2>&1 | cut -d' ' -f 2)")
RUSTC_VER_MAJ=$($rustc -V 2>&1 | cut -d' ' -f 2 | cut -d'.' -f 1);
RUSTC_VER_MIN=$($rustc -V 2>&1 | cut -d' ' -f 2 | cut -d'.' -f 2);
],[
RUSTC_VER_MAJ=0
RUSTC_VER_MIN=0
])

dnl ####
dnl rust binding checks
dnl ####
AC_ARG_ENABLE([rust],
[AS_HELP_STRING([--enable-rust],
[build the rust bindings, requires rustc])])
AS_IF([test "$enable_rust" = yes], [
# rustc version check
AS_IF([test "$RUSTC_VER_MAJ" -eq 1 -a "$RUSTC_VER_MIN" -lt 63], [
AC_MSG_ERROR([rust bindings require rustc 1.63 or higher])
])
])
AM_CONDITIONAL([ENABLE_RUST], [test "$enable_rust" = yes])
AC_DEFINE_UNQUOTED([ENABLE_RUST],
[$(test "$enable_rust" = yes && echo 1 || echo 0)],
[Rust bindings build flag.])

AC_CHECK_TOOL(GPERF, gperf)
if test -z "$GPERF"; then
AC_MSG_ERROR([please install gperf])
Expand Down
4 changes: 4 additions & 0 deletions tests/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,7 @@ util.pyc
58-live-tsync_notify
59-basic-empty_binary_tree
60-sim-precompute
/rust/target
/rust/utils/target
.crates.toml
.crates2.json
21 changes: 21 additions & 0 deletions tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,23 @@ miniseq_LDADD =

TESTS = regression

if ENABLE_RUST
rust_BINDINGS_TEST = yes
else
rust_BINDINGS_TEST = no
endif

rust_TESTS_DIR = ./rust
rust_LINK_TYPE = static
rust_LIBSECCOMP_LIBRARY_DIR = ../src/.libs

define build_rust_bindings
echo "Build test programs for rust bindings"; \
export LIBSECCOMP_LINK_TYPE=$(rust_LINK_TYPE) && \
export LIBSECCOMP_LIB_PATH=$(shell realpath $(rust_LIBSECCOMP_LIBRARY_DIR)) && \
$(MAKE) -C $(rust_TESTS_DIR);
endef

check_PROGRAMS = \
miniseq \
01-sim-allow \
Expand Down Expand Up @@ -240,6 +257,10 @@ EXTRA_PROGRAMS = 00-test

check-build:
${MAKE} ${AM_MAKEFLAGS} ${check_PROGRAMS}
@if [ "$(rust_BINDINGS_TEST)" = "yes" ]; then \
$(call build_rust_bindings) \
fi

clean-local:
${RM} -f 00-test *.pyc
$(MAKE) -C $(rust_TESTS_DIR) clean
13 changes: 12 additions & 1 deletion tests/regression
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ GLBL_SYS_RESOLVER="../tools/scmp_sys_resolver"
GLBL_SYS_SIM="../tools/scmp_bpf_sim"
GLBL_SYS_API="../tools/scmp_api_level"

RUST_TESTS_BIN="./rust/bin"

####
# functions

Expand Down Expand Up @@ -104,7 +106,7 @@ optional arguments:
-h show this help message and exit
-j JOBS run up to JOBS test jobs in parallel
can also be set via LIBSECCOMP_TSTCFG_JOBS env variable
-m MODE specified the test mode [c (default), python]
-m MODE specified the test mode [c (default), python, rust]
can also be set via LIBSECCOMP_TSTCFG_MODE_LIST env variable
-a specifies all tests are to be run
-b BATCH_NAME specifies batch of tests to be run
Expand Down Expand Up @@ -266,6 +268,8 @@ function run_test_command() {
else
cmd="$cmd /usr/bin/env python ${srcdir}/$2.py $3"
fi
elif [[ $mode == "rust" ]]; then
cmd="${RUST_TESTS_BIN}/$2 $3"
else
cmd="$2 $3"
fi
Expand Down Expand Up @@ -1115,6 +1119,9 @@ while getopts "ab:gj:l:m:s:t:T:vh" opt; do
verify_deps python
mode_list="$mode_list python"
;;
rust)
mode_list="$mode_list rust"
;;
*)
usage
exit 1
Expand Down Expand Up @@ -1160,6 +1167,10 @@ if [[ -z $mode_list ]]; then
[[ "$(grep "ENABLE_PYTHON" ../configure.h | \
awk '{ print $3 }')" = "1" ]] && \
mode_list="$mode_list python"
# rust tests
[[ "$(grep "ENABLE_RUST" ../configure.h | \
awk '{ print $3 }')" = "1" ]] && \
mode_list="$mode_list rust"
fi
fi

Expand Down
17 changes: 17 additions & 0 deletions tests/rust/01-sim-allow.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: LGPL-2.1-only
//
// Copyright 2023 Sony Group Corporation
//
// Seccomp Library test program
//

use anyhow::Result;
use libseccomp::*;
use utils::*;

fn main() -> Result<()> {
let opts = util_getopt();
let ctx = ScmpFilterContext::new_filter(ScmpAction::Allow)?;

util_filter_output(&opts, &ctx)
}
22 changes: 22 additions & 0 deletions tests/rust/02-sim-basic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: LGPL-2.1-only
//
// Copyright 2023 Sony Group Corporation
//
// Seccomp Library test program
//

use anyhow::Result;
use libseccomp::*;
use utils::*;

fn main() -> Result<()> {
let opts = util_getopt();
let mut ctx = ScmpFilterContext::new_filter(ScmpAction::KillThread)?;

ctx.add_rule_exact(ScmpAction::Allow, ScmpSyscall::from_name("read")?)?;
ctx.add_rule_exact(ScmpAction::Allow, ScmpSyscall::from_name("write")?)?;
ctx.add_rule_exact(ScmpAction::Allow, ScmpSyscall::from_name("close")?)?;
ctx.add_rule_exact(ScmpAction::Allow, ScmpSyscall::from_name("rt_sigreturn")?)?;

util_filter_output(&opts, &ctx)
}
37 changes: 37 additions & 0 deletions tests/rust/03-sim-basic_chains.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: LGPL-2.1-only
//
// Copyright 2023 Sony Group Corporation
//
// Seccomp Library test program
//

use anyhow::Result;
use libseccomp::*;
use std::io::{stderr, stdin, stdout};
use std::os::unix::io::AsRawFd;
use utils::*;

fn main() -> Result<()> {
let opts = util_getopt();
let mut ctx = ScmpFilterContext::new_filter(ScmpAction::KillThread)?;

ctx.add_rule_conditional_exact(
ScmpAction::Allow,
ScmpSyscall::from_name("read")?,
&[scmp_cmp!($arg0 == stdin().as_raw_fd() as u64)],
)?;
ctx.add_rule_conditional_exact(
ScmpAction::Allow,
ScmpSyscall::from_name("write")?,
&[scmp_cmp!($arg0 == stdout().as_raw_fd() as u64)],
)?;
ctx.add_rule_conditional_exact(
ScmpAction::Allow,
ScmpSyscall::from_name("write")?,
&[scmp_cmp!($arg0 == stderr().as_raw_fd() as u64)],
)?;
ctx.add_rule_exact(ScmpAction::Allow, ScmpSyscall::from_name("close")?)?;
ctx.add_rule_exact(ScmpAction::Allow, ScmpSyscall::from_name("rt_sigreturn")?)?;

util_filter_output(&opts, &ctx)
}
51 changes: 51 additions & 0 deletions tests/rust/04-sim-multilevel_chains.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: LGPL-2.1-only
//
// Copyright 2023 Sony Group Corporation
//
// Seccomp Library test program
//

use anyhow::Result;
use libseccomp::*;
use std::io::{stderr, stdin, stdout};
use std::os::unix::io::AsRawFd;
use utils::*;

fn main() -> Result<()> {
let opts = util_getopt();
let mut ctx = ScmpFilterContext::new_filter(ScmpAction::KillThread)?;

ctx.add_rule(ScmpAction::Allow, ScmpSyscall::from_name("openat")?)?;
ctx.add_rule(ScmpAction::Allow, ScmpSyscall::from_name("close")?)?;
ctx.add_rule_conditional(
ScmpAction::Allow,
ScmpSyscall::from_name("read")?,
&[
scmp_cmp!($arg0 == stdin().as_raw_fd() as u64),
scmp_cmp!($arg1 != 0),
scmp_cmp!($arg2 < libc::ssize_t::MAX as u64),
],
)?;
ctx.add_rule_conditional(
ScmpAction::Allow,
ScmpSyscall::from_name("write")?,
&[
scmp_cmp!($arg0 == stdout().as_raw_fd() as u64),
scmp_cmp!($arg1 != 0),
scmp_cmp!($arg2 < libc::ssize_t::MAX as u64),
],
)?;
ctx.add_rule_conditional(
ScmpAction::Allow,
ScmpSyscall::from_name("write")?,
&[
scmp_cmp!($arg0 == stderr().as_raw_fd() as u64),
scmp_cmp!($arg1 != 0),
scmp_cmp!($arg2 < libc::ssize_t::MAX as u64),
],
)?;
ctx.add_rule(ScmpAction::Allow, ScmpSyscall::from_name("close")?)?;
ctx.add_rule(ScmpAction::Allow, ScmpSyscall::from_name("rt_sigreturn")?)?;

util_filter_output(&opts, &ctx)
}
52 changes: 52 additions & 0 deletions tests/rust/05-sim-long_jumps.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// SPDX-License-Identifier: LGPL-2.1-only
//
// Copyright 2023 Sony Group Corporation
//
// Seccomp Library test program
//

use anyhow::Result;
use libseccomp::*;
use utils::*;

fn main() -> Result<()> {
let opts = util_getopt();
let mut ctx = ScmpFilterContext::new_filter(ScmpAction::KillThread)?;

ctx.add_rule(ScmpAction::Allow, ScmpSyscall::from_name("brk")?)?;

// same syscall, many chains
for iter in 0..100 {
ctx.add_rule_conditional(
ScmpAction::Allow,
ScmpSyscall::from_name("chdir")?,
&[
scmp_cmp!($arg0 == iter),
scmp_cmp!($arg1 != 0),
scmp_cmp!($arg2 < libc::ssize_t::MAX as u64),
],
)?;
}

// many syscalls, same chain
let mut ctr = 0;
for iter in 0..10000 {
if ctr >= 100 {
break;
}

let syscall = ScmpSyscall::from(iter);
if syscall == ScmpSyscall::from_name("chdir")? {
continue;
}

if syscall.get_name().is_ok() {
ctx.add_rule_conditional(ScmpAction::Allow, iter, &[scmp_cmp!($arg0 != 0)])?;
ctr += 1;
}
}

ctx.add_rule(ScmpAction::Allow, ScmpSyscall::from_name("close")?)?;

util_filter_output(&opts, &ctx)
}
29 changes: 29 additions & 0 deletions tests/rust/06-sim-actions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: LGPL-2.1-only
//
// Copyright 2023 Sony Group Corporation
//
// Seccomp Library test program
//

use anyhow::Result;
use libseccomp::*;
use utils::*;

fn main() -> Result<()> {
let opts = util_getopt();
let mut ctx = ScmpFilterContext::new_filter(ScmpAction::KillThread)?;

set_api(3)?;

ctx.add_rule(ScmpAction::Allow, ScmpSyscall::from_name("read")?)?;
ctx.add_rule(ScmpAction::Log, ScmpSyscall::from_name("rt_sigreturn")?)?;
ctx.add_rule(
ScmpAction::Errno(libc::EPERM),
ScmpSyscall::from_name("write")?,
)?;
ctx.add_rule(ScmpAction::Trap, ScmpSyscall::from_name("close")?)?;
ctx.add_rule(ScmpAction::Trace(1234), ScmpSyscall::from_name("openat")?)?;
ctx.add_rule(ScmpAction::KillProcess, ScmpSyscall::from_name("fstatfs")?)?;

util_filter_output(&opts, &ctx)
}

0 comments on commit e604063

Please sign in to comment.