Skip to content
Open
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 plugins/in_ebpf/in_ebpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ static struct flb_config_map config_map[] = {
{
FLB_CONFIG_MAP_STR, "Trace", NULL,
FLB_CONFIG_MAP_MULT, FLB_FALSE, 0,
"Set the eBPF trace to enable (for example, bind, malloc, signal). Can be set multiple times"
"Set the eBPF trace to enable (for example, bind, malloc, signal, vfs). Can be set multiple times"
},
/* EOF */
{0}
Expand Down
2 changes: 2 additions & 0 deletions plugins/in_ebpf/traces/includes/common/encoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ static inline char *event_type_to_string(enum event_type type) {
return "malloc";
case EVENT_TYPE_BIND:
return "bind";
case EVENT_TYPE_VFS:
return "vfs";
default:
return "unknown";
}
Expand Down
16 changes: 16 additions & 0 deletions plugins/in_ebpf/traces/includes/common/events.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@
#include <linux/types.h> // For __u32, __u64, etc.

#define TASK_COMM_LEN 16
#define VFS_PATH_MAX 256

enum event_type {
EVENT_TYPE_EXECVE,
EVENT_TYPE_SIGNAL,
EVENT_TYPE_MEM, // For memory operations
EVENT_TYPE_BIND, // Added event type for bind operations
EVENT_TYPE_VFS,
};

enum vfs_op {
VFS_OP_OPENAT,
};

/* Define memory operation types */
Expand Down Expand Up @@ -78,6 +84,15 @@ struct bind_event {
int error_raw; // Error code for the bind operation
};

struct vfs_event {
enum vfs_op operation;
char path[VFS_PATH_MAX];
__u32 flags;
__u32 mode;
int fd;
int error_raw;
};

/* The main event structure */
struct event {
enum event_type type; // Type of event (execve, signal, mem, bind)
Expand All @@ -87,6 +102,7 @@ struct event {
struct signal_event signal;
struct mem_event mem; // Memory event details
struct bind_event bind; // Bind event details
struct vfs_event vfs; // VFS event details
} details; // Event-specific details
};

Expand Down
4 changes: 4 additions & 0 deletions plugins/in_ebpf/traces/traces.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
#include "generated/trace_signal.skel.h"
#include "generated/trace_malloc.skel.h"
#include "generated/trace_bind.skel.h"
#include "generated/trace_vfs.skel.h"

#include "bind/handler.h"
#include "signal/handler.h" // Include signal handler
#include "malloc/handler.h" // Include malloc handler
#include "vfs/handler.h"

/* Skeleton function pointer types */
typedef void *(*trace_skel_open_func_t)(void);
Expand Down Expand Up @@ -58,11 +60,13 @@ struct trace_registration {
DEFINE_GET_BPF_OBJECT(trace_signal)
DEFINE_GET_BPF_OBJECT(trace_malloc)
DEFINE_GET_BPF_OBJECT(trace_bind)
DEFINE_GET_BPF_OBJECT(trace_vfs)

static struct trace_registration trace_table[] = {
REGISTER_TRACE(trace_signal, trace_signal_handler),
REGISTER_TRACE(trace_malloc, trace_malloc_handler),
REGISTER_TRACE(trace_bind, trace_bind_handler),
REGISTER_TRACE(trace_vfs, trace_vfs_handler),
};

#endif // TRACE_TRACES_H
114 changes: 114 additions & 0 deletions plugins/in_ebpf/traces/vfs/bpf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)

#include <vmlinux.h>

#define _LINUX_TYPES_H
#define _LINUX_POSIX_TYPES_H

#include <bpf/bpf_helpers.h>
#include <bpf/bpf_core_read.h>

#include <gadget/buffer.h>
#include <gadget/macros.h>
#include <gadget/mntns_filter.h>
#include <gadget/types.h>

#include "common/events.h"

#define MAX_ENTRIES 10240

struct vfs_open_args {
gadget_mntns_id mntns_id;
__u32 flags;
__u32 mode;
char path[VFS_PATH_MAX];
};

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, MAX_ENTRIES);
__type(key, __u32);
__type(value, struct vfs_open_args);
} values SEC(".maps");

GADGET_TRACER_MAP(events, 1024 * 256);

SEC("tracepoint/syscalls/sys_enter_openat")
int trace_vfs_openat_enter(struct syscall_trace_enter *ctx)
{
__u32 tid;
__u64 pid_tgid;
__u64 mntns_id;
const char *filename;
struct vfs_open_args val = {};

mntns_id = gadget_get_mntns_id();
if (gadget_should_discard_mntns_id(mntns_id)) {
return 0;
}

pid_tgid = bpf_get_current_pid_tgid();
tid = (__u32) pid_tgid;

filename = (const char *) ctx->args[1];
bpf_probe_read_user_str(val.path, sizeof(val.path), filename);

val.flags = (__u32) ctx->args[2];
val.mode = (__u32) ctx->args[3];
val.mntns_id = mntns_id;

bpf_map_update_elem(&values, &tid, &val, BPF_ANY);

return 0;
}

SEC("tracepoint/syscalls/sys_exit_openat")
int trace_vfs_openat_exit(struct syscall_trace_exit *ctx)
{
__u32 tid;
__u64 pid_tgid;
__u64 uid_gid;
struct vfs_open_args *val;
struct event *event;

pid_tgid = bpf_get_current_pid_tgid();
tid = (__u32) pid_tgid;

val = bpf_map_lookup_elem(&values, &tid);
if (!val) {
return 0;
}

event = gadget_reserve_buf(&events, sizeof(*event));
if (!event) {
bpf_map_delete_elem(&values, &tid);
return 0;
}

uid_gid = bpf_get_current_uid_gid();

event->common.timestamp_raw = bpf_ktime_get_boot_ns();
event->common.pid = pid_tgid >> 32;
event->common.tid = tid;
event->common.uid = (u32) uid_gid;
event->common.gid = (u32) (uid_gid >> 32);
event->common.mntns_id = val->mntns_id;
bpf_get_current_comm(event->common.comm, sizeof(event->common.comm));

event->type = EVENT_TYPE_VFS;
event->details.vfs.operation = VFS_OP_OPENAT;
event->details.vfs.flags = val->flags;
event->details.vfs.mode = val->mode;
event->details.vfs.fd = (int) ctx->ret;
event->details.vfs.error_raw = ctx->ret < 0 ? -ctx->ret : 0;

__builtin_memcpy(event->details.vfs.path, val->path, sizeof(event->details.vfs.path));

gadget_submit_buf(ctx, &events, event, sizeof(*event));

bpf_map_delete_elem(&values, &tid);

return 0;
}

char LICENSE[] SEC("license") = "Dual BSD/GPL";
126 changes: 126 additions & 0 deletions plugins/in_ebpf/traces/vfs/handler.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#include <fluent-bit/flb_input_plugin.h>
#include <fluent-bit/flb_log_event_encoder.h>

#include "common/events.h"
#include "common/event_context.h"
#include "common/encoder.h"

#include "handler.h"

int encode_vfs_event(struct flb_input_instance *ins,
struct flb_log_event_encoder *log_encoder,
const struct event *ev)
{
int ret;

ret = flb_log_event_encoder_begin_record(log_encoder);
if (ret != FLB_EVENT_ENCODER_SUCCESS) {
return -1;
}

ret = encode_common_fields(log_encoder, ev);
if (ret != FLB_EVENT_ENCODER_SUCCESS) {
flb_log_event_encoder_rollback_record(log_encoder);
return -1;
}

ret = flb_log_event_encoder_append_body_cstring(log_encoder, "operation");
if (ret != FLB_EVENT_ENCODER_SUCCESS) {
flb_log_event_encoder_rollback_record(log_encoder);
return -1;
}
ret = flb_log_event_encoder_append_body_int32(log_encoder, ev->details.vfs.operation);
if (ret != FLB_EVENT_ENCODER_SUCCESS) {
flb_log_event_encoder_rollback_record(log_encoder);
return -1;
}

ret = flb_log_event_encoder_append_body_cstring(log_encoder, "path");
if (ret != FLB_EVENT_ENCODER_SUCCESS) {
flb_log_event_encoder_rollback_record(log_encoder);
return -1;
}
ret = flb_log_event_encoder_append_body_cstring(log_encoder, ev->details.vfs.path);
if (ret != FLB_EVENT_ENCODER_SUCCESS) {
flb_log_event_encoder_rollback_record(log_encoder);
return -1;
}

ret = flb_log_event_encoder_append_body_cstring(log_encoder, "flags");
if (ret != FLB_EVENT_ENCODER_SUCCESS) {
flb_log_event_encoder_rollback_record(log_encoder);
return -1;
}
ret = flb_log_event_encoder_append_body_uint32(log_encoder, ev->details.vfs.flags);
if (ret != FLB_EVENT_ENCODER_SUCCESS) {
flb_log_event_encoder_rollback_record(log_encoder);
return -1;
}

ret = flb_log_event_encoder_append_body_cstring(log_encoder, "mode");
if (ret != FLB_EVENT_ENCODER_SUCCESS) {
flb_log_event_encoder_rollback_record(log_encoder);
return -1;
}
ret = flb_log_event_encoder_append_body_uint32(log_encoder, ev->details.vfs.mode);
if (ret != FLB_EVENT_ENCODER_SUCCESS) {
flb_log_event_encoder_rollback_record(log_encoder);
return -1;
}

ret = flb_log_event_encoder_append_body_cstring(log_encoder, "fd");
if (ret != FLB_EVENT_ENCODER_SUCCESS) {
flb_log_event_encoder_rollback_record(log_encoder);
return -1;
}
ret = flb_log_event_encoder_append_body_int32(log_encoder, ev->details.vfs.fd);
if (ret != FLB_EVENT_ENCODER_SUCCESS) {
flb_log_event_encoder_rollback_record(log_encoder);
return -1;
}

ret = flb_log_event_encoder_append_body_cstring(log_encoder, "error_raw");
if (ret != FLB_EVENT_ENCODER_SUCCESS) {
flb_log_event_encoder_rollback_record(log_encoder);
return -1;
}
ret = flb_log_event_encoder_append_body_int32(log_encoder, ev->details.vfs.error_raw);
if (ret != FLB_EVENT_ENCODER_SUCCESS) {
flb_log_event_encoder_rollback_record(log_encoder);
return -1;
}

ret = flb_log_event_encoder_commit_record(log_encoder);
if (ret != FLB_EVENT_ENCODER_SUCCESS) {
return -1;
}

return 0;
}

int trace_vfs_handler(void *ctx, void *data, size_t data_sz)
{
struct trace_event_context *event_ctx = (struct trace_event_context *) ctx;
struct event *ev = (struct event *) data;
struct flb_log_event_encoder *encoder = event_ctx->log_encoder;
int ret;

if (data_sz < sizeof(struct event) || ev->type != EVENT_TYPE_VFS) {
return -1;
}

ret = encode_vfs_event(event_ctx->ins, encoder, ev);
if (ret != 0) {
return -1;
}

ret = flb_input_log_append(event_ctx->ins, NULL, 0,
encoder->output_buffer, encoder->output_length);
if (ret == -1) {
return -1;
}

flb_log_event_encoder_reset(encoder);

return 0;
}
12 changes: 12 additions & 0 deletions plugins/in_ebpf/traces/vfs/handler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef VFS_HANDLER_H
#define VFS_HANDLER_H

#include <stddef.h>
#include "common/events.h"

int trace_vfs_handler(void *ctx, void *data, size_t data_sz);
int encode_vfs_event(struct flb_input_instance *ins,
struct flb_log_event_encoder *log_encoder,
const struct event *ev);

#endif
Loading