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(libsinsp): sinsp_repair_state_sc_set ppm sc API #826

Merged
merged 5 commits into from Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 17 additions & 0 deletions userspace/libsinsp/events/sinsp_events.h
Expand Up @@ -189,6 +189,23 @@ set<ppm_sc_code> names_to_sc_set(const std::unordered_set<std::string>& syscalls
*/
set<ppm_event_code> sc_set_to_event_set(const set<ppm_sc_code> &ppm_sc_of_interest);

/*!
* \brief [Experimental] Enforce sinsp state `ppm_sc` set conditioned by filter `ppm_sc` set.
* This has a resource-conscious effect in that the driver only subscribes to a set of `ppm_sc`
* that is effectively needed for the absolute minimum sinsp state build-up and
* life-cycle management.
*
* In addition, this option can be used to "repair" a custom set of user defined `ppm_sc`
* to ensure Falco runs correctly.
*
* TODO @incertum create new e2e test format to model sinsp state dependencies.
*
* @param ppm_sc_set set of `ppm_sc` from filter(s)
* @return sinsp state compliant set of `ppm_sc` conditioned by set of `ppm_sc` from filter(s)
*/
set<ppm_sc_code> sinsp_repair_state_sc_set(const set<ppm_sc_code>& ppm_sc_set);


/*=============================== PPM_SC set related (sinsp_events_ppm_sc.cpp) ===============================*/

/*=============================== PPME set related (sinsp_events.cpp) ===============================*/
Expand Down
75 changes: 75 additions & 0 deletions userspace/libsinsp/events/sinsp_events_ppm_sc.cpp
Expand Up @@ -18,6 +18,14 @@ limitations under the License.
#include "sinsp_events.h"
#include "../utils.h"

/*
* Repair base syscalls flags.
*/
#define PPM_ADAPTIVE_SC_NETWORK_BASE (1 << 0)
#define PPM_ADAPTIVE_SC_NETWORK_BIND (1 << 1)
#define PPM_ADAPTIVE_SC_FD_CLOSE (1 << 2)


libsinsp::events::set<ppm_sc_code> libsinsp::events::sinsp_state_sc_set()
{
static libsinsp::events::set<ppm_sc_code> ppm_sc_set;
Expand Down Expand Up @@ -312,3 +320,70 @@ std::unordered_set<std::string> libsinsp::events::sc_set_to_names(const libsinsp
}
return ppm_sc_names_set;
}

libsinsp::events::set<ppm_sc_code> libsinsp::events::sinsp_repair_state_sc_set(const libsinsp::events::set<ppm_sc_code>& ppm_sc_set)
Andreagit97 marked this conversation as resolved.
Show resolved Hide resolved
{
uint32_t flags = 0;
if (!libsinsp::events::net_sc_set().intersect(ppm_sc_set).empty())
{
flags |= PPM_ADAPTIVE_SC_NETWORK_BASE;
flags |= PPM_ADAPTIVE_SC_FD_CLOSE;
}

static libsinsp::events::set<ppm_sc_code> accept_listen_sc_set = {PPM_SC_ACCEPT, PPM_SC_ACCEPT4, PPM_SC_LISTEN};
if (!accept_listen_sc_set.intersect(ppm_sc_set).empty())
{
flags |= PPM_ADAPTIVE_SC_NETWORK_BASE;
Andreagit97 marked this conversation as resolved.
Show resolved Hide resolved
flags |= PPM_ADAPTIVE_SC_NETWORK_BIND;
flags |= PPM_ADAPTIVE_SC_FD_CLOSE;
}

if (!libsinsp::events::file_sc_set().intersect(ppm_sc_set).empty() ||
!libsinsp::events::io_sc_set().intersect(ppm_sc_set).empty() ||
!libsinsp::events::io_other_sc_set().intersect(ppm_sc_set).empty())
{
flags |= PPM_ADAPTIVE_SC_FD_CLOSE;
}

/* These syscalls are used to build up or modify info of the basic process (tinfo) struct.
* Consistent enforcement regardless of the input ppm_sc_set.
*/
libsinsp::events::set<ppm_sc_code> repaired_sinsp_state_sc_set = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this could be the right place to enforce PPM_SC_SCHED_PROCESS_EXIT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! Nice, since now we can do it, left a comment stating that it is ok if this enforcement is redundant in case we decide to also enforce PPM_SC_SCHED_PROCESS_EXIT elsewhere.

@jasondellaluce when we refactor sc_names_to_sc_set and/or create event_names_to_sc_set need to also include the tp now ...

PPM_SC_CLONE,
PPM_SC_CLONE3,
PPM_SC_FORK,
PPM_SC_VFORK,
PPM_SC_EXECVE,
PPM_SC_EXECVEAT,
PPM_SC_FCHDIR,
PPM_SC_CHDIR,
PPM_SC_CHROOT,
PPM_SC_CAPSET,
PPM_SC_SETGID,
PPM_SC_SETGID32,
PPM_SC_SETPGID,
PPM_SC_SETRESGID,
PPM_SC_SETRESGID32,
PPM_SC_SETRESUID,
PPM_SC_SETRESUID32,
PPM_SC_SETSID,
PPM_SC_SETUID,
PPM_SC_SETUID32,
};

if ((flags & PPM_ADAPTIVE_SC_NETWORK_BASE))
{
repaired_sinsp_state_sc_set.insert(PPM_SC_SOCKET);
repaired_sinsp_state_sc_set.insert(PPM_SC_GETSOCKOPT);
Andreagit97 marked this conversation as resolved.
Show resolved Hide resolved
}
if ((flags & PPM_ADAPTIVE_SC_NETWORK_BIND))
{
repaired_sinsp_state_sc_set.insert(PPM_SC_BIND);
}
if ((flags & PPM_ADAPTIVE_SC_FD_CLOSE))
{
repaired_sinsp_state_sc_set.insert(PPM_SC_CLOSE);
}

return repaired_sinsp_state_sc_set;
}
55 changes: 55 additions & 0 deletions userspace/libsinsp/test/public_sinsp_API/interesting_syscalls.cpp
Expand Up @@ -162,3 +162,58 @@ TEST(interesting_syscalls, event_set_to_sc_set_generic_events)
ASSERT_TRUE(sc_set.contains(PPM_SC_INIT_MODULE));
ASSERT_TRUE(sc_set.contains(PPM_SC_READLINKAT));
}

TEST(filter_ppm_codes, check_sinsp_repair_state_sc_set)
{
libsinsp::events::set<ppm_sc_code> truth;
libsinsp::events::set<ppm_sc_code> input_sc_set;
libsinsp::events::set<ppm_sc_code> sc_set;

truth = libsinsp::events::names_to_sc_set({
"capset", "chdir", "chroot", "clone", "clone3", "execve", "execveat", "fchdir", "fork",
"setgid", "setgid32", "setpgid", "setresgid", "setresgid32", "setresuid", "setresuid32", "setsid",
"setuid", "setuid32", "vfork"});
input_sc_set = libsinsp::events::names_to_sc_set({"execve", "execveat"});
sc_set = sinsp_repair_state_sc_set(input_sc_set).merge(input_sc_set);
ASSERT_PPM_SC_CODES_EQ(truth, sc_set);

truth = libsinsp::events::names_to_sc_set({
"accept", "accept4", "bind", "capset", "chdir", "chroot", "clone", "clone3", "close", "connect",
"execve", "execveat", "fchdir", "fork", "getsockopt", "setgid", "setgid32", "setpgid", "setresgid", "setresgid32",
"setresuid", "setresuid32", "setsid", "setuid", "setuid32", "socket", "vfork"});
input_sc_set = libsinsp::events::names_to_sc_set({"execve", "execveat", "connect", "accept", "accept4"});
sc_set = sinsp_repair_state_sc_set(input_sc_set).merge(input_sc_set);
ASSERT_PPM_SC_CODES_EQ(truth, sc_set);

truth = libsinsp::events::names_to_sc_set({
"capset", "chdir", "chroot", "clone", "clone3", "close", "connect", "execve", "execveat",
"fchdir", "fork", "getsockopt", "setgid", "setgid32", "setpgid", "setresgid", "setresgid32",
"setresuid", "setresuid32", "setsid", "setuid", "setuid32", "socket", "vfork"});
input_sc_set = libsinsp::events::names_to_sc_set({"execve", "execveat", "connect"});
sc_set = sinsp_repair_state_sc_set(input_sc_set).merge(input_sc_set);
ASSERT_PPM_SC_CODES_EQ(truth, sc_set);

truth = libsinsp::events::names_to_sc_set({
"accept", "accept4", "bind", "capset", "chdir", "chroot", "clone", "clone3", "close", "execve",
"execveat", "fchdir", "fork", "getsockopt", "setgid", "setgid32", "setpgid", "setresgid", "setresgid32",
"setresuid", "setresuid32", "setsid", "setuid", "setuid32", "socket", "vfork"});
input_sc_set = libsinsp::events::names_to_sc_set({"execve", "accept", "accept4"});
sc_set = sinsp_repair_state_sc_set(input_sc_set).merge(input_sc_set);
ASSERT_PPM_SC_CODES_EQ(truth, sc_set);

truth = libsinsp::events::names_to_sc_set({
"capset", "chdir", "chroot", "clone", "clone3", "execve", "execveat", "fchdir", "fork",
"setgid", "setgid32", "setpgid", "setresgid", "setresgid32", "setresuid", "setresuid32", "setsid",
"setuid", "setuid32", "vfork"});
input_sc_set = libsinsp::events::names_to_sc_set({"execve", "execveat"});
sc_set = sinsp_repair_state_sc_set(input_sc_set);
ASSERT_PPM_SC_CODES_EQ(truth, sc_set);

truth = libsinsp::events::names_to_sc_set({
"capset", "chdir", "chroot", "clone", "clone3", "close", "execve", "execveat", "fchdir", "fork", "open", "openat", "openat2",
"setgid", "setgid32", "setpgid", "setresgid", "setresgid32", "setresuid", "setresuid32", "setsid", "setuid", "setuid32", "vfork"});
input_sc_set = libsinsp::events::names_to_sc_set({"open", "openat", "openat2"});
sc_set = sinsp_repair_state_sc_set(input_sc_set).merge(input_sc_set);
ASSERT_PPM_SC_CODES_EQ(truth, sc_set);

}