This version works

Minimally working version that can link a go program against a so with
the embedded falco engine. Running the program opens the engine for
syscalls and prints any output strings on alert.

It assumes the device already exists and the kernel module is
loaded. Also assumes the lua code is below /user/share--we'll want to
bake that into the shared library.

Lots of memory leaks still, the interface from go to c is still
monolithic, and I had to change the config of openssl crypto and
luajit to compile with -fPIC in order to link into the shared library,
but this version shows its feasible.
This commit is contained in:
Mark Stemm
2021-08-11 13:16:29 -07:00
parent 5787dfa098
commit 0c3fe8a4e7
4 changed files with 76 additions and 6 deletions

View File

@@ -21,7 +21,7 @@ set(
"${YAMLCPP_LIB}"
)
add_library(falco_engine_embeddable STATIC ${FALCO_ENGINE_EMBEDDABLE_SOURCE_FILES})
add_library(falco_engine_embeddable SHARED ${FALCO_ENGINE_EMBEDDABLE_SOURCE_FILES})
add_dependencies(falco_engine_embeddable falco_engine)
target_include_directories(

View File

@@ -3,35 +3,100 @@ package main
//#cgo CFLAGS: -I../
//#cgo LDFLAGS: -L/home/mstemm/work/falco-build/userspace/engine/embeddable -lfalco_engine_embeddable -Wl,-rpath=/home/mstemm/work/falco-build/userspace/engine/embeddable
/*
#include "stdio.h"
#include "falco_engine_embeddable.h"
int open_engine(void **engine)
int open_engine(void **engine, void *rules_content)
{
int32_t rc;
*engine = falco_engine_embed_init(&rc);
if (rc != 0)
{
return rc;
}
char *errstr;
rc = falco_engine_embed_load_rules_content(*engine, (const char *) rules_content, &errstr);
if (rc != 0)
{
fprintf(stderr, "%s", errstr);
return rc;
}
rc = falco_engine_embed_open(*engine, &errstr);
if (rc != 0)
{
fprintf(stderr, "%s", errstr);
return rc;
}
return rc;
}
int next_result(void *engine, char **output)
{
int32_t rc;
falco_engine_embed_result *res;
char *errstr;
rc = falco_engine_embed_next_result(engine, &res, &errstr);
if (rc != 0)
{
fprintf(stderr, "NEXT ERROR %s", errstr);
return rc;
}
*output = res->output_str;
return rc;
}
*/
import "C"
import (
"fmt"
"io/ioutil"
"os"
"unsafe"
)
func doMain(path string, rules_file string) {
func doMain(rules_filename string) int {
rules_content, err := ioutil.ReadFile(rules_filename)
if err != nil {
fmt.Printf("Could not open rules file %s: %v", rules_filename, err)
return 1
}
var handle unsafe.Pointer
rc := C.open_engine(&handle)
rc := C.open_engine(&handle, C.CBytes(rules_content))
if rc != 0 {
fmt.Printf("Could not open falco engine")
return 1
}
for true {
var output *C.char
rc := C.next_result(handle, &output)
if rc != 0 {
fmt.Printf("Could not get next result")
return 1
}
fmt.Printf("GOT RESULT %s\n", C.GoString(output))
}
return 0
}
func main() {
os.Exit(doMain(Args[1]))
os.Exit(doMain(os.Args[1]))
}

View File

@@ -58,6 +58,7 @@ falco_engine_embed_int::falco_engine_embed_int()
{
m_inspector.reset(new sinsp());
m_falco_engine.reset(new falco_engine());
m_falco_engine->set_inspector(m_inspector.get());
m_formatters.reset(new sinsp_evt_formatter_cache(m_inspector.get()));
}
@@ -174,6 +175,10 @@ falco_engine_embed_result * falco_engine_embed_int::rule_result_to_embed_result(
m_formatters->tostring(ev, res->format, &output);
result->output_str = strdup(output.c_str());
result->output_fields = NULL;
result->output_values = NULL;
result->num_output_values = 0;
map<string, string> rule_output_fields;
m_formatters->resolve_tokens(ev, res->format, rule_output_fields);
for(auto &pair : rule_output_fields)

View File

@@ -21,4 +21,4 @@ limitations under the License.
// This is the result of running "falco --list -N | sha256sum" and
// represents the fields supported by this version of falco. It's used
// at build time to detect a changed set of fields.
#define FALCO_FIELDS_CHECKSUM "2f324e2e66d4b423f53600e7e0fcf2f0ff72e4a87755c490f2ae8f310aba9386"
#define FALCO_FIELDS_CHECKSUM "8183621f52451d842036eee409e2ed920d9c91bab33e0c4a44e4a871378d103f"