The only use of it was to include in --support output, which is
redundant as the support output already includes the full contents of
each rules file.
Additionally, it wasn't even being updated after the switch from lua
rules loading to c++ rules
loading (https://github.com/falcosecurity/falco/pull/1966/ or
surrounding PRs).
This will simplify follow-on changes to add a real "result" to rules
loading methods, as there will be fewer API variants to support.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
This updates the engine to comply and work properly with the newly-introduced
interface design.
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
This also fixes a couple of bugs. With the current implementation, the multi-ruleset feature is broken with multiple sources.
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
Once all rule files have been loaded, and all the rules have been compiled into filters and inserted in the engine rulesets, the loader definitions are maintained in memory without really being used. This commit adds a convenience method to clear the loader state and free-up some memory when engine consumers do not require such information in memory anymore.
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
falco_engine::process_event gets called for every inspector event.
Profiling showed that std::map::find takes about 10% of
falco_engine::process_event, and that can easily improved by accessing
the source by index.
Signed-off-by: Angelo Puglisi <angelopuglisi86@gmail.com>
The lua_filter_helper class is a simple Lua wrapper that can be used in the Lua rule loader to
parse/compile rule filters, and manipulate them to resolve/replace list and macro references.
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
The Lua PEG parser is not longer needed, since we now use the new filter parser implemented
in libsinsp.
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
When listing fields with -N (names only), also skip fields with the
EPF_TABLE_ONLY flag. (Skipping fields without -N is handled in libs,
in the as_string() method).
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Instead of having .lua files external to the program responsible for
loading rules, embed the contents of those files into the executable
and load them as strings instead of as files:
Add a cmake custom command below userspace/engine/lua that calls a
bash script lua-to-cpp.sh to generate falco_engine_lua_files.{cpp,hh}
that are compiled into the falco engine library.
The script creates a .cpp file that has const char * symbols for each
file, as well as lists of files that should be loaded when the falco
engine is loaded. There are actually two lists:
- lua_module_strings: these are loaded and also added to the lua
runtime package.preload table, so they are available when lua code
require()s them.
- lua_code_strings: these are loaded *and* evaluated, so the functions
in them are availble to be called from C++.
This simplifies some of the falco_common methods, as there's no need
to keep track of a "main" lua file to load or paths from which the lua
loader should find files for modules, and there's no need to keep
track of an "alternate" lua directory that occurs for debug builds.
Also, there's no need to include any .lua files in the installed
packages, as they're built into the falco binary.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Instead of having a falco-specific function to print field info, use
the built-in filter_fieldclass_info::as_string() instead. This is a
better implementation (displays addl info, has better wrapping, wider
output) and having a single implementation allows for consistent
outputs between falco and other potential programs that could use the libs.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Mostly plugins are just handled as a new filter/formatter factory with
a new source based on the loaded input plugin, but there are a few
changes at the engine level:
- is_source_valid returns whether a filter/formatter factory exists
for a given source. Will be used by rules loaded to skip rules for
an unknown source.
- the falco engine now holds the required_plugin_version predicates
found in rules files and a method is_plugin_compatible returns whether
a plugin semver is compatible with the predicates in the rules
- Update the falco engine version and fields checksum for plugins
Co-authored-by: Leonardo Grasso <me@leonardograsso.com>
Co-authored-by: Loris Degioanni <loris@sysdig.com>
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Instead of having hard-coded support for syscall/k8s_audit events, use
the notions of filter factories/formatter factories to provide generic
support for events having a given source:
- Within the engine, maps m_filter_factories / m_rulesets /
m_format_factories map from a given source to something that can
create filters, hold filters, and create formatters for a given
source. The hard-coded sinsp_factory/json_factory objects are removed.
- The specific add_xxx_filter/process_xxx_event are general purpose
and take an event source.
- A new method create_formatter() takes a source/output format and
provides a shared_ptr to a formatter than can resolve format
strings. This is used by the falco outputs code.
- In falco main, create the syscall/k8s_audit filter and formatter
factories and pass them to the engine. Later, we might make this
configurable/selective.
With all of the above changes, the falco engine doesn't need a direct
inspector any longer, so remove it.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Take advantage of the changes in
https://github.com/falcosecurity/libs/pull/75 to have a
general-purpose way to list fields for a given event source.
in the engine, list_fields() now takes a source, iterates over filter
factories, and calls get_fields() for each factory, printing the results.
list_source_fields now calls the engine regardless of source.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Move the code that splits a json object into a list of k8s audit/json
events out of falco engine and into json_evt.
This, along with other changes, allows the falco engine to be more
general purpose and not directly tied to the notion of syscall vs k8s
audit events.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
When returning a rule_result struct, also include a set of field names
used by all exceptions for this rule. This may make building exception
values a bit easier.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Currently, when calling enable_rule, the provided rule name pattern is a
substring match, that is if the rules file has a rule "My fantastic
rule", and you call engine->enable_rule("fantastic", true), the rule
will be enabled.
This can cause problems if one rule name is a complete subset of another
rule name e.g. rules "My rule" and "My rule is great", and calling
engine->enable_rule("My rule", true).
To allow for this case, add an alternate method enable_rule_exact() in
both default ruleset and ruleset variants. In this case, the rule name
must be an exact match.
In the underlying ruleset code, add a "match_exact" option to
falco_ruleset::enable() that denotes whether the substring is an exact
or substring match.
This doesn't change the default behavior of falco in any way, as the
existing calls still use enable_rule().
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
This defines certain functions as invalid tokens, i.e., when
compiled, the compiler throws an error.
Currently only `strcpy` is included as a banned function.
Fixes#788
Signed-off-by: Vaibhav <vrongmeal@gmail.com>
Callers aren't expected to catch execeptions and instead rely on the
bool return value to indicate whether or not the parsing was successful.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Currently, the json object POSTed to the /k8s_audit endpoint is assumed
to be an obect, with a "type" of either "Event" or "EventList". When the
K8s API Server POSTs events, it aggregates them into an EventList,
ensuring that there is always a single object.
However, we're going to add some intermediate tools that tail log files
and send them to the endpoint, and the easiest way to send a batch of
events is to pass them as a json array instead of a single object.
To properly handle this, modify parse_k8s_audit_event_json to also
handle a json array. For arrays, it iterates over the objects, calling
parse_k8s_audit_json recursively. This only iterates an initial top
level array to avoid excessive recursion/attacks involving degenerate
json objects with excessively nested arrays.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Support the notion of a message for all fields in a single class, and
making sure it's wrapped as well as the other fields.
This is used to display a single message about how indexing working for
ka.* filter fields and what IDX_ALLOWED/IDX_NUMERIC/IDX_KEY means,
rather than repeating the same text over and over in every field.
The wrapping is handled by a function falco::utils::wrap_text.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Given the compiler we currently use, you can't actually enable/disable
regexes in falco_engine::enable_rule using a regex pattern. The regex
either will fail to compile or will compile but not actually match
strings. This is noted on the c++11 compatibility notes for gcc 4.8.2:
https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/manual/manual/status.html#status.iso.2011.
The only use of using enable_rule was treating the regex pattern as a
substring match anyway, so we can change the engine to treat the pattern
as a substring.
So change the method/supporting sub-classes to note that the argument is
a substring match, and change falco itself to refer to substrings
instead of patterns.
This fixes https://github.com/falcosecurity/falco/issues/742.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Json-related filtercheck fields supported indexing with brackets, but
when looking at the field descriptions you couldn't tell if a field
allowed an index, required an index, or did not allow an index.
This information was available, but it was a part of the protected
aliases map within the class.
Move this to the public field information so it can be used outside the
class.
Also add m_ prefixes for member names, now that the struct isn't
trivial.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Add more accurate tracking of the number of falco rules loaded per
ruleset, which are made available via the engine method
::num_rules_for_ruleset().
In the ruleset objects, keep track if a filter wrapper is actually
added/removed and if so increment/decrement the count.
* Expose required_engine_version when loading rules
When loading a rules file, have alternate methods that return the
required_engine_version. The existing methods remain unchanged and just
call the new methods with a dummy placeholder.
* Add --support argument to print support bundle
Add an argument --support that can be used as a single way to collect
necessary support information, including the falco version, config,
commandline, and all rules files.
There might be a big of extra structure to the rules files, as they
actually support an array of "variants", but we're thinking ahead to
cases where there might be a comprehensive library of rules files and
choices, so we're adding the extra structure.