Skip to content

Commit 5aeb166

Browse files
cosmo0920edsiper
authored andcommitted
tests: in_ebpf_exec_handler: Add a test case for exec handler
Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
1 parent 85d4388 commit 5aeb166

2 files changed

Lines changed: 274 additions & 0 deletions

File tree

tests/runtime/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,17 @@ if(FLB_IN_EBPF)
171171
"../../plugins/in_ebpf/traces/tcp/handler.c"
172172
)
173173

174+
add_ebpf_handler_test(
175+
"exec"
176+
"in_ebpf_exec_handler.c"
177+
"../../plugins/in_ebpf/traces/exec/handler.c"
178+
)
179+
174180
add_dependencies(flb-rt-in_ebpf_bind_handler fluent-bit-static)
175181
add_dependencies(flb-rt-in_ebpf_signal_handler fluent-bit-static)
176182
add_dependencies(flb-rt-in_ebpf_malloc_handler fluent-bit-static)
177183
add_dependencies(flb-rt-in_ebpf_tcp_handler fluent-bit-static)
184+
add_dependencies(flb-rt-in_ebpf_exec_handler fluent-bit-static)
178185

179186
endif()
180187

Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
#include <stdio.h>
2+
#include <string.h>
3+
#include <assert.h>
4+
#include <fluent-bit/flb_log_event_encoder.h>
5+
#include <fluent-bit/flb_input_plugin.h>
6+
#include <fluent-bit/flb_log_event_decoder.h>
7+
#include "flb_tests_runtime.h"
8+
9+
#include "../../plugins/in_ebpf/traces/includes/common/event_context.h"
10+
#include "../../plugins/in_ebpf/traces/includes/common/events.h"
11+
#include "../../plugins/in_ebpf/traces/includes/common/encoder.h"
12+
#include "../../plugins/in_ebpf/traces/exec/handler.h"
13+
14+
struct test_context {
15+
struct trace_event_context event_ctx;
16+
struct flb_input_instance *ins;
17+
struct flb_log_event_decoder *decoder;
18+
};
19+
20+
static struct test_context *init_test_context()
21+
{
22+
struct test_context *ctx = flb_calloc(1, sizeof(struct test_context));
23+
24+
if (!ctx) {
25+
return NULL;
26+
}
27+
28+
ctx->ins = flb_calloc(1, sizeof(struct flb_input_instance));
29+
if (!ctx->ins) {
30+
flb_free(ctx);
31+
return NULL;
32+
}
33+
34+
ctx->event_ctx.log_encoder = flb_log_event_encoder_create(FLB_LOG_EVENT_FORMAT_DEFAULT);
35+
if (!ctx->event_ctx.log_encoder) {
36+
flb_free(ctx->ins);
37+
flb_free(ctx);
38+
return NULL;
39+
}
40+
41+
ctx->decoder = flb_log_event_decoder_create(NULL, 0);
42+
if (!ctx->decoder) {
43+
flb_log_event_encoder_destroy(ctx->event_ctx.log_encoder);
44+
flb_free(ctx->ins);
45+
flb_free(ctx);
46+
return NULL;
47+
}
48+
49+
ctx->ins->context = &ctx->event_ctx;
50+
ctx->event_ctx.ins = ctx->ins;
51+
52+
return ctx;
53+
}
54+
55+
static void cleanup_test_context(struct test_context *ctx)
56+
{
57+
if (!ctx) {
58+
return;
59+
}
60+
61+
if (ctx->decoder) {
62+
flb_log_event_decoder_destroy(ctx->decoder);
63+
}
64+
65+
if (ctx->event_ctx.log_encoder) {
66+
flb_log_event_encoder_destroy(ctx->event_ctx.log_encoder);
67+
}
68+
69+
if (ctx->ins) {
70+
flb_free(ctx->ins);
71+
}
72+
73+
flb_free(ctx);
74+
}
75+
76+
static int key_matches(msgpack_object key, const char *str)
77+
{
78+
if (key.type != MSGPACK_OBJECT_STR) {
79+
return 0;
80+
}
81+
82+
return (strncmp(key.via.str.ptr, str, key.via.str.size) == 0 &&
83+
strlen(str) == key.via.str.size);
84+
}
85+
86+
static void verify_decoded_values(struct flb_log_event *event,
87+
const struct event *original)
88+
{
89+
int seen_pid = FLB_FALSE;
90+
int seen_stage = FLB_FALSE;
91+
int seen_ppid = FLB_FALSE;
92+
int seen_filename = FLB_FALSE;
93+
int seen_argv = FLB_FALSE;
94+
int seen_argv1 = FLB_FALSE;
95+
int seen_argv2 = FLB_FALSE;
96+
int seen_argv_last = FLB_FALSE;
97+
int seen_argc = FLB_FALSE;
98+
int seen_error_raw = FLB_FALSE;
99+
msgpack_object_kv *kv;
100+
int i;
101+
102+
TEST_CHECK(event != NULL);
103+
TEST_CHECK(event->body->type == MSGPACK_OBJECT_MAP);
104+
105+
for (i = 0; i < event->body->via.map.size; i++) {
106+
kv = &event->body->via.map.ptr[i];
107+
108+
if (key_matches(kv->key, "pid")) {
109+
seen_pid = FLB_TRUE;
110+
TEST_CHECK(kv->val.type == MSGPACK_OBJECT_POSITIVE_INTEGER);
111+
TEST_CHECK(kv->val.via.u64 == original->common.pid);
112+
}
113+
else if (key_matches(kv->key, "stage")) {
114+
seen_stage = FLB_TRUE;
115+
TEST_CHECK(kv->val.type == MSGPACK_OBJECT_STR);
116+
if (original->details.execve.stage == EXECVE_STAGE_ENTER) {
117+
TEST_CHECK(strncmp(kv->val.via.str.ptr, "enter", kv->val.via.str.size) == 0);
118+
}
119+
else if (original->details.execve.stage == EXECVE_STAGE_EXIT) {
120+
TEST_CHECK(strncmp(kv->val.via.str.ptr, "exit", kv->val.via.str.size) == 0);
121+
}
122+
else {
123+
TEST_CHECK(strncmp(kv->val.via.str.ptr, "unknown", kv->val.via.str.size) == 0);
124+
}
125+
}
126+
else if (key_matches(kv->key, "ppid")) {
127+
seen_ppid = FLB_TRUE;
128+
TEST_CHECK(kv->val.type == MSGPACK_OBJECT_POSITIVE_INTEGER);
129+
TEST_CHECK(kv->val.via.u64 == original->details.execve.ppid);
130+
}
131+
else if (key_matches(kv->key, "filename")) {
132+
seen_filename = FLB_TRUE;
133+
TEST_CHECK(kv->val.type == MSGPACK_OBJECT_STR);
134+
TEST_CHECK(kv->val.via.str.size ==
135+
strlen(original->details.execve.filename));
136+
TEST_CHECK(strncmp(kv->val.via.str.ptr,
137+
original->details.execve.filename,
138+
kv->val.via.str.size) == 0);
139+
}
140+
else if (key_matches(kv->key, "argv")) {
141+
seen_argv = FLB_TRUE;
142+
TEST_CHECK(kv->val.type == MSGPACK_OBJECT_STR);
143+
TEST_CHECK(kv->val.via.str.size ==
144+
strlen(original->details.execve.argv));
145+
TEST_CHECK(strncmp(kv->val.via.str.ptr,
146+
original->details.execve.argv[0],
147+
kv->val.via.str.size) == 0);
148+
}
149+
else if (key_matches(kv->key, "argv1")) {
150+
seen_argv1 = FLB_TRUE;
151+
TEST_CHECK(kv->val.type == MSGPACK_OBJECT_STR);
152+
TEST_CHECK(strncmp(kv->val.via.str.ptr,
153+
original->details.execve.argv[1],
154+
kv->val.via.str.size) == 0);
155+
}
156+
else if (key_matches(kv->key, "argv2")) {
157+
seen_argv2 = FLB_TRUE;
158+
TEST_CHECK(kv->val.type == MSGPACK_OBJECT_STR);
159+
TEST_CHECK(strncmp(kv->val.via.str.ptr,
160+
original->details.execve.argv[2],
161+
kv->val.via.str.size) == 0);
162+
}
163+
else if (key_matches(kv->key, "argv_last")) {
164+
seen_argv_last = FLB_TRUE;
165+
TEST_CHECK(kv->val.type == MSGPACK_OBJECT_STR);
166+
TEST_CHECK(strncmp(kv->val.via.str.ptr,
167+
original->details.execve.argv_last,
168+
kv->val.via.str.size) == 0);
169+
}
170+
else if (key_matches(kv->key, "argc")) {
171+
seen_argc = FLB_TRUE;
172+
TEST_CHECK(kv->val.type == MSGPACK_OBJECT_POSITIVE_INTEGER);
173+
TEST_CHECK(kv->val.via.u64 == original->details.execve.argc);
174+
}
175+
else if (key_matches(kv->key, "error_raw")) {
176+
seen_error_raw = FLB_TRUE;
177+
TEST_CHECK(kv->val.type == MSGPACK_OBJECT_POSITIVE_INTEGER ||
178+
kv->val.type == MSGPACK_OBJECT_NEGATIVE_INTEGER);
179+
TEST_CHECK(kv->val.via.i64 == original->details.execve.error_raw);
180+
}
181+
}
182+
183+
TEST_CHECK(seen_pid == FLB_TRUE);
184+
TEST_CHECK(seen_stage == FLB_TRUE);
185+
TEST_CHECK(seen_ppid == FLB_TRUE);
186+
TEST_CHECK(seen_filename == FLB_TRUE);
187+
TEST_CHECK(seen_argv == FLB_TRUE);
188+
TEST_CHECK(seen_argv1 == FLB_TRUE);
189+
TEST_CHECK(seen_argv2 == FLB_TRUE);
190+
TEST_CHECK(seen_argv_last == FLB_TRUE);
191+
TEST_CHECK(seen_argc == FLB_TRUE);
192+
TEST_CHECK(seen_error_raw == FLB_TRUE);
193+
}
194+
195+
void test_exec_event_encoding()
196+
{
197+
struct event test_event = {
198+
.type = EVENT_TYPE_EXECVE,
199+
.common = {
200+
.pid = 100,
201+
.tid = 101,
202+
.uid = 1000,
203+
.gid = 1000,
204+
.comm = "bash"
205+
},
206+
.details.execve = {
207+
.stage = EXECVE_STAGE_EXIT,
208+
.ppid = 1,
209+
.filename = "/usr/bin/bash",
210+
.argv = {"bash", "-lc", "echo hello"},
211+
.argv_last = "echo hello",
212+
.argc = 3,
213+
.error_raw = 0
214+
}
215+
};
216+
struct flb_log_event log_event;
217+
struct test_context *ctx;
218+
int ret;
219+
220+
ctx = init_test_context();
221+
TEST_CHECK(ctx != NULL);
222+
223+
ret = encode_exec_event(ctx->ins, ctx->event_ctx.log_encoder, &test_event);
224+
TEST_CHECK(ret == 0);
225+
TEST_CHECK(ctx->event_ctx.log_encoder->output_length > 0);
226+
227+
ret = flb_log_event_decoder_init(ctx->decoder,
228+
ctx->event_ctx.log_encoder->output_buffer,
229+
ctx->event_ctx.log_encoder->output_length);
230+
TEST_CHECK(ret == 0);
231+
232+
ret = flb_log_event_decoder_next(ctx->decoder, &log_event);
233+
TEST_CHECK(ret == FLB_EVENT_DECODER_SUCCESS);
234+
235+
verify_decoded_values(&log_event, &test_event);
236+
237+
cleanup_test_context(ctx);
238+
}
239+
240+
void test_trace_exec_handler_negative_paths()
241+
{
242+
struct test_context *ctx;
243+
struct event invalid_type_event;
244+
struct event valid_event;
245+
int ret;
246+
247+
ctx = init_test_context();
248+
TEST_CHECK(ctx != NULL);
249+
250+
memset(&invalid_type_event, 0, sizeof(struct event));
251+
invalid_type_event.type = EVENT_TYPE_SIGNAL;
252+
ret = trace_exec_handler(&ctx->event_ctx, &invalid_type_event, sizeof(struct event));
253+
TEST_CHECK(ret == -1);
254+
255+
memset(&valid_event, 0, sizeof(struct event));
256+
valid_event.type = EVENT_TYPE_EXECVE;
257+
ret = trace_exec_handler(&ctx->event_ctx, &valid_event, sizeof(struct event) - 1);
258+
TEST_CHECK(ret == -1);
259+
260+
cleanup_test_context(ctx);
261+
}
262+
263+
TEST_LIST = {
264+
{"exec_event_encoding", test_exec_event_encoding},
265+
{"trace_exec_handler_negative_paths", test_trace_exec_handler_negative_paths},
266+
{NULL, NULL}
267+
};

0 commit comments

Comments
 (0)