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(falco): print all events with flags #2771

Merged
merged 3 commits into from
Sep 7, 2023
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
git_ref: ${{ github.event.pull_request.head.sha }}
minimal: false
build_type: Debug
cmd: "echo $(build/userspace/falco/falco -c ./falco.yaml --version | grep 'Engine:' | awk '{print $2}') $(echo $(build/userspace/falco/falco -c ./falco.yaml --version | grep 'Schema version:' | awk '{print $3}') $(build/userspace/falco/falco -c ./falco.yaml --list --markdown | grep '^`' | sort) $(build/userspace/falco/falco -c ./falco.yaml --list-syscall-events | sort) | sha256sum)"
cmd: "echo $(build/userspace/falco/falco -c ./falco.yaml --version | grep 'Engine:' | awk '{print $2}') $(echo $(build/userspace/falco/falco -c ./falco.yaml --version | grep 'Schema version:' | awk '{print $3}') $(build/userspace/falco/falco -c ./falco.yaml --list --markdown | grep '^`' | sort) $(build/userspace/falco/falco -c ./falco.yaml --list-events | sort) | sha256sum)"

# checks the falco engine checksum for consistency
check-engine-checksum:
Expand Down
6 changes: 3 additions & 3 deletions userspace/engine/falco_engine_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ limitations under the License.
*/

// The version of this Falco engine.
#define FALCO_ENGINE_VERSION (25)
#define FALCO_ENGINE_VERSION (26)

// This is the result of running the following command:
// FALCO="falco -c ./falco.yaml"
// echo $($FALCO --version | grep 'Engine:' | awk '{print $2}') $(echo $($FALCO --version | grep 'Schema version:' | awk '{print $3}') $($FALCO --list --markdown | grep '^`' | sort) $($FALCO --list-syscall-events | sort) | sha256sum)
// echo $($FALCO --version | grep 'Engine:' | awk '{print $2}') $(echo $($FALCO --version | grep 'Schema version:' | awk '{print $3}') $($FALCO --list --markdown | grep '^`' | sort) $($FALCO --list-events | sort) | sha256sum)
// It represents the fields supported by this version of Falco,
// the event types, and the underlying driverevent schema. It's used to
// detetect changes in engine version in our CI jobs.
#define FALCO_ENGINE_CHECKSUM "41b5dc700216b243d294b40c46264d4e89d0ee00098fdc1c21bb4b1e7639da06"
#define FALCO_ENGINE_CHECKSUM "98c6e665031b95c666a9ab02d5470e7008e8636bf02f4cc410912005b90dff5c"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note for the reviewer: the list of events did not change, but the format did so we need to update the checksum. Updating the engine version should be OK but if I forgot something and it's not please let me know and I'll revert

178 changes: 133 additions & 45 deletions userspace/falco/app/actions/print_syscall_events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ limitations under the License.

#include "actions.h"
#include "helpers.h"
#include "../app.h"
#include "../../versions_info.h"

using namespace falco::app;
using namespace falco::app::actions;
Expand All @@ -28,10 +30,56 @@ struct event_entry
const ppm_event_info* info;
};

static std::vector<event_entry> get_event_entries(bool include_generics, const libsinsp::events::set<ppm_event_code>& available)
struct events_by_category
{
event_entry entry;
std::vector<event_entry> events;
std::vector<event_entry> syscalls;
std::vector<event_entry> tracepoints;
std::vector<event_entry> pluginevents;
std::vector<event_entry> metaevents;

void add_event(ppm_event_code e, bool available, std::string name = "") {
event_entry entry;

entry.is_enter = PPME_IS_ENTER(e);
entry.info = libsinsp::events::info(e);
entry.available = available;

if (name == "")
{
entry.name = entry.info->name;
} else {
entry.name = name;
}

if (libsinsp::events::is_syscall_event(e))
{
syscalls.push_back(entry);
return;
}

if (libsinsp::events::is_tracepoint_event(e))
{
tracepoints.push_back(entry);
return;
}

if (libsinsp::events::is_plugin_event(e))
{
pluginevents.push_back(entry);
return;
}

if (libsinsp::events::is_metaevent(e))
{
metaevents.push_back(entry);
return;
}
}
};

static struct events_by_category get_event_entries_by_category(bool include_generics, const libsinsp::events::set<ppm_event_code>& available)
{
events_by_category result;

// skip generic events
for (const auto& e: libsinsp::events::all_event_set())
Expand All @@ -41,11 +89,7 @@ static std::vector<event_entry> get_event_entries(bool include_generics, const l
&& !libsinsp::events::is_unused_event(e)
&& !libsinsp::events::is_unknown_event(e))
{
entry.is_enter = PPME_IS_ENTER(e);
entry.available = available.contains(e);
entry.info = libsinsp::events::info(e);
entry.name = entry.info->name;
events.push_back(entry);
result.add_event(e, available.contains(e));
}
}

Expand All @@ -55,60 +99,104 @@ static std::vector<event_entry> get_event_entries(bool include_generics, const l
const auto names = libsinsp::events::event_set_to_names({ppm_event_code::PPME_GENERIC_E});
for (const auto& name : names)
{
entry.is_enter = PPME_IS_ENTER(ppm_event_code::PPME_GENERIC_E);
entry.available = available.contains(ppm_event_code::PPME_GENERIC_E);
entry.info = libsinsp::events::info(ppm_event_code::PPME_GENERIC_E);
entry.name = name;
events.push_back(entry);

entry.is_enter = PPME_IS_ENTER(ppm_event_code::PPME_GENERIC_X);
entry.available = available.contains(ppm_event_code::PPME_GENERIC_X);
entry.info = libsinsp::events::info(ppm_event_code::PPME_GENERIC_X);
entry.name = name;
events.push_back(entry);
result.add_event(ppm_event_code::PPME_GENERIC_E, available.contains(ppm_event_code::PPME_GENERIC_E), name);
result.add_event(ppm_event_code::PPME_GENERIC_X, available.contains(ppm_event_code::PPME_GENERIC_X), name);
}
}

return events;
return result;
}

falco::app::run_result falco::app::actions::print_syscall_events(falco::app::state& s)
static bool is_flag_type(ppm_param_type type)
{
if(s.options.list_syscall_events)
return (type == PT_FLAGS8 || type == PT_FLAGS16 || type == PT_FLAGS32 ||
type == PT_ENUMFLAGS8 || type == PT_ENUMFLAGS16 || type == PT_ENUMFLAGS32);
}

static void print_param(const struct ppm_param_info *param, bool markdown) {
printf("%s **%s**", param_type_to_string(param->type), param->name);

if (is_flag_type(param->type) && param->info) {
auto flag_info = static_cast<const ppm_name_value*>(param->info);

printf(": ");
for (size_t i = 0; flag_info[i].name != NULL; i++) {
if (i != 0)
{
printf(", ");
}

if (markdown) {
printf("*%s*", flag_info[i].name);
} else {
printf("%s", flag_info[i].name);
}
}
}
}

static void print_events(const std::vector<event_entry> &events, bool markdown)
{
if(markdown)
{
const auto events = get_event_entries(true, libsinsp::events::all_event_set());
printf("Default | Dir | Name | Params \n");
printf(":-------|:----|:-----|:-----\n");
}

if(s.options.markdown)
for (const auto& e : events)
{
char dir = e.is_enter ? '>' : '<';
if (markdown)
{
printf(e.available ? "Yes" : "No");
printf(" | `%c` | `%s` | ", dir, e.name.c_str());
}
else
{
printf("Falco | Dir | Event\n");
printf(":-----|:----|:-----\n");
printf("%c %s(", dir, e.name.c_str());
}

for (const auto& e : events)
for(uint32_t k = 0; k < e.info->nparams; k++)
{
char dir = e.is_enter ? '>' : '<';
if (s.options.markdown)
{
printf(e.available ? "Yes" : "No");
printf(" | %c | **%s**(", dir, e.name.c_str());
}
else
if(k != 0)
{
printf("%c %s(", dir, e.name.c_str());
printf(", ");
}

for(uint32_t k = 0; k < e.info->nparams; k++)
{
if(k != 0)
{
printf(", ");
}

printf("%s %s", param_type_to_string(e.info->params[k].type),
e.info->params[k].name);
}
print_param(&e.info->params[k], markdown);
}
if (markdown)
{
printf("\n");
}
else
{
printf(")\n");
}
}
}

falco::app::run_result falco::app::actions::print_syscall_events(falco::app::state& s)
{
if(s.options.list_syscall_events)
{
const falco::versions_info info(s.offline_inspector);
printf("The events below are valid for Falco *Schema Version*: %s\n", info.driver_schema_version.c_str());

const libsinsp::events::set<ppm_event_code> available = libsinsp::events::all_event_set().diff(sc_set_to_event_set(falco::app::ignored_sc_set()));
const struct events_by_category events_bc = get_event_entries_by_category(true, available);

printf("## Syscall events\n\n");
print_events(events_bc.syscalls, s.options.markdown);

printf("\n\n## Tracepoint events\n\n");
print_events(events_bc.tracepoints, s.options.markdown);

printf("\n\n## Plugin events\n\n");
print_events(events_bc.pluginevents, s.options.markdown);
Comment on lines +195 to +196
Copy link
Member

Choose a reason for hiding this comment

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

Do we intend to print all events (regardless of the data source) here? If so, I would change the option name from --list-syscall-events to --list-events.

cc @falcosecurity/falco-maintainers

Copy link
Member

Choose a reason for hiding this comment

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

yes agree with leo i would change it to --list-events

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I noticed that this flag never printed syscall events, but always printed all events. Yes, I introduced it and decided the name 😅 . So I agree with you, let me change it to --list-events.


printf("\n\n## Metaevents\n\n");
print_events(events_bc.metaevents, s.options.markdown);

return run_result::exit();
}
Expand Down
4 changes: 2 additions & 2 deletions userspace/falco/app/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,10 @@ void options::define(cxxopts::Options& opts)
("L", "Show the name and description of all rules and exit. If json_output is set to true, it prints details about all rules, macros, and lists in JSON format.", cxxopts::value(describe_all_rules)->default_value("false"))
("l", "Show the name and description of the rule specified <rule> and exit. If json_output is set to true, it prints details about the rule in JSON format.", cxxopts::value(describe_rule), "<rule>")
("list", "List all defined fields and exit. If <source> is provided, only list those fields for the source <source>. Current values for <source> are \"syscall\" or any source from a configured plugin with event sourcing capability.", cxxopts::value(list_source_fields)->implicit_value(""), "<source>")
("list-syscall-events", "List all defined 'syscall' events and exit.", cxxopts::value<bool>(list_syscall_events))
("list-events", "List all defined syscall events, metaevents, tracepoint events and exit.", cxxopts::value<bool>(list_syscall_events))
("list-plugins", "Print info on all loaded plugins and exit.", cxxopts::value(list_plugins)->default_value("false"))
("M", "Stop Falco execution after <num_seconds> are passed.", cxxopts::value(duration_to_tot)->default_value("0"), "<num_seconds>")
("markdown", "Print output in Markdown format when used in conjunction with --list or --list-syscall-events options. It has no effect when used with other options.", cxxopts::value<bool>(markdown))
("markdown", "Print output in Markdown format when used in conjunction with --list or --list-events options. It has no effect when used with other options.", cxxopts::value<bool>(markdown))
("N", "Only print field names when used in conjunction with the --list option. It has no effect when used with other options.", cxxopts::value(names_only)->default_value("false"))
("nodriver", "Do not use a driver to instrument the kernel. If a loaded plugin has event-sourcing capability and can produce system events, it will be used for event collection. Otherwise, no event will be collected.", cxxopts::value(nodriver)->default_value("false"))
("o,option", "Set the value of option <opt> to <val>. Overrides values in the configuration file. <opt> can be identified using its location in the configuration file using dot notation. Elements of list entries can be accessed via square brackets [].\n E.g. base.id = val\n base.subvalue.subvalue2 = val\n base.list[1]=val", cxxopts::value(cmdline_config_options), "<opt>=<val>")
Expand Down
Loading