Skip to content

Commit

Permalink
new(converter): add the scap file converter
Browse files Browse the repository at this point in the history
Signed-off-by: Andrea Terzolo <[email protected]>
  • Loading branch information
Andreagit97 committed Nov 22, 2024
1 parent f6d9f9b commit 5984e0f
Show file tree
Hide file tree
Showing 12 changed files with 796 additions and 2 deletions.
2 changes: 2 additions & 0 deletions driver/ppm_events_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -2056,6 +2056,8 @@ enum ppm_event_flags {
// overhead to full event capture */ SUPPORT DROPPED
EF_LARGE_PAYLOAD = (1 << 11), /* This event has a large payload, ie: up to UINT32_MAX bytes. DO
NOT USE ON syscalls-driven events!!! */
EF_TMP_CONVERTER_MANAGED = (1 << 12), /* todo!: this must be removed when we will mark ENTER
events as OLD_VERSION */
};

/*
Expand Down
5 changes: 5 additions & 0 deletions test/libscap/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ if(BUILD_LIBSCAP_GVISOR)
)# Used for <pkg/sentry/...> includes
endif()

file(GLOB_RECURSE SAVEFILE_TEST_SUITE
"${CMAKE_CURRENT_SOURCE_DIR}/test_suites/engines/savefile/*.cpp"
)
list(APPEND LIBSCAP_TESTS_SOURCES ${SAVEFILE_TEST_SUITE})

# Summary logs
set(LIBSCAP_UNIT_TESTS_PREFIX "[LIBSCAP UNIT TESTS]")
message(STATUS "${LIBSCAP_UNIT_TESTS_PREFIX} LIBSCAP_TESTS_SOURCES: ${LIBSCAP_TESTS_SOURCES}")
Expand Down
139 changes: 139 additions & 0 deletions test/libscap/test_suites/engines/savefile/convert_event_test.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License 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.
*/
#pragma once
#include <libscap/scap.h>
#include <gtest/gtest.h>
#include <cstdarg>
#include <memory>
#include <stdexcept>
#include <libscap/engine/savefile/converter/converter.h>

typedef std::shared_ptr<scap_evt> safe_scap_evt_t;
safe_scap_evt_t new_safe_scap_evt(scap_evt *evt) {
return safe_scap_evt_t{evt, free};
}
class convert_event_test : public testing::Test {
static constexpr uint16_t safe_margin = 100;

protected:
virtual void TearDown() {
// At every iteration we want to clear the storage in the converter
scap_clear_converter_storage();
}
safe_scap_evt_t create_safe_scap_event(uint64_t ts,
uint64_t tid,
ppm_event_code event_type,
uint32_t n,
...) {
char error[SCAP_LASTERR_SIZE] = {'\0'};
va_list args;
va_start(args, n);
scap_evt *evt = scap_create_event_v(error, ts, tid, event_type, n, args);
va_end(args);
if(evt == NULL) {
throw std::runtime_error("Error creating event: " + std::string(error));
}
return new_safe_scap_evt(evt);
}
// The expected result can be either CONVERSION_CONTINUE or CONVERSION_COMPLETED
void assert_single_conversion_success(enum conversion_result expected_res,
safe_scap_evt_t evt_to_convert,
safe_scap_evt_t expected_evt) {
char error[SCAP_LASTERR_SIZE] = {'\0'};
// We assume it's okay to create a new event with the same size as the expected event
auto storage = new_safe_scap_evt((scap_evt *)calloc(1, expected_evt->len));
// First we check the conversion result matches the expected result
ASSERT_EQ(scap_convert_event(storage.get(), evt_to_convert.get(), error), expected_res)
<< "Different conversion results: " << error;
if(!scap_compare_events(storage.get(), expected_evt.get(), error)) {
printf("\nExpected event:\n");
scap_print_event(expected_evt.get(), PRINT_FULL);
printf("\nConverted event:\n");
scap_print_event(storage.get(), PRINT_FULL);
FAIL() << error;
}
}
void assert_single_conversion_failure(safe_scap_evt_t evt_to_convert) {
char error[SCAP_LASTERR_SIZE] = {'\0'};
// We assume it's okay to create a new event with the same size as the expected event
auto storage = new_safe_scap_evt((scap_evt *)calloc(1, evt_to_convert->len));
// First we check the conversion result matches the expected result
ASSERT_EQ(scap_convert_event(storage.get(), evt_to_convert.get(), error), CONVERSION_ERROR)
<< "The conversion is not failed: " << error;
}
void assert_single_conversion_skip(safe_scap_evt_t evt_to_convert) {
char error[SCAP_LASTERR_SIZE] = {'\0'};
// We assume it's okay to create a new event with the same size as the expected event
auto storage = new_safe_scap_evt((scap_evt *)calloc(1, evt_to_convert->len));
// First we check the conversion result matches the expected result
ASSERT_EQ(scap_convert_event(storage.get(), evt_to_convert.get(), error), CONVERSION_SKIP)
<< "The conversion is not skipped: " << error;
}
void assert_full_conversion(safe_scap_evt_t evt_to_convert, safe_scap_evt_t expected_evt) {
char error[SCAP_LASTERR_SIZE] = {'\0'};
// Here we need to allocate more space than the expected event because in the middle we
// could have larger events. We could also use `MAX_EVENT_SIZE` but probably it will just
// slowdown tests.
auto to_convert_evt = new_safe_scap_evt(
(scap_evt *)calloc(1, expected_evt->len + convert_event_test::safe_margin));
auto new_evt = new_safe_scap_evt(
(scap_evt *)calloc(1, expected_evt->len + convert_event_test::safe_margin));
// We copy the event to convert into the new larger storage since during the conversions it
// could contain larger events than the initial one.
// We copy it in the new event to match the for loop logic.
memcpy(new_evt.get(), evt_to_convert.get(), evt_to_convert->len);
int conv_num = 0;
conversion_result conv_res = CONVERSION_CONTINUE;
for(conv_num = 0; conv_num < MAX_CONVERSION_BOUNDARY && conv_res == CONVERSION_CONTINUE;
conv_num++) {
// Copy the new event into the one to convert for the next conversion.
memcpy(to_convert_evt.get(), new_evt.get(), new_evt->len);
conv_res = scap_convert_event((scap_evt *)new_evt.get(),
(scap_evt *)to_convert_evt.get(),
error);
}
switch(conv_res) {
case CONVERSION_ERROR:
FAIL() << "Unexpected CONVERSION_ERROR: " << error;
case CONVERSION_SKIP:
FAIL() << "Unexpected CONVERSION_SKIP";
case CONVERSION_CONTINUE:
if(conv_num < MAX_CONVERSION_BOUNDARY) {
FAIL() << "Unexpected CONVERSION_CONTINUE without reaching max boundary";
} else {
FAIL() << "Unexpected CONVERSION_CONTINUE reaching max boundary";
}
default:
break;
}
if(!scap_compare_events(new_evt.get(), expected_evt.get(), error)) {
printf("\nExpected event:\n");
scap_print_event(expected_evt.get(), PRINT_FULL);
printf("\nConverted event:\n");
scap_print_event(new_evt.get(), PRINT_FULL);
FAIL() << error;
}
}
void assert_event_storage_presence(safe_scap_evt_t expected_evt) {
char error[SCAP_LASTERR_SIZE] = {'\0'};
int64_t tid = expected_evt.get()->tid;
auto event = scap_retrieve_evt_from_converter_storage(tid);
if(!event) {
FAIL() << "Event with tid " << tid << " not found in the storage";
}
if(!scap_compare_events(event, expected_evt.get(), error)) {
FAIL() << "Different events: " << error;
}
}
};
23 changes: 23 additions & 0 deletions test/libscap/test_suites/engines/savefile/converter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License 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 "convert_event_test.h"

// todo!: remove it when we will add the first example.
TEST_F(convert_event_test, tmp_example) {
uint64_t ts = 12;
int64_t tid = 25;

// At the moment we don't have event managed by the converter so this should fail.
assert_single_conversion_failure(create_safe_scap_event(ts, tid, PPME_SYSCALL_OPEN_E, 0));
}
8 changes: 6 additions & 2 deletions userspace/libscap/engine/savefile/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
#
# Since we have circular dependencies between libscap and the savefile engine, make this library
# always static (directly linked into libscap)
add_subdirectory(converter)
add_library(scap_engine_savefile STATIC scap_savefile.c scap_reader_gzfile.c scap_reader_buffered.c)

add_dependencies(scap_engine_savefile zlib)
target_link_libraries(scap_engine_savefile PRIVATE scap_engine_noop scap_platform_util ${ZLIB_LIB})
add_dependencies(scap_engine_savefile zlib scap_savefile_converter)
target_link_libraries(
scap_engine_savefile PRIVATE scap_engine_noop scap_platform_util scap_savefile_converter
${ZLIB_LIB}
)
23 changes: 23 additions & 0 deletions userspace/libscap/engine/savefile/converter/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2024 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License
# 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.
#

# Since we have circular dependencies between libscap and the savefile engine, make this library
# always static (directly linked into libscap)
add_library(scap_savefile_converter STATIC converter.cpp)

target_include_directories(
scap_savefile_converter PRIVATE ${LIBS_DIR} ${LIBS_DIR}/userspace
${LIBS_DIR}/userspace/libscap/engine/savefile
)
Loading

0 comments on commit 5984e0f

Please sign in to comment.