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

bpf: Emit error messages to DebugFS #40

Merged
merged 4 commits into from
Nov 13, 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
161 changes: 79 additions & 82 deletions agent/src/bpf/audit.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
#include <bpf/usdt.bpf.h>
#include "audit.h"

#define DEBUG(format, ...) \
bpf_trace_printk ("%s: " format, sizeof("%s: " format), \
__PRETTY_FUNCTION__, __VA_ARGS__)

struct {
__uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, 4096 /* one page */);
Expand All @@ -24,35 +28,31 @@ populate_event_header (struct audit_event_header_st *header,
}

static __always_inline int
record_new_context (struct pt_regs *ctx)
record_new_context (struct pt_regs *ctx, long context, long parent)
{
int err;

long context;
err = bpf_usdt_arg (ctx, 0, &context);
if (err < 0)
return err;

long parent;
err = bpf_usdt_arg (ctx, 1, &parent);
if (err < 0)
return err;

/* Tolerate changes in `struct bpf_stack_build_id` definition in the
future with longer hash output. */
unsigned char buf[sizeof(struct bpf_stack_build_id) + MAX_BUILD_ID_SIZE];
struct bpf_stack_build_id *build_id = (struct bpf_stack_build_id *)buf;
err = bpf_get_stack (ctx, buf, bpf_core_type_size (struct bpf_stack_build_id),
BPF_F_USER_STACK | BPF_F_USER_BUILD_ID);
if (err < 0)
return err;
{
DEBUG ("unable to extract build-id: %ld\n", err);
return err;
}

struct audit_new_context_event_st *event =
bpf_ringbuf_reserve (&ringbuf,
sizeof(struct audit_new_context_event_st),
0);
if (!event)
return -ENOMEM;
{
DEBUG ("unable to allocate ringbuf entry: %ld\n", -ENOMEM);
return -ENOMEM;
}

populate_event_header (&event->header,
AUDIT_EVENT_NEW_CONTEXT,
Expand All @@ -75,31 +75,20 @@ record_new_context (struct pt_regs *ctx)
}

static __always_inline int
record_word_data (struct pt_regs *ctx)
record_word_data (struct pt_regs *ctx, long context, const char *key_ptr,
long value)
{
int err;

long context;
err = bpf_usdt_arg (ctx, 0, &context);
if (err < 0)
return err;

long key_ptr;
err = bpf_usdt_arg (ctx, 1, &key_ptr);
if (err < 0)
return err;

long value_ptr;
err = bpf_usdt_arg (ctx, 2, &value_ptr);
if (err < 0)
return err;

struct audit_word_data_event_st *event =
bpf_ringbuf_reserve (&ringbuf,
sizeof(struct audit_word_data_event_st),
0);
if (!event)
return -ENOMEM;
{
DEBUG ("unable to allocate ringbuf entry: %ld\n", -ENOMEM);
return -ENOMEM;
}

populate_event_header (&event->base.header,
AUDIT_EVENT_DATA,
Expand All @@ -109,8 +98,11 @@ record_word_data (struct pt_regs *ctx)
event->base.type = AUDIT_DATA_WORD;
err = bpf_probe_read_user_str (event->base.key, KEY_SIZE, (void *)key_ptr);
if (err < 0)
goto error;
event->value = value_ptr;
{
DEBUG ("unable to read event key: %ld\n", err);
goto error;
}
event->value = value;

bpf_ringbuf_submit (event, 0);
return 0;
Expand All @@ -121,31 +113,20 @@ record_word_data (struct pt_regs *ctx)
}

static __always_inline int
record_string_data (struct pt_regs *ctx)
record_string_data (struct pt_regs *ctx, long context, const char *key_ptr,
const char *value_ptr)
{
int err;

long context;
err = bpf_usdt_arg (ctx, 0, &context);
if (err < 0)
return err;

long key_ptr;
err = bpf_usdt_arg (ctx, 1, &key_ptr);
if (err < 0)
return err;

long value_ptr;
err = bpf_usdt_arg (ctx, 2, &value_ptr);
if (err < 0)
return err;

struct audit_blob_data_event_st *event =
bpf_ringbuf_reserve (&ringbuf,
sizeof(struct audit_blob_data_event_st),
0);
if (!event)
return -ENOMEM;
{
DEBUG ("unable to allocate ringbuf entry: %ld\n", -ENOMEM);
return -ENOMEM;
}

populate_event_header (&event->base.header,
AUDIT_EVENT_DATA,
Expand All @@ -155,12 +136,18 @@ record_string_data (struct pt_regs *ctx)
event->base.type = AUDIT_DATA_STRING;
err = bpf_probe_read_user_str (event->base.key, KEY_SIZE, (void *)key_ptr);
if (err < 0)
goto error;
{
DEBUG ("unable to read event key: %ld\n", err);
goto error;
}

err = bpf_probe_read_user_str (event->value, VALUE_SIZE,
(void *)value_ptr);
if (err < 0)
goto error;
{
DEBUG ("unable to read event data: %ld\n", err);
goto error;
}

event->size = err & (VALUE_SIZE - 1);

Expand All @@ -173,36 +160,27 @@ record_string_data (struct pt_regs *ctx)
}

static __always_inline int
record_blob_data (struct pt_regs *ctx)
record_blob_data (struct pt_regs *ctx, long context, const char *key_ptr)
{
int err;

long context;
err = bpf_usdt_arg (ctx, 0, &context);
if (err < 0)
return err;

long key_ptr;
err = bpf_usdt_arg (ctx, 1, &key_ptr);
if (err < 0)
return err;

long value_ptr;
err = bpf_usdt_arg (ctx, 2, &value_ptr);
if (err < 0)
return err;

long value_size;
err = bpf_usdt_arg (ctx, 3, &value_size);
if (err < 0)
return err;
{
DEBUG ("unable to determine value size: %ld\n", err);
return err;
}

struct audit_blob_data_event_st *event =
bpf_ringbuf_reserve (&ringbuf,
sizeof(struct audit_blob_data_event_st),
0);
if (!event)
return -ENOMEM;
{
DEBUG ("unable to allocate ringbuf entry: %ld\n", -ENOMEM);
return -ENOMEM;
}

populate_event_header (&event->base.header,
AUDIT_EVENT_DATA,
Expand All @@ -212,12 +190,30 @@ record_blob_data (struct pt_regs *ctx)
event->base.type = AUDIT_DATA_BLOB;
err = bpf_probe_read_user_str (event->base.key, KEY_SIZE, (void *)key_ptr);
if (err < 0)
goto error;
{
DEBUG ("unable to read event key: %ld\n", err);
goto error;
}

value_size &= (VALUE_SIZE - 1);
err = bpf_probe_read_user (event->value, value_size, (void *)value_ptr);
if (err < 0)
goto error;
if (value_size > 0)
{
long value_ptr;

err = bpf_usdt_arg (ctx, 2, &value_ptr);
if (err < 0)
{
DEBUG ("unable to read value: %ld\n", err);
goto error;
}

value_size &= (VALUE_SIZE - 1);
ueno marked this conversation as resolved.
Show resolved Hide resolved
err = bpf_probe_read_user (event->value, value_size, (void *)value_ptr);
if (err < 0)
{
DEBUG ("unable to read event data: %ld\n", err);
goto error;
}
}

event->size = value_size;

Expand All @@ -231,30 +227,31 @@ record_blob_data (struct pt_regs *ctx)

SEC("usdt")
int
BPF_USDT(new_context)
BPF_USDT(new_context, long context, long parent)
{
return record_new_context(ctx);
return record_new_context(ctx, context, parent);
}

SEC("usdt")
int
BPF_USDT(word_data)
BPF_USDT(word_data, long context, const char *key_ptr, long value)
{
return record_word_data(ctx);
return record_word_data(ctx, context, key_ptr, value);
}

SEC("usdt")
int
BPF_USDT(string_data)
BPF_USDT(string_data, long context, const char *key_ptr,
const char *value_ptr)
{
return record_string_data(ctx);
return record_string_data(ctx, context, key_ptr, value_ptr);
}

SEC("usdt")
int
BPF_USDT(blob_data)
BPF_USDT(blob_data, long context, const char *key_ptr)
{
return record_blob_data(ctx);
return record_blob_data(ctx, context, key_ptr);
}

char LICENSE[] SEC("license") = "GPL";
6 changes: 5 additions & 1 deletion agent/tests/coalesce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,13 @@ fn test_probe_coalesce() {
.expect("unable to spawn agent");

// Wait until the agent process starts up
while !log_path.exists() {
for _ in 0..5 {
if log_path.exists() {
break;
}
thread::sleep(Duration::from_millis(100));
}
assert!(log_path.exists());

let result = panic::catch_unwind(|| {
let foo = String::from("foo\0");
Expand Down
6 changes: 5 additions & 1 deletion agent/tests/no_coalesce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,13 @@ fn test_probe_no_coalesce() {
.expect("unable to spawn agent");

// Wait until the agent starts up
while !log_path.exists() {
for _ in 0..5 {
if log_path.exists() {
break;
}
thread::sleep(Duration::from_millis(100));
}
assert!(log_path.exists());

let result = panic::catch_unwind(|| {
let foo = String::from("foo\0");
Expand Down