new(userspace): initial lifecycle implementation

Signed-off-by: Lorenzo Fontana <lo@linux.com>
This commit is contained in:
Lorenzo Fontana
2020-11-19 16:00:26 +01:00
parent f87e6f1871
commit 344b8c002c
8 changed files with 225 additions and 25 deletions

View File

@@ -226,6 +226,7 @@ set(FALCO_ABSOLUTE_SHARE_DIR "${CMAKE_INSTALL_PREFIX}/${FALCO_SHARE_DIR}")
set(FALCO_BIN_DIR bin)
add_subdirectory(scripts)
add_subdirectory(userspace/libhawk)
add_subdirectory(userspace/engine)
add_subdirectory(userspace/falco)
add_subdirectory(tests)

View File

@@ -30,6 +30,7 @@ set(
set(
FALCO_INCLUDE_DIRECTORIES
"${LIBHAWK_INCLUDE_DIRECTORY}"
"${PROJECT_SOURCE_DIR}/userspace/engine"
"${PROJECT_BINARY_DIR}/userspace/falco"
"${PROJECT_BINARY_DIR}/driver/src"
@@ -52,6 +53,7 @@ set(
set(
FALCO_LIBRARIES
falco_engine
libhawk
sinsp
"${LIBYAML_LIB}"
"${YAMLCPP_LIB}"
@@ -112,18 +114,6 @@ add_executable(
${FALCO_SOURCES}
)
if(DEFINED LIBHAWK_LIBRARIES)
message(STATUS "Using externally provided libhawk implementations: ${LIBHAWK_LIBRARIES}")
list(
APPEND FALCO_LIBRARIES
"${LIBHAWK_LIBRARIES}"
)
list(
APPEND FALCO_INCLUDE_DIRECTORIES
"${PROJECT_SOURCE_DIR}/userspace/libhawk"
)
endif()
add_dependencies(falco ${FALCO_DEPENDENCIES})
target_link_libraries(

View File

@@ -36,9 +36,9 @@ limitations under the License.
#include "logger.h"
#include "utils.h"
#include "chisel.h"
#include "fields_info.h"
#include "lifecycle.h"
#include "event_drops.h"
#include "configuration.h"
#include "falco_engine.h"
@@ -48,10 +48,6 @@ limitations under the License.
#include "webserver.h"
#include "grpc_server.h"
#endif
extern "C"
{
#include "hawk.h"
}
#include "banned.h" // This raises a compilation error when certain functions are used
typedef function<void(sinsp* inspector)> open_t;
@@ -463,6 +459,7 @@ int falco_init(int argc, char **argv)
falco_engine *engine_blueprint;
std::thread watchrules_thread;
falco_outputs *outputs = NULL;
libhawk::lifecycle *hawk_lifecycle = NULL;
syscall_evt_drop_mgr sdropmgr;
int op;
int long_index = 0;
@@ -810,6 +807,8 @@ int falco_init(int argc, char **argv)
throw std::invalid_argument("If -d is provided, a pid file must also be provided");
}
hawk_lifecycle = new libhawk::lifecycle();
ifstream conf_stream;
if (conf_filename.size())
{
@@ -948,10 +947,11 @@ int falco_init(int argc, char **argv)
// engine->enable_rule_by_tag(enabled_rule_tags, true);
}
hawk_init();
watchrules_thread = std::thread([&] {
// todo: pass verbose, and all_events
hawk_watch_rules((hawk_watch_rules_cb)rules_cb, reinterpret_cast<hawk_engine *>(&engine_blueprint));
hawk_lifecycle->watch_rules(
(hawk_watch_rules_cb)rules_cb,
reinterpret_cast<hawk_engine *>(&engine_blueprint),
"hawk_example_c");
});
falco_logger::log(LOG_INFO, "DOPO\n");
@@ -1455,7 +1455,6 @@ int falco_init(int argc, char **argv)
sdropmgr.print_stats();
if(watchrules_thread.joinable())
{
hawk_destroy();
watchrules_thread.join();
}
#ifndef MINIMAL_BUILD
@@ -1472,7 +1471,6 @@ int falco_init(int argc, char **argv)
display_fatal_err("Runtime error: " + string(e.what()) + ". Exiting.\n");
if(watchrules_thread.joinable())
{
hawk_destroy();
watchrules_thread.join();
}
result = EXIT_FAILURE;
@@ -1492,6 +1490,7 @@ exit:
delete inspector;
delete engine_blueprint;
delete outputs;
delete hawk_lifecycle;
return result;
}

View File

@@ -0,0 +1,39 @@
#
# Copyright (C) 2020 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
#
include(CheckSymbolExists)
set(
LIBHAWK_SOURCES
lifecycle.cpp
)
set(
LIBHAWK_PUBLIC_INCLUDES
hawk.h
)
set(LIBHAWK_INCLUDE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE)
add_library(libhawk STATIC ${LIBHAWK_SOURCES})
if(DEFINED LIBHAWK_LIBRARIES)
message(STATUS "Using externally provided libhawk plugins: ${LIBHAWK_LIBRARIES}")
target_link_libraries(libhawk ${LIBHAWK_LIBRARIES})
endif()
#todo: we want to provide a default version of the libhawk plugin functions
# we need to manage the situation where the user only provides parts of it and not others
install(
FILES ${LIBHAWK_PUBLIC_INCLUDES}
DESTINATION "${FALCO_SHARE_DIR}"
)

View File

@@ -0,0 +1,23 @@
#pragma once
#include <stdexcept>
#include <stdexcept>
#include <string>
namespace libhawk
{
class hawk_exception : public std::runtime_error
{
public:
hawk_exception(const std::string& message):
std::runtime_error(message) {}
};
class hawk_plugin_exception: public hawk_exception
{
public:
hawk_plugin_exception(const std::string& plugin_name, const std::string& message):
hawk_exception("plugin: " + plugin_name + ", error: " + message) {}
};
} // namespace libhawk

View File

@@ -1,10 +1,35 @@
#ifndef HAWK_H
#define HAWK_H
extern void hawk_init();
extern void hawk_destroy();
#define HAWK_VERSION_CODE 0x000001
#define HAWK_VERSION_BITS(x, y, z) ((x) << 16 | (y) << 8 | (z))
#define HAWK_AT_LEAST_VERSION(x, y, z) \
(HAWK_VERSION_CODE >= HAWK_VERSION_BITS(x, y, z))
typedef void* hawk_engine;
typedef void (*hawk_watch_rules_cb)(char* rules_content, hawk_engine* engine);
extern void hawk_watch_rules(hawk_watch_rules_cb cb, hawk_engine* engine);
typedef struct
{
void (*hawk_init)(void);
void (*hawk_destroy)(void);
void (*hawk_watch_rules)(hawk_watch_rules_cb, hawk_engine*);
} hawk_plugin_definition;
typedef void(register_plugin_cb)(const char *, hawk_plugin_definition);
typedef struct
{
register_plugin_cb* register_plugin;
} hawk_plugin_registry;
extern hawk_plugin_registry plugin_registry;
#define HAWK_REGISTER_PLUGIN(name, definition) \
void name##_hawk_plugin_init(void) __attribute__((constructor)); \
void name##_hawk_plugin_init(void) \
{ \
plugin_registry.register_plugin(#name, definition); \
}
#endif //HAWK_H

View File

@@ -0,0 +1,83 @@
/*
Copyright (C) 2020 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "lifecycle.h"
#include "exception.h"
#include <iostream>
std::map<std::string, hawk_plugin_definition> *libhawk::g_plugins;
void libhawk_register_plugin(const char *name, hawk_plugin_definition def)
{
if(libhawk::g_plugins == nullptr)
{
libhawk::g_plugins = new std::map<std::string, hawk_plugin_definition>();
}
auto name_str = std::string(name);
auto plugin = libhawk::g_plugins->find(name_str);
if(plugin != libhawk::g_plugins->end())
{
throw libhawk::hawk_exception("cannot register an already registered plugin: " + name_str);
}
libhawk::g_plugins->insert(std::make_pair(name_str, def));
};
hawk_plugin_registry plugin_registry = {
.register_plugin = &libhawk_register_plugin,
};
libhawk::lifecycle::lifecycle()
{
if(g_plugins == nullptr)
{
throw hawk_exception("no libhawk plugins registered");
}
for(auto plugin : *g_plugins)
{
if(plugin.second.hawk_init != nullptr)
{
plugin.second.hawk_init();
}
}
}
libhawk::lifecycle::~lifecycle()
{
for(auto plugin : *g_plugins)
{
if(plugin.second.hawk_destroy != nullptr)
{
plugin.second.hawk_destroy();
}
}
}
void libhawk::lifecycle::watch_rules(hawk_watch_rules_cb cb, hawk_engine *engine, const std::string &plugin_name)
{
auto plugin = g_plugins->find(plugin_name);
if(plugin == g_plugins->end())
{
throw hawk_plugin_exception(plugin_name, "cannot watch_rules on a non existing plugin");
}
if(plugin->second.hawk_watch_rules == nullptr)
{
throw hawk_plugin_exception(plugin_name, "plugin does not implement hawk_watch_rules");
}
plugin->second.hawk_watch_rules(cb, engine);
}

View File

@@ -0,0 +1,40 @@
/*
Copyright (C) 2020 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
#include <map>
#include <string>
#include <vector>
extern "C"
{
#include "hawk.h"
}
namespace libhawk
{
extern std::map<std::string, hawk_plugin_definition>* g_plugins;
class lifecycle
{
public:
lifecycle();
virtual ~lifecycle();
void watch_rules(hawk_watch_rules_cb cb, hawk_engine* engine, const std::string& plugin_name);
};
} // namespace libhawk