From 93ad72e7b43883a6926980d624d120b35ffbb404 Mon Sep 17 00:00:00 2001 From: chenjingwen Date: Sat, 18 Nov 2023 20:10:35 +0800 Subject: [PATCH] ebpf: support disable ebpf prog if not needed Signed-off-by: chenjingwen --- include/secDetector_topic.h | 1 + observer_agent/CMakeLists.txt | 5 +- observer_agent/ebpf/CMakeLists.txt | 2 +- observer_agent/ebpf/fentry.c | 47 +++++++++++++++- observer_agent/ebpf/fentry.h | 6 ++- observer_agent/ebpf/file_ebpf/CMakeLists.txt | 2 +- .../ebpf/file_ebpf/file_fentry.bpf.c | 2 +- observer_agent/ebpf/file_ebpf/file_fentry.c | 53 ++++++++++++++++++- .../ebpf/file_ebpf/test_file_fentry.c | 2 +- observer_agent/ebpf/test_fentry.c | 2 +- observer_agent/service/ebpf_converter.cpp | 2 +- observer_agent/service/main.cpp | 24 ++++++--- 12 files changed, 130 insertions(+), 18 deletions(-) diff --git a/include/secDetector_topic.h b/include/secDetector_topic.h index ebbb76b..7320042 100644 --- a/include/secDetector_topic.h +++ b/include/secDetector_topic.h @@ -50,4 +50,5 @@ /* memory corruption kmodule list */ #define KMODULELIST 0x00800000 +#define ALL_TOPIC 0xFFFFFFFF #endif diff --git a/observer_agent/CMakeLists.txt b/observer_agent/CMakeLists.txt index a443935..8465044 100644 --- a/observer_agent/CMakeLists.txt +++ b/observer_agent/CMakeLists.txt @@ -7,8 +7,9 @@ set(GRPC_PATH ${CMAKE_CURRENT_SOURCE_DIR}/grpc_comm) add_custom_target(grpc_demo ALL COMMAND make -C ${GRPC_PATH}) -add_executable(secDetectord grpc_comm/client.cpp grpc_comm/server.cpp service/main.cpp service/ringbuffer.cpp - service/ebpf_converter.cpp) +add_executable(secDetectord grpc_comm/client.cpp grpc_comm/server.cpp + service/main.cpp service/ringbuffer.cpp + service/ebpf_converter.cpp) add_dependencies(secDetectord ebpf file_ebpf) target_include_directories(secDetectord PUBLIC service grpc_comm ${CMAKE_SOURCE_DIR}/include .) diff --git a/observer_agent/ebpf/CMakeLists.txt b/observer_agent/ebpf/CMakeLists.txt index 64fdae1..6b97de4 100644 --- a/observer_agent/ebpf/CMakeLists.txt +++ b/observer_agent/ebpf/CMakeLists.txt @@ -6,7 +6,7 @@ add_custom_target(ebpf COMMAND bpftool btf dump file /sys/kernel/btf/vmlinux format c > ${CMAKE_CURRENT_BINARY_DIR}/.output/vmlinux.h COMMAND clang -g -O2 -target bpf -D__TARGET_ARCH_x86 -I${CMAKE_SOURCE_DIR}/include -I${CMAKE_CURRENT_BINARY_DIR}/.output -c ${CMAKE_CURRENT_SOURCE_DIR}/fentry.bpf.c -o ${CMAKE_CURRENT_BINARY_DIR}/.output/fentry.bpf.o COMMAND bpftool gen skeleton ${CMAKE_CURRENT_BINARY_DIR}/.output/fentry.bpf.o > ${CMAKE_CURRENT_BINARY_DIR}/.output/fentry.skel.h - COMMAND cc -g -Wall -fPIC -I${CMAKE_CURRENT_BINARY_DIR}/.output -I${CMAKE_CURRENT_SOURCE_DIR} -c ${CMAKE_CURRENT_SOURCE_DIR}/fentry.c -o ${CMAKE_CURRENT_BINARY_DIR}/.output/fentry.o + COMMAND cc -g -Wall -fPIC -I${CMAKE_SOURCE_DIR}/include -I${CMAKE_CURRENT_BINARY_DIR}/.output -I${CMAKE_CURRENT_SOURCE_DIR} -c ${CMAKE_CURRENT_SOURCE_DIR}/fentry.c -o ${CMAKE_CURRENT_BINARY_DIR}/.output/fentry.o ) add_executable(test_fentry ${CMAKE_CURRENT_SOURCE_DIR}/test_fentry.c) diff --git a/observer_agent/ebpf/fentry.c b/observer_agent/ebpf/fentry.c index c3e026f..cf7787a 100644 --- a/observer_agent/ebpf/fentry.c +++ b/observer_agent/ebpf/fentry.c @@ -14,6 +14,7 @@ * Description: secDetector process hook */ #include "fentry.h" +#include "secDetector_topic.h" #include "ebpf_types.h" #include "fentry.skel.h" #include @@ -32,7 +33,49 @@ void StopProcesseBPFProg() exiting = 1; } -int StartProcesseBPFProg(ring_buffer_sample_fn cb, unsigned int rb_sz) +static void DisableProg(struct bpf_object_skeleton *s, const char *prog_name) +{ + int n = s->prog_cnt; + + for (int i = 0; i < n; i++) { + if (strcmp(s->progs[i].name, prog_name) == 0) { + fprintf(stderr, "%s is not enabled\n", prog_name); + bpf_link__destroy(*s->progs[i].link); + s->progs[i].link = NULL; + + /* exchange the last one */ + s->progs[i].prog = s->progs[n - 1].prog; + s->progs[i].link = s->progs[n - 1].link; + s->progs[i].name = s->progs[n - 1].name; + s->prog_cnt--; + } + } +} + + +static void DisableProgBasedOnMask(struct bpf_object_skeleton *skel, int mask) +{ + if ((mask & CREATPROCESS) == 0) { + DisableProg(skel, "handle_exec"); + DisableProg(skel, "handle_fork"); + DisableProg(skel, "handle_bprm_check"); + } + + if ((mask & DESTROYPROCESS) == 0) { + DisableProg(skel, "handle_exit"); + } + + if ((mask & SETPROCESSATTR) == 0) { + DisableProg(skel, "handle_commit_creds"); + } + + if ((mask & EXECCMD) == 0) { + DisableProg(skel, "handle_execve_cmd"); + } +} + + +int StartProcesseBPFProg(ring_buffer_sample_fn cb, unsigned int rb_sz, int mask) { struct fentry_bpf *skel; struct ring_buffer *rb = NULL; @@ -70,6 +113,8 @@ int StartProcesseBPFProg(ring_buffer_sample_fn cb, unsigned int rb_sz) goto cleanup; } + DisableProgBasedOnMask(skel->skeleton, mask); + while (exiting == 0) { err = ring_buffer__poll(rb, 1000 /* timeout ms*/); diff --git a/observer_agent/ebpf/fentry.h b/observer_agent/ebpf/fentry.h index b0819f3..172bafe 100644 --- a/observer_agent/ebpf/fentry.h +++ b/observer_agent/ebpf/fentry.h @@ -19,13 +19,15 @@ extern "C" { #endif +#include "fentry.h" #include +extern struct fentry_bpf *process_bpf_skel; void StopProcesseBPFProg(); -int StartProcesseBPFProg(ring_buffer_sample_fn cb, unsigned int rb_sz); +int StartProcesseBPFProg(ring_buffer_sample_fn cb, unsigned int rb_sz, int mask); void StopFileBPFProg(); -int StartFileBPFProg(ring_buffer_sample_fn cb, unsigned int rb_sz); +int StartFileBPFProg(ring_buffer_sample_fn cb, unsigned int rb_sz, int mask); #ifdef __cplusplus } #endif diff --git a/observer_agent/ebpf/file_ebpf/CMakeLists.txt b/observer_agent/ebpf/file_ebpf/CMakeLists.txt index 024379e..9517832 100644 --- a/observer_agent/ebpf/file_ebpf/CMakeLists.txt +++ b/observer_agent/ebpf/file_ebpf/CMakeLists.txt @@ -7,7 +7,7 @@ add_custom_target(file_ebpf COMMAND bpftool btf dump file /sys/kernel/btf/vmlinux format c > ${CMAKE_CURRENT_BINARY_DIR}/.output/vmlinux.h COMMAND clang -g -O2 -target bpf -D__TARGET_ARCH_x86 -I${CMAKE_SOURCE_DIR}/include -I${CMAKE_CURRENT_BINARY_DIR}/.output -c ${CMAKE_CURRENT_SOURCE_DIR}/file_fentry.bpf.c -o ${CMAKE_CURRENT_BINARY_DIR}/.output/file_fentry.bpf.o COMMAND bpftool gen skeleton ${CMAKE_CURRENT_BINARY_DIR}/.output/file_fentry.bpf.o > ${CMAKE_CURRENT_BINARY_DIR}/.output/file_fentry.skel.h - COMMAND cc -g -Wall -fPIC -I${CMAKE_CURRENT_BINARY_DIR}/.output -I${CMAKE_CURRENT_SOURCE_DIR} -c ${CMAKE_CURRENT_SOURCE_DIR}/file_fentry.c -o ${CMAKE_CURRENT_BINARY_DIR}/.output/file_fentry.o + COMMAND cc -g -Wall -fPIC -I${CMAKE_SOURCE_DIR}/include -I${CMAKE_CURRENT_BINARY_DIR}/.output -I${CMAKE_CURRENT_SOURCE_DIR} -c ${CMAKE_CURRENT_SOURCE_DIR}/file_fentry.c -o ${CMAKE_CURRENT_BINARY_DIR}/.output/file_fentry.o ) add_executable(test_file_fentry ${CMAKE_CURRENT_SOURCE_DIR}/test_file_fentry.c) diff --git a/observer_agent/ebpf/file_ebpf/file_fentry.bpf.c b/observer_agent/ebpf/file_ebpf/file_fentry.bpf.c index d5f7275..84faf54 100644 --- a/observer_agent/ebpf/file_ebpf/file_fentry.bpf.c +++ b/observer_agent/ebpf/file_ebpf/file_fentry.bpf.c @@ -163,7 +163,7 @@ int BPF_PROG(fexit_vfs_unlink, struct inode *dir, struct dentry *dentry, struct if (!e) return 0; - e->type = 2; + e->type = DELFILE; get_common_info(e); __builtin_memcpy(e->event_name, "vfs_unlink", sizeof("vfs_unlink")); bpf_probe_read(e->file_info.filename, MAX_TEXT_SIZE, dentry->d_name.name); diff --git a/observer_agent/ebpf/file_ebpf/file_fentry.c b/observer_agent/ebpf/file_ebpf/file_fentry.c index 8e83723..bf445ab 100644 --- a/observer_agent/ebpf/file_ebpf/file_fentry.c +++ b/observer_agent/ebpf/file_ebpf/file_fentry.c @@ -5,6 +5,7 @@ #include "../ebpf_types.h" #include "../fentry.h" #include "file_fentry.skel.h" +#include "secDetector_topic.h" #include #include #include @@ -21,7 +22,55 @@ void StopFileBPFProg() exiting = 1; } -int StartFileBPFProg(ring_buffer_sample_fn cb, unsigned int rb_sz) +static void DisableProg(struct bpf_object_skeleton *s, const char *prog_name) +{ + int n = s->prog_cnt; + + for (int i = 0; i < n; i++) { + if (strcmp(s->progs[i].name, prog_name) == 0) { + fprintf(stderr, "%s is not enabled\n", prog_name); + bpf_link__destroy(*s->progs[i].link); + s->progs[i].link = NULL; + + /* exchange the last one */ + s->progs[i].prog = s->progs[n - 1].prog; + s->progs[i].link = s->progs[n - 1].link; + s->progs[i].name = s->progs[n - 1].name; + s->prog_cnt--; + break; + } + } +} + +static void DisableProgBasedOnMask(struct bpf_object_skeleton *skel, int mask) +{ + if ((mask & CREATFILE) == 0) { + DisableProg(skel, "do_filp_open_exit"); + } + + if ((mask & DELFILE) == 0) { + DisableProg(skel, "fexit_vfs_unlink"); + } + + if ((mask & WRITEFILE) == 0) { + DisableProg(skel, "fexit_vfs_write"); + } + + if ((mask & READFILE) == 0) { + DisableProg(skel, "fexit_vfs_read"); + } + + if ((mask & SETFILEATTR) == 0) { + DisableProg(skel, "fexit_vfs_utimes"); + DisableProg(skel, "fexit_chown_common"); + DisableProg(skel, "fexit_chmod_common"); + DisableProg(skel, "fentry__vfs_setxattr_noperm"); + DisableProg(skel, "fentry__vfs_removexattr_locked"); + DisableProg(skel, "fentry_vfs_rename"); + } +} + +int StartFileBPFProg(ring_buffer_sample_fn cb, unsigned int rb_sz, int mask) { struct file_fentry_bpf *skel; struct ring_buffer *rb = NULL; @@ -59,6 +108,8 @@ int StartFileBPFProg(ring_buffer_sample_fn cb, unsigned int rb_sz) goto cleanup; } + DisableProgBasedOnMask(skel->skeleton, mask); + while (exiting == 0) { err = ring_buffer__poll(rb, 1000 /* timeout ms*/); diff --git a/observer_agent/ebpf/file_ebpf/test_file_fentry.c b/observer_agent/ebpf/file_ebpf/test_file_fentry.c index 3a49a5c..a9ea778 100644 --- a/observer_agent/ebpf/file_ebpf/test_file_fentry.c +++ b/observer_agent/ebpf/file_ebpf/test_file_fentry.c @@ -26,5 +26,5 @@ int main() { /* Set up libbpf errors and debug info callback */ libbpf_set_print(libbpf_print_fn); - StartFileBPFProg(handle_event, 4 * 1024 * 1024); + StartFileBPFProg(handle_event, 4 * 1024 * 1024, 0xffffffff); } diff --git a/observer_agent/ebpf/test_fentry.c b/observer_agent/ebpf/test_fentry.c index 039153b..0616958 100644 --- a/observer_agent/ebpf/test_fentry.c +++ b/observer_agent/ebpf/test_fentry.c @@ -39,5 +39,5 @@ int main() { /* Set up libbpf errors and debug info callback */ libbpf_set_print(libbpf_print_fn); - StartProcesseBPFProg(handle_event, 4 * 1024 * 1024); + StartProcesseBPFProg(handle_event, 4 * 1024 * 1024, 0xffffffff); } diff --git a/observer_agent/service/ebpf_converter.cpp b/observer_agent/service/ebpf_converter.cpp index eddc96e..6e42b6c 100644 --- a/observer_agent/service/ebpf_converter.cpp +++ b/observer_agent/service/ebpf_converter.cpp @@ -76,7 +76,7 @@ static std::string extract_common_info(struct ebpf_event *e) { std::ostringstream ss; ss << "timestamp:" << get_local_time() << " event_name:" << e->event_name << " exe:" << FindProcessPathFromPid(e) - << " pid:" << e->pid << " tgid:" << e->tgid << " uid:" << e->uid << " gid:" << e->gid << " comm:" << e->comm + << " pid:" << e->pid << " tgid:" << e->tgid << " pgid:" << e->pgid << " uid:" << e->uid << " gid:" << e->gid << " comm:" << e->comm << " sid:" << e->sid << " ppid:" << e->ppid << " pcomm:" << e->pcomm << " nodename:" << e->nodename << " pns:" << e->pns << " root_pns:" << e->pns; return ss.str(); diff --git a/observer_agent/service/main.cpp b/observer_agent/service/main.cpp index 3e784c7..940cf83 100644 --- a/observer_agent/service/main.cpp +++ b/observer_agent/service/main.cpp @@ -18,6 +18,7 @@ #include "ebpf/fentry.h" #include "ebpf_converter.h" #include "ringbuffer.h" +#include "secDetector_topic.h" #include #include #include @@ -44,6 +45,7 @@ using grpc::ServerWriter; #define MAX_RINGBUF_SIZE 1024 static unsigned int ringbuf_size_bytes; static unsigned int ringbuf_size = MIN_RINGBUF_SIZE; +static int topic_mask = ALL_TOPIC; static bool power_of_2(unsigned int num) { @@ -65,7 +67,7 @@ static bool ringbuf_size_check(void) std::cerr << "[secDetector] ringbuf_size should be power of 2" << std::endl; return false; } - + std::cout << "ringbuf size is set to " << ringbuf_size << "Mb" << std::endl; ringbuf_size_bytes = ringbuf_size * 1024 * 1024; return true; @@ -80,6 +82,9 @@ static bool debug = false; static void push_log(int type, const std::string &content) { + if ((topic_mask & type) == 0) + return; + // push to console if debug if (debug) { @@ -122,10 +127,9 @@ int main(int argc, char *argv[]) { int r; int opt; - unsigned int rb_sz; set_signal_handler(); - while ((opt = getopt(argc, argv, "ds:")) != -1) + while ((opt = getopt(argc, argv, "ds:t:")) != -1) { switch (opt) { @@ -135,9 +139,17 @@ int main(int argc, char *argv[]) case 's': ringbuf_size = strtoul(optarg, NULL, 0); break; + case 't': + topic_mask = strtoul(optarg, NULL, 0); + break; } } - + + if (topic_mask == 0) { + std::cerr << "not a valid topic_mask" << std::endl; + return -1; + } + if (!ringbuf_size_check()) { std::cerr << "Not a valid ring buffer size" << std::endl; return -1; @@ -165,8 +177,8 @@ int main(int argc, char *argv[]) } std::thread thread_grpc = std::thread(RunServer); - std::thread thread_ebpf_process = std::thread(StartProcesseBPFProg, ebpf_cb, ringbuf_size_bytes); - std::thread thread_ebpf_file = std::thread(StartFileBPFProg, ebpf_cb, ringbuf_size_bytes); + std::thread thread_ebpf_process = std::thread(StartProcesseBPFProg, ebpf_cb, ringbuf_size_bytes, topic_mask); + std::thread thread_ebpf_file = std::thread(StartFileBPFProg, ebpf_cb, ringbuf_size_bytes, topic_mask); while (exiting == 0) { -- Gitee