Skip to content

Commit

Permalink
test: seccomp + handshake
Browse files Browse the repository at this point in the history
  • Loading branch information
lrstewart committed Sep 13, 2024
1 parent 341a69e commit f81fc75
Show file tree
Hide file tree
Showing 7 changed files with 242 additions and 2 deletions.
100 changes: 100 additions & 0 deletions .github/workflows/ci_ubuntu.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: Ubuntu
on:
pull_request:
branches: [main]
merge_group:
types: [checks_requested]
branches: [main]

# Builds should match https://github.com/aws/s2n-tls/blob/main/docs/BUILD.md#building-s2n-tls
# If any of these builds need to be modified, BUILD.md also needs to be modified.
jobs:
default:
runs-on: ubuntu-latest
steps:
- name: Install dependencies
run: |
sudo apt update
sudo apt install cmake
sudo apt install libssl-dev
- uses: actions/checkout@v4

- name: Build s2n-tls
run: |
cmake . -Bbuild \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=./s2n-tls-install
cmake --build build -j $(nproc)
CTEST_PARALLEL_LEVEL=$(nproc) ctest --test-dir build
cmake --install build
- name: Rebuild with seccomp
run: |
rm -rf build
sudo apt install libseccomp-dev
cmake . -Bbuild \
-DCMAKE_BUILD_TYPE=Release \
-DSECCOMP=1 \
-DCMAKE_INSTALL_PREFIX=./s2n-tls-install
cmake --build build -j $(nproc)
CTEST_PARALLEL_LEVEL=$(nproc) ctest --test-dir build
awslc:
runs-on: ubuntu-latest
steps:
- name: Install aws-lc dependencies
run: |
sudo apt update
sudo apt install cmake clang golang
- uses: actions/checkout@v4
with:
repository: aws/aws-lc
path: awslc
- name: Build awslc
# See https://github.com/aws/aws-lc/blob/main/BUILDING.md#building
working-directory: awslc
run: |
cmake -B build
make -C build
cmake --install install
- name: Install s2n-tls dependencies
run: |
sudo apt update
sudo apt install cmake
- uses: actions/checkout@v4
with:
path: s2ntls
- name: Build s2n-tls
working-directory: s2ntls
run: |
cmake . -Bbuild \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH=../awslc/install \
-DCMAKE_INSTALL_PREFIX=./s2n-tls-install
cmake --build build -j $(nproc)
CTEST_PARALLEL_LEVEL=$(nproc) ctest --test-dir build
cmake --install build
- name: Check libcrypto is aws-lc
working-directory: s2ntls/build/bin
run: s2nc localhost 8000 | grep "AWS-LC"

- name: Install seccomp
run: |
sudo apt install libseccomp-dev
- uses: actions/checkout@v4
with:
path: seccomp
- name: Build s2n-tls with seccomp
working-directory: seccomp
run: |
cmake . -Bbuild \
-DCMAKE_BUILD_TYPE=Release \
-DSECCOMP=1 \
-DCMAKE_PREFIX_PATH=../awslc/install \
-DCMAKE_INSTALL_PREFIX=./s2n-tls-install
cmake --build build -j $(nproc)
CTEST_PARALLEL_LEVEL=$(nproc) ctest --test-dir build
- name: Check libcrypto is aws-lc
working-directory: seccomp/build/bin
run: s2nc localhost 8000 | grep "AWS-LC"
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ option(S2N_INSTALL_S2NC_S2ND "Install the binaries s2nc and s2nd" OFF)
option(S2N_USE_CRYPTO_SHARED_LIBS "For S2N to use shared libs in Findcrypto" OFF)
option(TSAN "Enable ThreadSanitizer to test thread safety" OFF)
option(ASAN "Enable AddressSanitizer to test memory safety" OFF)
option(SECCOMP "Link with seccomp and run seccomp tests" OFF)

# Turn BUILD_TESTING=ON by default
include(CTest)
Expand Down Expand Up @@ -452,6 +453,11 @@ if (BUILD_TESTING)
target_include_directories(testss2n PUBLIC tests)
target_compile_options(testss2n PRIVATE -std=gnu99)
target_link_libraries(testss2n PUBLIC ${PROJECT_NAME})
if (SECCOMP)
message(STATUS "Linking tests with seccomp")
target_link_libraries(testss2n PRIVATE seccomp)
target_compile_definitions(testss2n PRIVATE SECCOMP)
endif()

if (S2N_INTERN_LIBCRYPTO)
# if libcrypto was interned, rewrite libcrypto symbols so use of internal functions will link correctly
Expand Down
6 changes: 4 additions & 2 deletions tests/s2n_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

int test_count;

bool s2n_use_color_in_output = true;

/* Macro definitions for calls that occur within BEGIN_TEST() and END_TEST() to preserve the SKIPPED test behavior
* by ignoring the test_count, keeping it as 0 to indicate that a test was skipped. */
#define EXPECT_TRUE_WITHOUT_COUNT( condition ) do { if ( !(condition) ) { FAIL_MSG( #condition " is not true "); } } while(0)
Expand All @@ -40,7 +42,7 @@ int test_count;
#define EXPECT_SUCCESS_WITHOUT_COUNT( function_call ) EXPECT_NOT_EQUAL_WITHOUT_COUNT( (function_call) , -1 )

#define END_TEST_PRINT() \
if (isatty(fileno(stdout))) { \
if (s2n_use_color_in_output && isatty(fileno(stdout))) { \
if (test_count) { \
fprintf(stdout, "\033[32;1mPASSED\033[0m %10d tests\n", test_count ); \
} \
Expand Down Expand Up @@ -105,7 +107,7 @@ int test_count;
/* isatty and s2n_print_stacktrace will overwrite errno on failure */ \
int real_errno = errno; \
s2n_print_stacktrace(stderr); \
if (isatty(fileno(stderr))) { \
if (s2n_use_color_in_output && isatty(fileno(stderr))) { \
errno = real_errno; \
fprintf(stderr, "\033[31;1mFAILED test %d\033[0m\n%s (%s:%d)\nError Message: '%s'\n Debug String: '%s'\n System Error: %s (%d)\n", test_count, (msg), __FILE__, __LINE__, s2n_strerror(s2n_errno, "EN"), s2n_strerror_debug(s2n_errno, "EN"), strerror(errno), errno); \
} \
Expand Down
56 changes: 56 additions & 0 deletions tests/testlib/s2n_seccomp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

#include "testlib/s2n_testlib.h"
#include "utils/s2n_safety.h"

#ifdef SECCOMP

#include <seccomp.h>

DEFINE_POINTER_CLEANUP_FUNC(scmp_filter_ctx, seccomp_release);

extern bool s2n_use_color_in_output;

S2N_RESULT s2n_seccomp_init()
{
/* Using SCMP_ACT_TRAP instead of SCMP_ACT_KILL makes this test easier
* to debug. GDB will report exactly which syscalls triggered the signal.
*/
DEFER_CLEANUP(scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_TRAP),
seccomp_release_pointer);
RESULT_ENSURE_REF(ctx);

RESULT_GUARD_POSIX(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(brk), 0));
RESULT_GUARD_POSIX(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0));
RESULT_GUARD_POSIX(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0));
RESULT_GUARD_POSIX(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fstat), 0));
RESULT_GUARD_POSIX(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex), 0));
RESULT_GUARD_POSIX(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0));
RESULT_GUARD_POSIX(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0));

RESULT_GUARD_POSIX(seccomp_load(ctx));
s2n_use_color_in_output = false;
return S2N_RESULT_OK;
}

#else

S2N_RESULT s2n_seccomp_init()
{
return S2N_RESULT_OK;
}

#endif
2 changes: 2 additions & 0 deletions tests/testlib/s2n_testlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,3 +298,5 @@ S2N_RESULT s2n_resumption_test_ticket_key_setup(struct s2n_config *config);
#define S2N_CHECKED_BLOB_FROM_HEX(name, check, hex) \
DEFER_CLEANUP(struct s2n_blob name = { 0 }, s2n_free); \
check(s2n_blob_alloc_from_hex_with_whitespace(&name, (const char *) hex));

S2N_RESULT s2n_seccomp_init();
70 changes: 70 additions & 0 deletions tests/unit/s2n_seccomp_handshake_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

#include <stdio.h>
#include <string.h>
#include <seccomp.h>

#include "api/s2n.h"
#include "s2n_test.h"
#include "testlib/s2n_testlib.h"

int main(int argc, char **argv)
{
BEGIN_TEST();

/* We don't use s2n_test_cert_chain_and_key_new because we want to explicitly
* only do the PEM file read before enabling seccomp.
*/
char cert_chain_pem[S2N_MAX_TEST_PEM_SIZE] = { 0 };
char private_key_pem[S2N_MAX_TEST_PEM_SIZE] = { 0 };
EXPECT_SUCCESS(s2n_read_test_pem(S2N_DEFAULT_ECDSA_TEST_CERT_CHAIN, cert_chain_pem, S2N_MAX_TEST_PEM_SIZE));
EXPECT_SUCCESS(s2n_read_test_pem(S2N_DEFAULT_ECDSA_TEST_PRIVATE_KEY, private_key_pem, S2N_MAX_TEST_PEM_SIZE));

/* No unexpected syscalls allowed beyond this point */
EXPECT_OK(s2n_seccomp_init());

DEFER_CLEANUP(struct s2n_cert_chain_and_key *chain_and_key = s2n_cert_chain_and_key_new(),
s2n_cert_chain_and_key_ptr_free);
EXPECT_SUCCESS(s2n_cert_chain_and_key_load_pem(chain_and_key, cert_chain_pem, private_key_pem));

DEFER_CLEANUP(struct s2n_config *config = s2n_config_new_minimal(), s2n_config_ptr_free);
EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key));
EXPECT_SUCCESS(s2n_config_set_unsafe_for_testing(config));

const char* security_policies[] = { "default", "default_tls13" };

for (size_t i = 0; i < s2n_array_len(security_policies); i++) {
DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT),
s2n_connection_ptr_free);
EXPECT_NOT_NULL(client);
EXPECT_SUCCESS(s2n_connection_set_config(client, config));
EXPECT_SUCCESS(s2n_connection_set_cipher_preferences(client, security_policies[i]));

DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER),
s2n_connection_ptr_free);
EXPECT_NOT_NULL(server);
EXPECT_SUCCESS(s2n_connection_set_config(server, config));
EXPECT_SUCCESS(s2n_connection_set_cipher_preferences(server, security_policies[i]));

DEFER_CLEANUP(struct s2n_test_io_stuffer_pair io_pair = { 0 }, s2n_io_stuffer_pair_free);
EXPECT_OK(s2n_io_stuffer_pair_init(&io_pair));
EXPECT_OK(s2n_connections_set_io_stuffer_pair(client, server, &io_pair));
EXPECT_SUCCESS(s2n_negotiate_test_server_and_client(server, client));
}

END_TEST();
}

4 changes: 4 additions & 0 deletions utils/s2n_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ int s2n_init(void)
s2n_stack_traces_enabled_set(true);
}

#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
CRYPTO_pre_sandbox_init();
#endif

initialized = true;

return S2N_SUCCESS;
Expand Down

0 comments on commit f81fc75

Please sign in to comment.