Skip to content

Commit fd56382

Browse files
committed
new(converter): add the scap file converter
Signed-off-by: Andrea Terzolo <[email protected]>
1 parent b8412df commit fd56382

File tree

12 files changed

+797
-2
lines changed

12 files changed

+797
-2
lines changed

driver/ppm_events_public.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2056,6 +2056,8 @@ enum ppm_event_flags {
20562056
// overhead to full event capture */ SUPPORT DROPPED
20572057
EF_LARGE_PAYLOAD = (1 << 11), /* This event has a large payload, ie: up to UINT32_MAX bytes. DO
20582058
NOT USE ON syscalls-driven events!!! */
2059+
EF_TMP_CONVERTER_MANAGED = (1 << 12), /* todo!: this must be removed when we will mark ENTER
2060+
events as OLD_VERSION */
20592061
};
20602062

20612063
/*

test/libscap/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ if(BUILD_LIBSCAP_GVISOR)
9292
)# Used for <pkg/sentry/...> includes
9393
endif()
9494

95+
file(GLOB_RECURSE SAVEFILE_TEST_SUITE
96+
"${CMAKE_CURRENT_SOURCE_DIR}/test_suites/engines/savefile/*.cpp"
97+
)
98+
list(APPEND LIBSCAP_TESTS_SOURCES ${SAVEFILE_TEST_SUITE})
99+
95100
# Summary logs
96101
set(LIBSCAP_UNIT_TESTS_PREFIX "[LIBSCAP UNIT TESTS]")
97102
message(STATUS "${LIBSCAP_UNIT_TESTS_PREFIX} LIBSCAP_TESTS_SOURCES: ${LIBSCAP_TESTS_SOURCES}")
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
/*
3+
Copyright (C) 2024 The Falco Authors.
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
Unless required by applicable law or agreed to in writing, software
9+
distributed under the License is distributed on an "AS IS" BASIS,
10+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
See the License for the specific language governing permissions and
12+
limitations under the License.
13+
*/
14+
#pragma once
15+
#include <libscap/scap.h>
16+
#include <gtest/gtest.h>
17+
#include <cstdarg>
18+
#include <memory>
19+
#include <stdexcept>
20+
#include <libscap/engine/savefile/converter/converter.h>
21+
22+
typedef std::shared_ptr<scap_evt> safe_scap_evt_t;
23+
safe_scap_evt_t new_safe_scap_evt(scap_evt *evt) {
24+
return safe_scap_evt_t{evt, free};
25+
}
26+
class convert_event_test : public testing::Test {
27+
static constexpr uint16_t safe_margin = 100;
28+
29+
protected:
30+
virtual void TearDown() {
31+
// At every iteration we want to clear the storage in the converter
32+
scap_clear_converter_storage();
33+
}
34+
safe_scap_evt_t create_safe_scap_event(uint64_t ts,
35+
uint64_t tid,
36+
ppm_event_code event_type,
37+
uint32_t n,
38+
...) {
39+
char error[SCAP_LASTERR_SIZE] = {'\0'};
40+
va_list args;
41+
va_start(args, n);
42+
scap_evt *evt = scap_create_event_v(error, ts, tid, event_type, n, args);
43+
va_end(args);
44+
if(evt == NULL) {
45+
throw std::runtime_error("Error creating event: " + std::string(error));
46+
}
47+
return new_safe_scap_evt(evt);
48+
}
49+
// The expected result can be either CONVERSION_CONTINUE or CONVERSION_COMPLETED
50+
void assert_single_conversion_success(enum conversion_result expected_res,
51+
safe_scap_evt_t evt_to_convert,
52+
safe_scap_evt_t expected_evt) {
53+
char error[SCAP_LASTERR_SIZE] = {'\0'};
54+
// We assume it's okay to create a new event with the same size as the expected event
55+
auto storage = new_safe_scap_evt((scap_evt *)calloc(1, expected_evt->len));
56+
// First we check the conversion result matches the expected result
57+
ASSERT_EQ(scap_convert_event(storage.get(), evt_to_convert.get(), error), expected_res)
58+
<< "Different conversion results: " << error;
59+
if(!scap_compare_events(storage.get(), expected_evt.get(), error)) {
60+
printf("\nExpected event:\n");
61+
scap_print_event(expected_evt.get(), PRINT_FULL);
62+
printf("\nConverted event:\n");
63+
scap_print_event(storage.get(), PRINT_FULL);
64+
FAIL() << error;
65+
}
66+
}
67+
void assert_single_conversion_failure(safe_scap_evt_t evt_to_convert) {
68+
char error[SCAP_LASTERR_SIZE] = {'\0'};
69+
// We assume it's okay to create a new event with the same size as the expected event
70+
auto storage = new_safe_scap_evt((scap_evt *)calloc(1, evt_to_convert->len));
71+
// First we check the conversion result matches the expected result
72+
ASSERT_EQ(scap_convert_event(storage.get(), evt_to_convert.get(), error), CONVERSION_ERROR)
73+
<< "The conversion is not failed: " << error;
74+
}
75+
void assert_single_conversion_skip(safe_scap_evt_t evt_to_convert) {
76+
char error[SCAP_LASTERR_SIZE] = {'\0'};
77+
// We assume it's okay to create a new event with the same size as the expected event
78+
auto storage = new_safe_scap_evt((scap_evt *)calloc(1, evt_to_convert->len));
79+
// First we check the conversion result matches the expected result
80+
ASSERT_EQ(scap_convert_event(storage.get(), evt_to_convert.get(), error), CONVERSION_SKIP)
81+
<< "The conversion is not skipped: " << error;
82+
}
83+
void assert_full_conversion(safe_scap_evt_t evt_to_convert, safe_scap_evt_t expected_evt) {
84+
char error[SCAP_LASTERR_SIZE] = {'\0'};
85+
// Here we need to allocate more space than the expected event because in the middle we
86+
// could have larger events. We could also use `MAX_EVENT_SIZE` but probably it will just
87+
// slowdown tests.
88+
auto to_convert_evt = new_safe_scap_evt(
89+
(scap_evt *)calloc(1, expected_evt->len + convert_event_test::safe_margin));
90+
auto new_evt = new_safe_scap_evt(
91+
(scap_evt *)calloc(1, expected_evt->len + convert_event_test::safe_margin));
92+
// We copy the event to convert into the new larger storage since during the conversions it
93+
// could contain larger events than the initial one.
94+
// We copy it in the new event to match the for loop logic.
95+
memcpy(new_evt.get(), evt_to_convert.get(), evt_to_convert->len);
96+
int conv_num = 0;
97+
conversion_result conv_res = CONVERSION_CONTINUE;
98+
for(conv_num = 0; conv_num < MAX_CONVERSION_BOUNDARY && conv_res == CONVERSION_CONTINUE;
99+
conv_num++) {
100+
// Copy the new event into the one to convert for the next conversion.
101+
memcpy(to_convert_evt.get(), new_evt.get(), new_evt->len);
102+
conv_res = scap_convert_event((scap_evt *)new_evt.get(),
103+
(scap_evt *)to_convert_evt.get(),
104+
error);
105+
}
106+
switch(conv_res) {
107+
case CONVERSION_ERROR:
108+
FAIL() << "Unexpected CONVERSION_ERROR: " << error;
109+
case CONVERSION_SKIP:
110+
FAIL() << "Unexpected CONVERSION_SKIP";
111+
case CONVERSION_CONTINUE:
112+
if(conv_num < MAX_CONVERSION_BOUNDARY) {
113+
FAIL() << "Unexpected CONVERSION_CONTINUE without reaching max boundary";
114+
} else {
115+
FAIL() << "Unexpected CONVERSION_CONTINUE reaching max boundary";
116+
}
117+
default:
118+
break;
119+
}
120+
if(!scap_compare_events(new_evt.get(), expected_evt.get(), error)) {
121+
printf("\nExpected event:\n");
122+
scap_print_event(expected_evt.get(), PRINT_FULL);
123+
printf("\nConverted event:\n");
124+
scap_print_event(new_evt.get(), PRINT_FULL);
125+
FAIL() << error;
126+
}
127+
}
128+
void assert_event_storage_presence(safe_scap_evt_t expected_evt) {
129+
char error[SCAP_LASTERR_SIZE] = {'\0'};
130+
int64_t tid = expected_evt.get()->tid;
131+
auto event = scap_retrieve_evt_from_converter_storage(tid);
132+
if(!event) {
133+
FAIL() << "Event with tid " << tid << " not found in the storage";
134+
}
135+
if(!scap_compare_events(event, expected_evt.get(), error)) {
136+
FAIL() << "Different events: " << error;
137+
}
138+
}
139+
};
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
/*
3+
Copyright (C) 2024 The Falco Authors.
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
Unless required by applicable law or agreed to in writing, software
9+
distributed under the License is distributed on an "AS IS" BASIS,
10+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
See the License for the specific language governing permissions and
12+
limitations under the License.
13+
*/
14+
#include "convert_event_test.h"
15+
16+
// todo!: remove it when we will add the first example.
17+
TEST_F(convert_event_test, tmp_example) {
18+
uint64_t ts = 12;
19+
int64_t tid = 25;
20+
21+
// At the moment we don't have event managed by the converter so this should fail.
22+
assert_single_conversion_failure(create_safe_scap_event(ts, tid, PPME_SYSCALL_OPEN_E, 0));
23+
}

userspace/libscap/engine/savefile/CMakeLists.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@
1414
#
1515
# Since we have circular dependencies between libscap and the savefile engine, make this library
1616
# always static (directly linked into libscap)
17+
add_subdirectory(converter)
1718
add_library(scap_engine_savefile STATIC scap_savefile.c scap_reader_gzfile.c scap_reader_buffered.c)
1819

19-
add_dependencies(scap_engine_savefile zlib)
20-
target_link_libraries(scap_engine_savefile PRIVATE scap_engine_noop scap_platform_util ${ZLIB_LIB})
20+
add_dependencies(scap_engine_savefile zlib scap_savefile_converter)
21+
target_link_libraries(
22+
scap_engine_savefile PRIVATE scap_engine_noop scap_platform_util scap_savefile_converter
23+
${ZLIB_LIB}
24+
)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
# Copyright (C) 2024 The Falco Authors.
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
7+
# in compliance with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software distributed under the License
12+
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
13+
# or implied. See the License for the specific language governing permissions and limitations under
14+
# the License.
15+
#
16+
17+
# Since we have circular dependencies between libscap and the savefile engine, make this library
18+
# always static (directly linked into libscap)
19+
add_library(scap_savefile_converter STATIC converter.cpp)
20+
21+
target_include_directories(
22+
scap_savefile_converter PRIVATE ${LIBS_DIR} ${LIBS_DIR}/userspace
23+
${LIBS_DIR}/userspace/libscap/engine/savefile
24+
)

0 commit comments

Comments
 (0)