mirror of
https://github.com/falcosecurity/falco.git
synced 2025-09-12 13:07:49 +00:00
new(app_actions): add base_syscalls.repair option
See https://github.com/falcosecurity/falco/issues/2433 Co-authored-by: Jason Dellaluce <jasondellaluce@gmail.com> Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
This commit is contained in:
80
falco.yaml
80
falco.yaml
@@ -460,66 +460,86 @@ metadata_download:
|
||||
watch_freq_sec: 1
|
||||
|
||||
|
||||
# base_syscalls ! Use with caution !
|
||||
# base_syscalls ! Use with caution, read carefully !
|
||||
#
|
||||
# --- [Description]
|
||||
#
|
||||
# With this option you are in full control of the total set of syscalls that
|
||||
# With this option you are in full control of the set of syscalls that
|
||||
# Falco will enable in the kernel for active tracing.
|
||||
|
||||
# All syscalls and events from each enabled Falco rule will automatically be activated
|
||||
# even when choosing this option. This option provides full end user control to specifically
|
||||
# define a static set of base syscalls that will be activated in addition to the
|
||||
# All syscalls and events from each enabled Falco rule are activated
|
||||
# even when choosing this option. This option allows you to define a
|
||||
# set of base syscalls that will be activated in addition to the
|
||||
# syscalls defined in the rules.
|
||||
#
|
||||
# When using this option, Falco does not add any other syscalls that may be needed for
|
||||
# Falco's state engine. The union of all syscalls from the rules (including resolved macros)
|
||||
# and the ones specified here compose the final set of syscalls that are traced in the kernel.
|
||||
# This puts the end user in the driver seat, but if not used correctly Falco logs may be
|
||||
# incomplete or wrong. This option however can be very useful to lower CPU utilization and
|
||||
# allowing you to tailor Falco to specific environments according to your
|
||||
# organization's threat model and security posture as well as cost budget.
|
||||
|
||||
# !!! When NOT using this option, Falco defaults to adding a static set of syscalls in addition
|
||||
# to the rules system calls you need for Falco's state engine build-up and life-cycle management.
|
||||
# You may ask yourself why do we need to activate syscalls in addition to the rules?
|
||||
#
|
||||
# Falco requires a set of syscalls to build up state in userspace. This is because for
|
||||
# example when spawning a new process or creating a network connection more than one syscall
|
||||
# is involved. Furthermore, properties of a process during its life time can be modified
|
||||
# by syscalls. Falco takes care of this by activating more syscalls than the ones defined
|
||||
# in the rules and by managing a smart process cache table in userspace.
|
||||
# Processes are purged when a process exits.
|
||||
#
|
||||
# Looking back to what this option does, it activates all syscalls from the rules
|
||||
# (including resolved macros) and the ones specified here.
|
||||
#
|
||||
# This puts the end user in the driver seat to tell Falco what it needs, but if not used correctly
|
||||
# Falco logs may be incomplete or wrong or Falco won't work at all. This option however can be
|
||||
# very useful to lower CPU utilization and allowing you to tailor Falco to specific environments
|
||||
# according to your organization's threat model and cost budget.
|
||||
#
|
||||
# !!! When NOT using this option, Falco defaults to adding a static set of syscalls in addition
|
||||
# to the rules system calls Falco needs for its state engine build-up and life-cycle management.
|
||||
#
|
||||
# If you like the recommendations below you can automate them via setting `base_syscalls.repair`
|
||||
# to true. `base_syscalls.repair` is an experimental alternative to Falco's default state engine
|
||||
# enforcement. `base_syscalls.repair` is designed to be the most resourceful option to ensure
|
||||
# Falco runs correctly while activating a most minimal set of additional syscalls.
|
||||
#
|
||||
# --- [Usage]
|
||||
#
|
||||
# List of system calls names (<syscall-name>) plus negative ("!<syscall-name>") notation supported.
|
||||
#
|
||||
# base_syscalls: [<syscall-name>, <syscall-name>, "!<syscall-name>"]
|
||||
# base_syscalls.repair: <bool>
|
||||
# base_syscalls.custom_set: [<syscall-name>, <syscall-name>, "!<syscall-name>"]
|
||||
#
|
||||
#
|
||||
# --- [Suggestions]
|
||||
#
|
||||
# Here are a few recommendations that may help you to use the full power of this option:
|
||||
# Here are a few recommendations that may help you.
|
||||
# Setting `base_syscalls.repair: true` automates the recommendations.
|
||||
#
|
||||
# Consider to at minimum add the following syscalls regardless of the syscalls used in the rules.
|
||||
#
|
||||
# [clone, clone3, fork, vfork, execve, execveat, close]
|
||||
#
|
||||
# This is because some Falco fields you may output for an execve* system call are retrieved
|
||||
# from the associated "clone", "clone3", "fork", "vfork" syscall when spawning a new process.
|
||||
# The "close" system call is used to purge file descriptors from Falco's internal
|
||||
# thread / process cache table and therefore should always be added when you have rules around fds
|
||||
# This is because some Falco fields for an execve* system call are retrieved
|
||||
# from the associated `clone`, `clone3`, `fork`, `vfork` syscall when spawning a
|
||||
# new process. The `close` system call is used to purge file descriptors from Falco's
|
||||
# internal thread / process cache table and should always be added when you have
|
||||
# rules around file descriptors.
|
||||
# (e.g. open, openat, openat2, socket, connect, accept, accept4 ... and many more)
|
||||
#
|
||||
# When network syscalls are used in rules we recommend to at minimum set
|
||||
#
|
||||
# [clone, clone3, fork, vfork, execve, execveat, close, socket, bind, getsockopt]
|
||||
#
|
||||
# It turns out that while you absolutely can log connect or accept* syscalls without the socket
|
||||
# It turns out that while you can log `connect` or `accept*` syscalls without the socket
|
||||
# system call, the log however would not contain the ip tuples.
|
||||
# For listen and accept* system calls you also need the bind system call.
|
||||
#
|
||||
# Lastly, if you care about the correct uid, gid or sid, pgid of a process when that process then
|
||||
# opens a file or makes a network connection or any other action, consider also
|
||||
# adding the following syscalls:
|
||||
# For listen and accept* system calls you also need the `bind` system call.
|
||||
#`
|
||||
# Lastly, if you care about the correct `uid`, `gid` or `sid`, `pgid of a process when the
|
||||
# running process opens a file or makes a network connection, consider adding the following syscalls:
|
||||
#
|
||||
# setresuid, setsid, setuid, setgid, setpgid, setresgid, setsid, capset, chdir, chroot, fchdir
|
||||
#
|
||||
# Only exclude syscalls, e.g. "!mprotect" if you need a fast deployment update (overriding rules),
|
||||
# else rather remove unwanted or not needed syscalls from the Falco rules.
|
||||
# We recommend to exclude syscalls, e.g. "!mprotect" only if you need a fast deployment update
|
||||
# (overriding rules), else remove unwanted syscalls from the Falco rules.
|
||||
#
|
||||
# Passing `-o "log_level=debug"` to Falco's cmd args during a dry-run will print the
|
||||
# final set of syscalls to STDOUT.
|
||||
|
||||
base_syscalls: []
|
||||
base_syscalls:
|
||||
repair: false
|
||||
custom_set: []
|
||||
|
@@ -85,13 +85,15 @@ static void select_event_set(falco::app::state& s, const libsinsp::events::set<p
|
||||
/* USER OVERRIDE INPUT OPTION "base_syscalls". */
|
||||
std::unordered_set<std::string> user_positive_names = {};
|
||||
std::unordered_set<std::string> user_negative_names = {};
|
||||
extract_base_syscalls_names(s.config->m_base_syscalls, user_positive_names, user_negative_names);
|
||||
extract_base_syscalls_names(s.config->m_base_syscalls_custom_set, user_positive_names, user_negative_names);
|
||||
auto user_positive_sc_set = libsinsp::events::names_to_sc_set(user_positive_names);
|
||||
auto user_negative_sc_set = libsinsp::events::names_to_sc_set(user_negative_names);
|
||||
|
||||
if (!user_positive_sc_set.empty())
|
||||
if (!user_positive_sc_set.empty() || s.config->m_base_syscalls_repair)
|
||||
{
|
||||
// user overrides base event set
|
||||
// in case `user_positive_sc_set` is empty, but `base_syscalls.repair` is set
|
||||
// this has the effect of clearing the default `sinsp_state_sc_set()`
|
||||
base_sc_set = user_positive_sc_set;
|
||||
|
||||
// we re-transform from sc_set to names to make
|
||||
@@ -111,6 +113,17 @@ static void select_event_set(falco::app::state& s, const libsinsp::events::set<p
|
||||
// base events set (either the default or the user-defined one)
|
||||
s.selected_sc_set = rules_sc_set.merge(base_sc_set);
|
||||
|
||||
if (s.config->m_base_syscalls_repair)
|
||||
{
|
||||
/* If base_syscalls.repair set enforce `libsinsp` state based on rules set
|
||||
* and merge with user supplied base_syscalls.custom_set
|
||||
*
|
||||
* Also applies when base_syscalls.custom_set empty but base_syscalls.repair set
|
||||
* effectively bypassing the default `libsinsp` state enforcement and using
|
||||
* `sinsp_repair_state_sc_set` instead. */
|
||||
s.selected_sc_set = libsinsp::events::sinsp_repair_state_sc_set(rules_sc_set).merge(base_sc_set);
|
||||
}
|
||||
|
||||
if (!user_negative_sc_set.empty())
|
||||
{
|
||||
/* Remove negative base_syscalls events. */
|
||||
|
@@ -332,8 +332,9 @@ void falco_configuration::load_yaml(const std::string& config_name, const yaml_h
|
||||
|
||||
m_syscall_drop_failed_exit = config.get_scalar<bool>("syscall_drop_failed_exit", false);
|
||||
|
||||
m_base_syscalls.clear();
|
||||
config.get_sequence<std::unordered_set<std::string>>(m_base_syscalls, std::string("base_syscalls"));
|
||||
m_base_syscalls_custom_set.clear();
|
||||
config.get_sequence<std::unordered_set<std::string>>(m_base_syscalls_custom_set, std::string("base_syscalls.custom_set"));
|
||||
m_base_syscalls_repair = config.get_scalar<bool>("base_syscalls.repair", false);
|
||||
|
||||
std::set<std::string> load_plugins;
|
||||
|
||||
|
@@ -109,7 +109,8 @@ public:
|
||||
bool m_syscall_drop_failed_exit;
|
||||
|
||||
// User supplied base_syscalls, overrides any Falco state engine enforcement.
|
||||
std::unordered_set<std::string> m_base_syscalls;
|
||||
std::unordered_set<std::string> m_base_syscalls_custom_set;
|
||||
bool m_base_syscalls_repair;
|
||||
|
||||
std::vector<plugin_config> m_plugins;
|
||||
|
||||
|
Reference in New Issue
Block a user