Skip to content

Commit 4bce8d8

Browse files
authored
Merge pull request #234 from mbargull/conditional-SCMP_ACT_KILL_PROCESS
seccompfilter: Use SCMP_ACT_KILL_PROCESS only on compatible kernels
2 parents 13ac4c2 + bf13e3e commit 4bce8d8

9 files changed

+171
-16
lines changed

.github/workflows/main.yaml

+33
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,39 @@ jobs:
1717
steps:
1818
- uses: actions/checkout@v2
1919
- run: DOCKER_BUILDKIT=1 docker build -f Dockerfile.buildtests .
20+
test-centos:
21+
runs-on: macos-latest
22+
env:
23+
LIBSECCOMP_COMMIT: v2.3.3
24+
LIBSLIRP_COMMIT: v4.1.0
25+
BENCHMARK_IPERF3_DURATION: 3
26+
steps:
27+
- uses: actions/checkout@v2
28+
- name: Setup CentOS 7 VM
29+
run: |
30+
vagrant up --provision --no-tty
31+
cat > ./run-vagrant-tests <<'EOF'
32+
exec vagrant ssh --no-tty -c "
33+
export LIBSECCOMP_COMMIT=\"${LIBSECCOMP_COMMIT}\"
34+
export LIBSLIRP_COMMIT=\"${LIBSLIRP_COMMIT}\"
35+
export BENCHMARK_IPERF3_DURATION=\"${BENCHMARK_IPERF3_DURATION}\"
36+
/src/build-and-test
37+
"
38+
EOF
39+
- name: Build and test with Debian 10's version of libseccomp
40+
run: sh ./run-vagrant-tests
41+
- name: Build and test with Ubuntu 20.04's versions of libseccomp/libslirp
42+
run: sh ./run-vagrant-tests
43+
env:
44+
LIBSECCOMP_COMMIT: v2.4.3
45+
LIBSLIRP_COMMIT: v4.1.0
46+
- name: Build and test with recent versions of libseccomp/libslirp
47+
run: sh ./run-vagrant-tests
48+
env:
49+
LIBSECCOMP_COMMIT: v2.5.0
50+
LIBSLIRP_COMMIT: v4.2.0
51+
# Fails with --disable-dns from libslirp >=4.3.0
52+
# (no timeout in test-slirp4netns-disable-dns.sh).
2053
artifact:
2154
runs-on: ubuntu-latest
2255
steps:

Makefile.am

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ AM_CFLAGS = @GLIB_CFLAGS@ @SLIRP_CFLAGS@ @LIBCAP_CFLAGS@ @LIBSECCOMP_CFLAGS@
55
noinst_LIBRARIES = libparson.a
66

77
AM_TESTS_ENVIRONMENT = PATH="$(abs_top_builddir):$(PATH)"
8-
TESTS = tests/test-slirp4netns.sh tests/test-slirp4netns-configure.sh tests/test-slirp4netns-exit-fd.sh tests/test-slirp4netns-ready-fd.sh tests/test-slirp4netns-api-socket.sh tests/test-slirp4netns-disable-host-loopback.sh tests/test-slirp4netns-cidr.sh tests/test-slirp4netns-outbound-addr.sh tests/test-slirp4netns-disable-dns.sh
8+
TESTS = tests/test-slirp4netns.sh tests/test-slirp4netns-configure.sh tests/test-slirp4netns-exit-fd.sh tests/test-slirp4netns-ready-fd.sh tests/test-slirp4netns-api-socket.sh tests/test-slirp4netns-disable-host-loopback.sh tests/test-slirp4netns-cidr.sh tests/test-slirp4netns-outbound-addr.sh tests/test-slirp4netns-disable-dns.sh tests/test-slirp4netns-seccomp.sh
99

1010
EXTRA_DIST = \
1111
slirp4netns.1.md \
@@ -54,12 +54,12 @@ indent:
5454
$(CLANGFORMAT) -i $(slirp4netns_SOURCES)
5555

5656
benchmark:
57-
benchmarks/benchmark-iperf3.sh
58-
benchmarks/benchmark-iperf3-reverse.sh
57+
"$(abs_srcdir)/benchmarks/benchmark-iperf3.sh"
58+
"$(abs_srcdir)/benchmarks/benchmark-iperf3-reverse.sh"
5959

6060
ci:
6161
$(MAKE) indent
62-
git diff --exit-code
62+
git -C "$(abs_srcdir)" diff --exit-code
6363
# TODO: make sure ./vendor is synced with ./vendor.sh
6464
$(MAKE) lint
6565
$(MAKE) -j $(shell nproc) distcheck || ( find . -name test-suite.log | xargs cat; exit 1 )

Vagrantfile

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
Vagrant.configure("2") do |config|
2+
require 'etc'
3+
config.vm.provider "virtualbox" do |vbox|
4+
vbox.cpus = [1, Etc.nprocessors].max
5+
end
6+
config.vm.box = "centos/7"
7+
config.vm.synced_folder ".", "/vagrant", disabled: true
8+
config.vm.synced_folder ".", "/src/slirp4netns", type: "rsync"
9+
config.vm.provision "shell",
10+
inline: <<~'SHELL'
11+
set -xeu
12+
sysctl user.max_user_namespaces=65536
13+
14+
yum install -y \
15+
epel-release \
16+
https://repo.ius.io/ius-release-el7.rpm
17+
18+
yum install -y \
19+
autoconf automake make gcc gperf libtool \
20+
git-core meson ninja-build \
21+
glib2-devel libcap-devel \
22+
git-core libtool iproute iputils iperf3 nmap jq
23+
24+
cd /src
25+
chown vagrant .
26+
27+
su vagrant -c '
28+
set -xeu
29+
30+
git clone --depth=1 --no-checkout https://github.com/seccomp/libseccomp
31+
git -C ./libseccomp fetch --tags --depth=1
32+
33+
git clone --depth=1 --no-checkout https://gitlab.freedesktop.org/slirp/libslirp.git
34+
git -C ./libslirp fetch --tags --depth=1
35+
36+
touch ./build-and-test
37+
chmod a+x ./build-and-test
38+
'
39+
40+
cat > ./build-and-test <<'EOS'
41+
#! /bin/sh
42+
set -xeu
43+
src_dir='/src'
44+
45+
prefix="${PREFIX:-${HOME}/prefix}"
46+
build_root="${BUILD_ROOT:-${prefix}/build}"
47+
rm -rf "${prefix}" "${build_root}"
48+
mkdir -p "${build_root}"
49+
50+
export CFLAGS="-I${prefix}"
51+
export LDFLAGS="-L${prefix} -Wl,-rpath,${prefix}/lib"
52+
export PKG_CONFIG_PATH="${prefix}/lib/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}"
53+
54+
git -C "${src_dir}/libseccomp" fetch --depth=1 origin "${LIBSECCOMP_COMMIT:-v2.4.3}"
55+
git -C "${src_dir}/libseccomp" checkout FETCH_HEAD
56+
( cd "${src_dir}/libseccomp" && ./autogen.sh )
57+
mkdir "${build_root}/libseccomp"
58+
pushd "${build_root}/libseccomp"
59+
"${src_dir}/libseccomp/configure" --prefix="${prefix}"
60+
make -j "$( nproc )" CFLAGS+="-I$( pwd )/include"
61+
make install
62+
popd
63+
64+
git -C "${src_dir}/libslirp" fetch --depth=1 origin "${LIBSLIRP_COMMIT:-v4.1.0}"
65+
git -C "${src_dir}/libslirp" checkout FETCH_HEAD
66+
mkdir "${build_root}/libslirp"
67+
pushd "${build_root}/libslirp"
68+
meson setup --prefix="${prefix}" --libdir=lib . "${src_dir}/libslirp"
69+
ninja -C . install
70+
popd
71+
72+
( cd "${src_dir}/slirp4netns" && ./autogen.sh )
73+
mkdir "${build_root}/slirp4netns"
74+
pushd "${build_root}/slirp4netns"
75+
"${src_dir}/slirp4netns/configure" --prefix="${prefix}"
76+
make -j "$( nproc )"
77+
78+
make ci 'CLANGTIDY=echo skipping:' 'CLANGFORMAT=echo skipping:'
79+
popd
80+
EOS
81+
SHELL
82+
end

benchmarks/benchmark-iperf3-reverse.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,4 @@ function cleanup {
3030
}
3131
trap cleanup EXIT
3232

33-
iperf3 -c 127.0.0.1 -p 15201 -t 60
33+
iperf3 -c 127.0.0.1 -p 15201 -t "${BENCHMARK_IPERF3_DURATION:-60}"

benchmarks/benchmark-iperf3.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ function cleanup {
2323
}
2424
trap cleanup EXIT
2525

26-
nsenter --preserve-credentials -U -n --target=$child iperf3 -c 10.0.2.2 -t 60
26+
nsenter --preserve-credentials -U -n --target=$child iperf3 -c 10.0.2.2 -t "${BENCHMARK_IPERF3_DURATION:-60}"

configure.ac

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ AC_CONFIG_HEADERS([config.h])
66
AC_PROG_CC
77
AC_PROG_RANLIB
88

9-
AM_INIT_AUTOMAKE([1.9 foreign subdir-objects])
9+
AM_INIT_AUTOMAKE([1.11.2 foreign subdir-objects])
10+
AM_PROG_AR
1011

1112
AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/ioctl.h sys/mount.h sys/socket.h sys/timeb.h unistd.h getopt.h])
1213

seccompfilter.c

+23-7
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,30 @@
33
#include <stdio.h>
44
#include <errno.h>
55
#include <string.h>
6+
#include <linux/seccomp.h>
67
#include <seccomp.h>
78
#include "seccomparch.h"
89

10+
#if defined(SCMP_ACT_KILL_PROCESS) && defined(SECCOMP_GET_ACTION_AVAIL) && \
11+
defined(SECCOMP_RET_KILL_PROCESS)
12+
#include <unistd.h>
13+
#include <sys/syscall.h>
14+
15+
uint32_t get_block_action()
16+
{
17+
const uint32_t action = SECCOMP_RET_KILL_PROCESS;
18+
/* Syscall fails if either actions_avail or kill_process is not available */
19+
if (syscall(__NR_seccomp, SECCOMP_GET_ACTION_AVAIL, 0, &action) == 0)
20+
return SCMP_ACT_KILL_PROCESS;
21+
return SCMP_ACT_KILL;
22+
}
23+
#else
24+
uint32_t get_block_action()
25+
{
26+
return SCMP_ACT_KILL;
27+
}
28+
#endif
29+
930
int enable_seccomp()
1031
{
1132
int rc = -1, i;
@@ -24,14 +45,10 @@ int enable_seccomp()
2445
}
2546
}
2647
printf("seccomp: The following syscalls will be blocked by seccomp:");
27-
#ifdef SCMP_ACT_KILL_PROCESS
28-
#define BLOCK_ACTION SCMP_ACT_KILL_PROCESS
29-
#else
30-
#define BLOCK_ACTION SCMP_ACT_KILL
31-
#endif
48+
uint32_t block_action = get_block_action();
3249
#define BLOCK(x) \
3350
{ \
34-
rc = seccomp_rule_add(ctx, BLOCK_ACTION, SCMP_SYS(x), 0); \
51+
rc = seccomp_rule_add(ctx, block_action, SCMP_SYS(x), 0); \
3552
if (rc < 0) \
3653
goto ret; \
3754
printf(" %s", #x); \
@@ -59,7 +76,6 @@ int enable_seccomp()
5976
BLOCK(umount2);
6077
BLOCK(unshare);
6178
#undef BLOCK
62-
#undef BLOCK_ACTION
6379
printf(".\n");
6480
rc = seccomp_load(ctx);
6581
ret:

tests/test-slirp4netns-cidr.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,5 @@ function cleanup {
4343
}
4444
trap cleanup EXIT
4545

46-
ip=$(nsenter --preserve-credentials -U -n --target=$child ip -json a show dev tun11 | jq -r .[1].addr_info[0].local)
47-
[[ $ip = 10.0.135.228 ]]
46+
result="$(nsenter --preserve-credentials -U -n --target=$child ip a show dev tun11)"
47+
echo "$result" | grep -om1 '^\s*inet .*/' | grep -qF 10.0.135.228

tests/test-slirp4netns-seccomp.sh

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/bin/bash
2+
set -xeuo pipefail
3+
4+
. $(dirname $0)/common.sh
5+
6+
unshare -r -n sleep infinity &
7+
child=$!
8+
9+
wait_for_network_namespace $child
10+
11+
slirp4netns -c --enable-seccomp --userns-path=/proc/$child/ns/user $child tun11 &
12+
slirp_pid=$!
13+
14+
wait_for_network_device $child tun11
15+
16+
function cleanup {
17+
kill -9 $child $slirp_pid
18+
}
19+
trap cleanup EXIT
20+
21+
nsenter --preserve-credentials -U -n --target=$child ip -a netconf | grep tun11
22+
23+
nsenter --preserve-credentials -U -n --target=$child ip addr show tun11 | grep inet

0 commit comments

Comments
 (0)