Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new(tests): add some libsinsp tests #1791

Merged
merged 5 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions driver/modern_bpf/helpers/store/auxmap_store_params.h
Original file line number Diff line number Diff line change
Expand Up @@ -720,11 +720,18 @@ static __always_inline void auxmap__store_socktuple_param(struct auxiliary_map *
}

unsigned long start_reading_point;
/* We have to skip the two bytes of socket family. */
char first_path_byte = *(char *)path;
if(first_path_byte == '\0')
{
/* This is an abstract socket address, we need to skip the initial `\0`. */
/* Please note exceptions in the `sun_path`:
* Taken from: https://man7.org/linux/man-pages/man7/unix.7.html
*
* An `abstract socket address` is distinguished (from a
* pathname socket) by the fact that sun_path[0] is a null byte
* ('\0').
*
* So in this case, we need to skip the initial `\0`.
*/
start_reading_point = (unsigned long)path + 1;
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def test_db_program_spawned_process(sinsp, run_containers: dict):
},
{
"container.id": generator_id,
"evt.args": "filename=/bin/ls ",
"evt.args": "filename=/bin/ls",
"evt.category": "process",
"evt.num": SinspField.numeric_field(),
"evt.time": SinspField.numeric_field(),
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/tests/test_event_generator/test_file_writes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


def create_expected_arg(directory: str) -> str:
return fr'^fd=3\(<f>{re.escape(directory)}\/created-by-event-generator\) dirfd=-100\(AT_FDCWD\) name={re.escape(directory)}\/created-by-event-generator flags=20742\(O_TRUNC\|O_CREAT\|O_WRONLY\|O_CLOEXEC\|O_F_CREATED\) mode=0755 dev=.* ino=\d+ $'
return fr'^fd=3\(<f>{re.escape(directory)}\/created-by-event-generator\) dirfd=-100\(AT_FDCWD\) name={re.escape(directory)}\/created-by-event-generator flags=20742\(O_TRUNC\|O_CREAT\|O_WRONLY\|O_CLOEXEC\|O_F_CREATED\) mode=0755 dev=.* ino=\d+$'


def generate_ids(parameters: list) -> list:
Expand Down
6 changes: 3 additions & 3 deletions test/e2e/tests/test_event_generator/test_make_binary_dirs.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def test_make_binary_dirs(sinsp, run_containers: dict):
"thread.tid": SinspField.numeric_field()
},
{
"evt.args": "res=0 dirfd=-100(AT_FDCWD) path=/bin/directory-created-by-event-generator mode=1ED ",
"evt.args": "res=0 dirfd=-100(AT_FDCWD) path=/bin/directory-created-by-event-generator mode=1ED",
"evt.cpu": SinspField.numeric_field(),
"evt.dir": "<",
"evt.num": SinspField.numeric_field(),
Expand All @@ -55,7 +55,7 @@ def test_make_binary_dirs(sinsp, run_containers: dict):
"thread.tid": SinspField.numeric_field()
},
{
"evt.args": "res=-21(EISDIR) dirfd=-100(AT_FDCWD) name=/bin/directory-created-by-event-generator flags=0 ",
"evt.args": "res=-21(EISDIR) dirfd=-100(AT_FDCWD) name=/bin/directory-created-by-event-generator flags=0",
"evt.cpu": SinspField.numeric_field(),
"evt.dir": "<",
"evt.num": SinspField.numeric_field(),
Expand All @@ -75,7 +75,7 @@ def test_make_binary_dirs(sinsp, run_containers: dict):
"thread.tid": SinspField.numeric_field()
},
{
"evt.args": "res=0 dirfd=-100(AT_FDCWD) name=/bin/directory-created-by-event-generator flags=512(AT_REMOVEDIR) ",
"evt.args": "res=0 dirfd=-100(AT_FDCWD) name=/bin/directory-created-by-event-generator flags=512(AT_REMOVEDIR)",
"evt.cpu": SinspField.numeric_field(),
"evt.dir": "<",
"evt.num": SinspField.numeric_field(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def test_modify_binary_dirs(sinsp, run_containers: dict):
"thread.tid": SinspField.numeric_field()
},
{
"evt.args": "res=0 olddirfd=-100(AT_FDCWD) oldpath=/bin/true newdirfd=-100(AT_FDCWD) newpath=/bin/true.event-generator ",
"evt.args": "res=0 olddirfd=-100(AT_FDCWD) oldpath=/bin/true newdirfd=-100(AT_FDCWD) newpath=/bin/true.event-generator",
"evt.cpu": SinspField.numeric_field(),
"evt.dir": "<",
"evt.num": SinspField.numeric_field(),
Expand All @@ -55,7 +55,7 @@ def test_modify_binary_dirs(sinsp, run_containers: dict):
"thread.tid": SinspField.numeric_field()
},
{
"evt.args": "res=0 olddirfd=-100(AT_FDCWD) oldpath=/bin/true.event-generator newdirfd=-100(AT_FDCWD) newpath=/bin/true ",
"evt.args": "res=0 olddirfd=-100(AT_FDCWD) oldpath=/bin/true.event-generator newdirfd=-100(AT_FDCWD) newpath=/bin/true",
"evt.cpu": SinspField.numeric_field(),
"evt.dir": "<",
"evt.num": SinspField.numeric_field(),
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/tests/test_event_generator/test_network_activity.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def test_network_activity(sinsp, run_containers: dict):
expected_events = [
{
"container.id": generator_id,
"evt.args": "fd=3(<4>) addr=10.2.3.4:8192 ",
"evt.args": "fd=3(<4>) addr=10.2.3.4:8192",
"evt.category": "net",
"evt.num": SinspField.numeric_field(),
"evt.time": SinspField.numeric_field(),
Expand All @@ -43,7 +43,7 @@ def test_network_activity(sinsp, run_containers: dict):
},
{
"container.id": generator_id,
"evt.args": SinspField.regex_field(fr'^res=0 tuple={ipv4_regex}->10\.2\.3\.4:8192 fd=3\(<4u>{ipv4_regex}->10\.2\.3\.4:8192\) $'),
"evt.args": SinspField.regex_field(fr'^res=0 tuple={ipv4_regex}->10\.2\.3\.4:8192 fd=3\(<4u>{ipv4_regex}->10\.2\.3\.4:8192\)$'),
"evt.category": "net",
"evt.num": SinspField.numeric_field(),
"evt.time": SinspField.numeric_field(),
Expand Down
8 changes: 4 additions & 4 deletions test/e2e/tests/test_event_generator/test_non_sudo_setuid.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,25 @@ def test_non_sudo_setuid(sinsp, run_containers):

expected_events = [
{
"evt.args": "uid=2(<NA>) ",
"evt.args": "uid=2(<NA>)",
"evt.dir": ">",
"evt.type": "setuid",
"proc.name": "child",
},
{
"evt.args": "res=0 ",
"evt.args": "res=0",
"evt.dir": "<",
"evt.type": "setuid",
"proc.name": "child",
},
{
"evt.args": "uid=0(<NA>) ",
"evt.args": "uid=0(<NA>)",
"evt.dir": ">",
"evt.type": "setuid",
"proc.name": "child",
},
{
"evt.args": "res=-1(EPERM) ",
"evt.args": "res=-1(EPERM)",
"evt.dir": "<",
"evt.type": "setuid",
"proc.name": "child",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def test_read_sensitive_file(sinsp, run_containers: dict, expected_process: str)

expected_events = [
{
"evt.args": SinspField.regex_field(r'fd=3\(<f>/etc/shadow\) dirfd=-100\(AT_FDCWD\) name=/etc/shadow flags=4097\(O_RDONLY|O_CLOEXEC\) mode=0 dev=\W+ ino=\d+ '),
"evt.args": SinspField.regex_field(r'fd=3\(<f>/etc/shadow\) dirfd=-100\(AT_FDCWD\) name=/etc/shadow flags=4097\(O_RDONLY|O_CLOEXEC\) mode=0 dev=\W+ ino=\d+'),
"evt.cpu": SinspField.numeric_field(),
"evt.dir": "<",
"evt.num": SinspField.numeric_field(),
Expand Down
18 changes: 9 additions & 9 deletions test/e2e/tests/test_network/test_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,61 +32,61 @@ def expected_events(origin: dict, destination: dict) -> list:
return [
{
"container.id": origin['id'],
"evt.args": "domain=2(AF_INET) type=1 proto=0 ",
"evt.args": "domain=2(AF_INET) type=1 proto=0",
"evt.category": "net",
"evt.type": "socket",
"fd.name": None,
"proc.cmdline": f"curl --local-port {origin['local_port']} {destination['ip']}",
"proc.exe": "curl",
}, {
"container.id": origin['id'],
"evt.args": "fd=3(<4>) ",
"evt.args": "fd=3(<4>)",
"evt.category": "net",
"evt.type": "socket",
"fd.name": "",
"proc.cmdline": f"curl --local-port {origin['local_port']} {destination['ip']}",
"proc.exe": "curl",
}, {
"container.id": origin['id'],
"evt.args": f"fd=3(<4t>0.0.0.0:{origin['local_port']}) addr={destination['ip']} ",
"evt.args": f"fd=3(<4t>0.0.0.0:{origin['local_port']}) addr={destination['ip']}",
"evt.category": "net",
"evt.type": "connect",
"fd.name": f"0.0.0.0:{origin['local_port']}",
"proc.cmdline": f"curl --local-port {origin['local_port']} {destination['ip']}",
"proc.exe": "curl",
}, {
"container.id": destination['id'],
"evt.args": "flags=0 ",
"evt.args": "flags=0",
"evt.category": "net",
"evt.type": "accept4",
"fd.name": None,
"proc.cmdline": "nginx",
"proc.exe": "nginx: master proces",
}, {
"container.id": destination['id'],
"evt.args": f"fd=3(<4t>{origin['ip']}->{destination['ip']}) tuple={origin['ip']}->{destination['ip']} queuepct=0 queuelen=0 queuemax=511 ",
"evt.args": f"fd=3(<4t>{origin['ip']}->{destination['ip']}) tuple={origin['ip']}->{destination['ip']} queuepct=0 queuelen=0 queuemax=511",
"evt.category": "net",
"evt.type": "accept4",
"fd.name": f"{origin['ip']}->{destination['ip']}",
"proc.cmdline": "nginx",
"proc.exe": "nginx: master proces",
}, {
"evt.args": f"fd=3(<4t>{origin['ip']}->{destination['ip']}) ",
"evt.args": f"fd=3(<4t>{origin['ip']}->{destination['ip']})",
"evt.dir": ">",
"evt.type": "close",
"proc.name": "curl",
}, {
"evt.args": "res=0 ",
"evt.args": "res=0",
"evt.dir": "<",
"evt.type": "close",
"proc.name": "curl",
}, {
"evt.args": f"fd=3(<4t>{origin['ip']}->{destination['ip']}) ",
"evt.args": f"fd=3(<4t>{origin['ip']}->{destination['ip']})",
"evt.dir": ">",
"evt.type": "close",
"proc.name": "nginx",
}, {
"evt.args": "res=0 ",
"evt.args": "res=0",
"evt.dir": "<",
"evt.type": "close",
"proc.name": "nginx",
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/tests/test_process/test_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def test_exec_in_container(sinsp, run_containers: dict):
expected_events = [
{
'container.id': container_id,
'evt.args': 'filename=/http-echo ',
'evt.args': 'filename=/http-echo',
'evt.category': 'process',
'evt.type': 'execve',
'proc.exe': 'runc',
Expand Down
4 changes: 4 additions & 0 deletions userspace/libsinsp/sinsp_filtercheck_event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1135,6 +1135,10 @@ uint8_t* sinsp_filter_check_event::extract(sinsp_evt *evt, OUT uint32_t* len, bo
}
}

if(!m_strstorage.empty())
{
m_strstorage.pop_back();
}
RETURN_EXTRACT_STRING(m_strstorage);
}
break;
Expand Down
1 change: 1 addition & 0 deletions userspace/libsinsp/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ if(WIN32)
elseif(APPLE OR EMSCRIPTEN)
list(REMOVE_ITEM LIBSINSP_UNIT_TESTS_SOURCES
events_net.ut.cpp
${CMAKE_CURRENT_SOURCE_DIR}/parsers/parse_connect.cpp
)
endif()

Expand Down
37 changes: 36 additions & 1 deletion userspace/libsinsp/test/filterchecks/evt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,39 @@ TEST_F(sinsp_with_test_input, EVT_FILTER_cmd_str)
sinsp_evt* evt = add_event_advance_ts(increasing_ts(), 1, PPME_SYSCALL_BPF_2_X, 2, fd, (uint64_t)PPM_BPF_PROG_LOAD);

ASSERT_EQ(get_field_as_string(evt, "evt.arg.cmd"), "BPF_PROG_LOAD");
}
}
TEST_F(sinsp_with_test_input, EVT_FILTER_check_evt_arg_uid)
{
add_default_init_thread();
open_inspector();

uint32_t user_id = 5;
std::string container_id = "";
auto evt = add_event_advance_ts(increasing_ts(), INIT_TID, PPME_SYSCALL_SETUID_E, 1, user_id);
ASSERT_EQ(get_field_as_string(evt, "evt.type"), "setuid");

// The rawarg provides the field directly from the table.
ASSERT_EQ(get_field_as_string(evt, "evt.rawarg.uid"), std::to_string(user_id));

// The `evt.arg.uid` tries to find a user in the user table, in this
// case the user table is empty.
ASSERT_EQ(get_field_as_string(evt, "evt.arg.uid"), "<NA>");
ASSERT_EQ(get_field_as_string(evt, "evt.arg[0]"), "<NA>");
ASSERT_EQ(get_field_as_string(evt, "evt.args"), "uid=5(<NA>)");

// we are adding a user on the host so the `pid` parameter is not considered
ASSERT_TRUE(m_inspector.m_usergroup_manager.add_user(container_id, 0, user_id, 6, "test", "/test", "/bin/test"));

// Now we should have the necessary info
ASSERT_EQ(get_field_as_string(evt, "evt.arg.uid"), "test");
ASSERT_EQ(get_field_as_string(evt, "evt.arg[0]"), "test");
ASSERT_EQ(get_field_as_string(evt, "evt.args"), "uid=5(test)");

// We remove the user, and the fields should be empty again
m_inspector.m_usergroup_manager.rm_user(container_id, user_id);
ASSERT_FALSE(m_inspector.m_usergroup_manager.get_user(container_id, user_id));

ASSERT_EQ(get_field_as_string(evt, "evt.arg.uid"), "<NA>");
ASSERT_EQ(get_field_as_string(evt, "evt.arg[0]"), "<NA>");
ASSERT_EQ(get_field_as_string(evt, "evt.args"), "uid=5(<NA>)");
}
93 changes: 93 additions & 0 deletions userspace/libsinsp/test/parsers/parse_connect.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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 <gtest/gtest.h>
#include <test/sinsp_with_test_input.h>
#include <test/test_utils.h>

// Note:
// 1. We don't save the type of the unix socket: datagram or stream
// 2. Do we want to keep the tuple in this way `9c758d0f->9c758d0a /tmp/stream.sock`?
TEST_F(sinsp_with_test_input, CONNECT_parse_unix_socket)
{
add_default_init_thread();
open_inspector();

int64_t return_value = 0;
int64_t client_fd = 9;

// We need the enter event because we store it and we use it in the exit one.
// We only store it, we don't create a fdinfo, if the enter event is missing
// we don't parse the exit one.
auto evt = add_event_advance_ts(increasing_ts(), INIT_TID, PPME_SOCKET_SOCKET_E, 3, (uint32_t)PPM_AF_UNIX,
(uint32_t)SOCK_STREAM, (uint32_t)0);
auto fdinfo = evt->get_fd_info();
ASSERT_FALSE(fdinfo);

evt = add_event_advance_ts(increasing_ts(), INIT_TID, PPME_SOCKET_SOCKET_X, 1, client_fd);

/* FDINFO associated with the event */
fdinfo = evt->get_fd_info();
ASSERT_TRUE(fdinfo);
ASSERT_TRUE(fdinfo->is_unix_socket());
// todo! do we want this? In the end a unix socket could be of type datagram or stream
ASSERT_EQ(fdinfo->get_l4proto(), scap_l4_proto::SCAP_L4_NA);
ASSERT_TRUE(fdinfo->is_role_none());
ASSERT_FALSE(fdinfo->is_socket_connected());
// The socket syscall doesn't populate the name of the socket
ASSERT_EQ(fdinfo->m_name, "");

/* FDINFO associated with the thread */
auto init_tinfo = m_inspector.get_thread_ref(INIT_TID, false).get();
ASSERT_TRUE(init_tinfo);
fdinfo = init_tinfo->get_fd(client_fd);
ASSERT_TRUE(fdinfo);
ASSERT_TRUE(fdinfo->is_unix_socket());
ASSERT_EQ(fdinfo->get_l4proto(), scap_l4_proto::SCAP_L4_NA);
ASSERT_TRUE(fdinfo->is_role_none());
ASSERT_FALSE(fdinfo->is_socket_connected());
ASSERT_EQ(fdinfo->m_name, "");

// We don't need the enter event!
std::vector<uint8_t> socktuple = test_utils::pack_unix_socktuple(0x9c758d0f, 0x9c758d0a, "/tmp/stream.sock");
evt = add_event_advance_ts(increasing_ts(), INIT_TID, PPME_SOCKET_CONNECT_X, 3, return_value,
scap_const_sized_buffer{socktuple.data(), socktuple.size()}, client_fd);

/* FDINFO associated with the event */
fdinfo = evt->get_fd_info();
ASSERT_TRUE(fdinfo);
ASSERT_TRUE(fdinfo->is_unix_socket());
ASSERT_EQ(fdinfo->get_l4proto(), scap_l4_proto::SCAP_L4_NA);
ASSERT_TRUE(fdinfo->is_role_client());
ASSERT_TRUE(fdinfo->is_socket_connected());
// Note: `9c758d0f` is the kernel pointer to the socket that performs the connection.
// `9c758d0a` is the kernel pointer to the socket that receives the connection.
ASSERT_EQ(fdinfo->m_name, "9c758d0f->9c758d0a /tmp/stream.sock");
// we don't have code to populate this `m_name_raw` for sockets.
ASSERT_EQ(fdinfo->m_name_raw, "");

/* FDINFO associated with the thread */
fdinfo = init_tinfo->get_fd(client_fd);
ASSERT_TRUE(fdinfo);
ASSERT_TRUE(fdinfo->is_unix_socket());
ASSERT_EQ(fdinfo->get_l4proto(), scap_l4_proto::SCAP_L4_NA);
ASSERT_TRUE(fdinfo->is_role_client());
ASSERT_TRUE(fdinfo->is_socket_connected());
ASSERT_EQ(fdinfo->m_name, "9c758d0f->9c758d0a /tmp/stream.sock");
ASSERT_EQ(fdinfo->m_name_raw, "");
}
Loading
Loading