mirror of
https://github.com/falcosecurity/falco.git
synced 2025-09-13 05:22:34 +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
|
watch_freq_sec: 1
|
||||||
|
|
||||||
|
|
||||||
# base_syscalls ! Use with caution !
|
# base_syscalls ! Use with caution, read carefully !
|
||||||
#
|
#
|
||||||
# --- [Description]
|
# --- [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.
|
# Falco will enable in the kernel for active tracing.
|
||||||
|
|
||||||
# All syscalls and events from each enabled Falco rule will automatically be activated
|
# All syscalls and events from each enabled Falco rule are activated
|
||||||
# even when choosing this option. This option provides full end user control to specifically
|
# even when choosing this option. This option allows you to define a
|
||||||
# define a static set of base syscalls that will be activated in addition to the
|
# set of base syscalls that will be activated in addition to the
|
||||||
# syscalls defined in the rules.
|
# syscalls defined in the rules.
|
||||||
#
|
#
|
||||||
# When using this option, Falco does not add any other syscalls that may be needed for
|
# You may ask yourself why do we need to activate syscalls in addition to the rules?
|
||||||
# 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.
|
|
||||||
#
|
#
|
||||||
|
# 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]
|
# --- [Usage]
|
||||||
#
|
#
|
||||||
# List of system calls names (<syscall-name>) plus negative ("!<syscall-name>") notation supported.
|
# 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]
|
# --- [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.
|
# Consider to at minimum add the following syscalls regardless of the syscalls used in the rules.
|
||||||
#
|
#
|
||||||
# [clone, clone3, fork, vfork, execve, execveat, close]
|
# [clone, clone3, fork, vfork, execve, execveat, close]
|
||||||
#
|
#
|
||||||
# This is because some Falco fields you may output for an execve* system call are retrieved
|
# 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.
|
# from the associated `clone`, `clone3`, `fork`, `vfork` syscall when spawning a
|
||||||
# The "close" system call is used to purge file descriptors from Falco's internal
|
# new process. The `close` system call is used to purge file descriptors from Falco's
|
||||||
# thread / process cache table and therefore should always be added when you have rules around fds
|
# 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)
|
# (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
|
# When network syscalls are used in rules we recommend to at minimum set
|
||||||
#
|
#
|
||||||
# [clone, clone3, fork, vfork, execve, execveat, close, socket, bind, getsockopt]
|
# [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.
|
# system call, the log however would not contain the ip tuples.
|
||||||
# For listen and accept* system calls you also need the bind system call.
|
# 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
|
# Lastly, if you care about the correct `uid`, `gid` or `sid`, `pgid of a process when the
|
||||||
# opens a file or makes a network connection or any other action, consider also
|
# running process opens a file or makes a network connection, consider adding the following syscalls:
|
||||||
# adding the following syscalls:
|
|
||||||
#
|
#
|
||||||
# setresuid, setsid, setuid, setgid, setpgid, setresgid, setsid, capset, chdir, chroot, fchdir
|
# 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),
|
# We recommend to exclude syscalls, e.g. "!mprotect" only if you need a fast deployment update
|
||||||
# else rather remove unwanted or not needed syscalls from the Falco rules.
|
# (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". */
|
/* USER OVERRIDE INPUT OPTION "base_syscalls". */
|
||||||
std::unordered_set<std::string> user_positive_names = {};
|
std::unordered_set<std::string> user_positive_names = {};
|
||||||
std::unordered_set<std::string> user_negative_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_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);
|
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
|
// 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;
|
base_sc_set = user_positive_sc_set;
|
||||||
|
|
||||||
// we re-transform from sc_set to names to make
|
// 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)
|
// base events set (either the default or the user-defined one)
|
||||||
s.selected_sc_set = rules_sc_set.merge(base_sc_set);
|
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())
|
if (!user_negative_sc_set.empty())
|
||||||
{
|
{
|
||||||
/* Remove negative base_syscalls events. */
|
/* 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_syscall_drop_failed_exit = config.get_scalar<bool>("syscall_drop_failed_exit", false);
|
||||||
|
|
||||||
m_base_syscalls.clear();
|
m_base_syscalls_custom_set.clear();
|
||||||
config.get_sequence<std::unordered_set<std::string>>(m_base_syscalls, std::string("base_syscalls"));
|
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;
|
std::set<std::string> load_plugins;
|
||||||
|
|
||||||
|
@@ -109,7 +109,8 @@ public:
|
|||||||
bool m_syscall_drop_failed_exit;
|
bool m_syscall_drop_failed_exit;
|
||||||
|
|
||||||
// User supplied base_syscalls, overrides any Falco state engine enforcement.
|
// 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;
|
std::vector<plugin_config> m_plugins;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user