diff --git a/.github/workflows/misc-tests.yaml b/.github/workflows/misc-tests.yaml new file mode 100644 index 0000000000..126111a88c --- /dev/null +++ b/.github/workflows/misc-tests.yaml @@ -0,0 +1,28 @@ +name: Misc tests +on: + push: + branches: [ '*' ] + pull_request: + branches: [ '*' ] +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }} + cancel-in-progress: true +jobs: + pre-sandbox: + if: github.repository_owner == 'aws' + runs-on: ubuntu-latest + steps: + - name: Install OS Dependencies + run: | + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none + sudo apt-get -y --no-install-recommends install \ + cmake clang ninja-build golang + echo "CC=clang" >> $GITHUB_ENV + echo "CXX=clang++" >> $GITHUB_ENV + - name: Install seccomp dependencies + run: | + sudo apt-get -y --no-install-recommends install libseccomp-dev + - uses: actions/checkout@v3 + - name: Test sandbox configuration + run: | + ./tests/ci/run_presandbox_tests.sh diff --git a/SANDBOXING.md b/SANDBOXING.md index 0f3eb70051..f2d5b97ae1 100644 --- a/SANDBOXING.md +++ b/SANDBOXING.md @@ -120,6 +120,11 @@ Once initialized, this mechanism does not require system calls in the steady state, though note the configured page will be inherited across privilege transitions. +### Snapsafe protection + +Similar considerations to fork protection. The Snapsafe protection +implementation maps a page that can trip sandboxes. + ## C and C++ standard library BoringSSL depends on the C and C++ standard libraries which, themselves, do not diff --git a/tests/ci/run_presandbox_tests.sh b/tests/ci/run_presandbox_tests.sh new file mode 100755 index 0000000000..839f3b0170 --- /dev/null +++ b/tests/ci/run_presandbox_tests.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 OR ISC + +# We expect an executable failure in this test. Hence, don't use -e. +set -xo pipefail + +source tests/ci/common_posix_setup.sh + +# libseccomp is required to run this tests. Typically this package is named +# either libseccomp-dev or libseccomp-devel. + +# Set up environment. + +# SYS_ROOT +# | +# - SRC_ROOT(aws-lc) +# | +# - SCRATCH_FOLDER +# | +# - seccomp app binary +# - AWS_LC_BUILD_FOLDER +# - AWS_LC_INSTALL_FOLDER + +# Assumes script is executed from the root of aws-lc directory +SCRATCH_FOLDER=${SYS_ROOT}/"SCRATCH_AWSLC_PRESANDBOX_TEST" +AWS_LC_BUILD_FOLDER="${SCRATCH_FOLDER}/aws-lc-build" +AWS_LC_INSTALL_FOLDER="${SCRATCH_FOLDER}/aws-lc-install" +: "${CC:=gcc}" + +# Make script execution idempotent. +mkdir -p ${SCRATCH_FOLDER} +rm -rf "${SCRATCH_FOLDER:?}"/* +cd ${SCRATCH_FOLDER} + +aws_lc_build "$SRC_ROOT" "$AWS_LC_BUILD_FOLDER" "$AWS_LC_INSTALL_FOLDER" \ + -DBUILD_TESTING=OFF -DBUILD_TOOL=OFF -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DBUILD_SHARED_LIBS=OFF + +# Check which AWS-LC library folder name we must use. +if [ -d ${AWS_LC_INSTALL_FOLDER}/lib64 ]; then + AWS_LC_LIBRARY_FOLDER="lib64" +else + AWS_LC_LIBRARY_FOLDER="lib" +fi + +function seccomp_build() { + __CFLAGS=${1} + ${CC} -I${SRC_ROOT}/include ${__CFLAGS} \ + ${SRC_ROOT}/tests/ci/test_apps/seccomp_app.c -o seccomp_app \ + -lseccomp -L${AWS_LC_INSTALL_FOLDER}/${AWS_LC_LIBRARY_FOLDER} -lcrypto -pthread +} + +echo "Test that AWS-LC performs syscalls that will trip the seccomp filter." +seccomp_build "" +./seccomp_app +if [ $? -eq 0 ]; then + echo "Failure: expected AWS-LC syscalls to trip the seccomp filter." + exit 1 +fi + +echo "Test that when AWS-LC is sandbox configured, the seccomp filter does not trip." +seccomp_build "-DUSE_AWS_LC_PRE_SANDBOX" +./seccomp_app +if [ $? -ne 0 ]; then + echo "Failure: AWS-LC is sandbox configured but something tripped the seccomp filter." + exit 1 +fi + +echo "Pre-sandbox test succeeded." diff --git a/tests/ci/test_apps/seccomp_app.c b/tests/ci/test_apps/seccomp_app.c new file mode 100644 index 0000000000..a58fa0302e --- /dev/null +++ b/tests/ci/test_apps/seccomp_app.c @@ -0,0 +1,60 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR ISC + +#include +#include +#include +#include + +#include +#include + +static void enable_seccomp(void) { + + // Kill on all system calls by default. + scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL); + if (ctx == NULL) { + exit(EXIT_FAILURE); + } + + // Allow write and exit system calls. In addition, on success we exit with + // exit_group. Hence, allow that as well. + seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0); + seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0); + seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0); + + if (seccomp_load(ctx) < 0) { + seccomp_release(ctx); + exit(EXIT_FAILURE); + } + + seccomp_release(ctx); +} + +int main() { + + const char notice[] = "\nTesting AWS-LC pre-sandbox.\n"; +#if defined(USE_AWS_LC_PRE_SANDBOX) + const char status[] = "Pre-sandbox configuration is ENABLED, expect success.\n\n"; +#else + const char status[] = "Pre-sandbox configuration is DISABLED, expect failure.\n\n"; +#endif + + write(STDOUT_FILENO, notice, sizeof(notice)); + write(STDOUT_FILENO, status, sizeof(status)); + +#if defined(USE_AWS_LC_PRE_SANDBOX) + // Must be invoked before enabling seccomp filter. + CRYPTO_pre_sandbox_init(); +#endif + + // Enable seccomp filter. + enable_seccomp(); + + uint8_t buffer[10]; + if (RAND_bytes(buffer, 10) != 1) { + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +}