Skip to content

Commit

Permalink
daemon: add running uprobe program support (#52)
Browse files Browse the repository at this point in the history
* runtime: add comments

* move to user

* daemon: improve config

* add driver defines

* add minimal

* fix bpftime tool open

* remove use of global open type

* serialize and run the bpftim tool

* fix tracer error

* implement driver

* add daemon test

* fxi unit test

* fix uprobe path config

* daemon: impl trace and insert

* daemon: add info

* fix seg fault

* fix handle event

* fix export module name

* fix ci

---------

Co-authored-by: Littlefisher619 <i@littlefisher.me>
  • Loading branch information
yunwei37 and Littlefisher619 authored Oct 24, 2023
1 parent 451397a commit e5b1081
Show file tree
Hide file tree
Showing 53 changed files with 1,518 additions and 315 deletions.
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: install coverage test docs help build clean build-arm run-arm run-arm64 build-arm64 build-arm32
.PHONY: install coverage test docs help build clean unit-test-daemon unit-test unit-test-runtime
.DEFAULT_GOAL := help

define BROWSER_PYSCRIPT
Expand Down Expand Up @@ -34,11 +34,16 @@ build-unit-test:
cmake -Bbuild -DBPFTIME_ENABLE_UNIT_TESTING=1 -DCMAKE_BUILD_TYPE:STRING=Debug
cmake --build build --config Debug --target bpftime_runtime_tests

unit-test: ## run catch2 unit tests
unit-test-daemon:
build/daemon/test/bpftime_daemon_tests

unit-test-runtime: ## run catch2 unit tests
make -C runtime/test/bpf && cp runtime/test/bpf/*.bpf.o build/runtime/test/
./build/runtime/unit-test/bpftime_runtime_tests
cd build/runtime/test && ctest -VV

unit-test: unit-test-daemon unit-test-runtime ## run catch2 unit tests

build: ## build the package
cmake -Bbuild -DBPFTIME_ENABLE_UNIT_TESTING=1
cmake --build build --config Debug
Expand Down
2 changes: 1 addition & 1 deletion daemon/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ package.yaml
ecli
bootstrap
.output
bpf-mocker
bpf_tracer
victim
victim2
test.txt
Expand Down
46 changes: 39 additions & 7 deletions daemon/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,46 @@
# Create a target that builds the ebpf program
add_ebpf_program_target(bpftime_daemon_ebpf_target ${CMAKE_CURRENT_SOURCE_DIR}/bpf-mocker.bpf.c ${CMAKE_CURRENT_BINARY_DIR}/bpf-mocker.bpf.o)
add_ebpf_program_target(bpftime_daemon_ebpf_target ${CMAKE_CURRENT_SOURCE_DIR}/kernel/bpf_tracer.bpf.c ${CMAKE_CURRENT_BINARY_DIR}/bpf_tracer.bpf.o)

# Create a target that generated the bpf skeleton
add_bpf_skel_generating_target(bpftime_daemon_ebpf_skel ${CMAKE_CURRENT_BINARY_DIR}/bpf-mocker.bpf.o ${CMAKE_CURRENT_BINARY_DIR}/bpf-mocker.skel.h)
add_bpf_skel_generating_target(bpftime_daemon_ebpf_skel ${CMAKE_CURRENT_BINARY_DIR}/bpf_tracer.bpf.o ${CMAKE_CURRENT_BINARY_DIR}/bpf_tracer.skel.h)

add_dependencies(bpftime_daemon_ebpf_skel bpftime_daemon_ebpf_target)

add_executable(bpftime_daemon main.cpp bpf-mocker.cpp handle_bpf_event.cpp)
add_dependencies(bpftime_daemon bpftime_daemon_ebpf_skel libbpf spdlog::spdlog)
add_library(libbpftime_daemon STATIC
user/bpf_tracer.cpp
user/handle_bpf_event.cpp
user/bpftime_driver.cpp
)

target_include_directories(bpftime_daemon PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${LIBBPF_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(bpftime_daemon PRIVATE ${LIBBPF_LIBRARIES} elf z spdlog::spdlog)
set_property(TARGET bpftime_daemon PROPERTY CXX_STANDARD 20)
add_executable(bpftime_daemon
user/main.cpp
)

add_dependencies(libbpftime_daemon
bpftime_daemon_ebpf_skel
libbpf
spdlog::spdlog
runtime
)

target_include_directories(libbpftime_daemon PRIVATE
${CMAKE_CURRENT_BINARY_DIR}
${LIBBPF_INCLUDE_DIRS}/uapi
${LIBBPF_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../vm/include
${CMAKE_CURRENT_SOURCE_DIR}/../runtime/include
)
target_link_libraries(libbpftime_daemon PRIVATE
${LIBBPF_LIBRARIES}
elf
z
spdlog::spdlog
runtime
)
set_property(TARGET libbpftime_daemon PROPERTY CXX_STANDARD 20)

add_dependencies(bpftime_daemon libbpftime_daemon)
target_link_libraries(bpftime_daemon PRIVATE libbpftime_daemon)

add_subdirectory(test)
4 changes: 3 additions & 1 deletion daemon/README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
# bpf-mocker
# bpftime daemon: trace and replay eBPF related events

The bpftime daemon is a tool to trace and replay eBPF related events.
It's similar to our syscall server but run together with kernel eBPF.
11 changes: 10 additions & 1 deletion daemon/bpf-mocker-event.h → daemon/bpf_tracer_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ enum event_type {
SYS_OPEN,
SYS_CLOSE,
SYS_BPF,
SYS_IOCTL,
SYS_PERF_EVENT_OPEN,
BPF_PROG_LOAD_EVENT,
};
Expand Down Expand Up @@ -46,7 +47,6 @@ struct event {
int cpu;

// uprobe data
uint64_t offset;
char name_or_path[NAME_MAX];
} perf_event_data;

Expand All @@ -55,11 +55,20 @@ struct event {
unsigned int insn_cnt;
char prog_name[BPF_OBJ_NAME_LEN];
unsigned int insns[MAX_INSN_SIZE];
// used as key for later lookup in userspace
unsigned long long insns_ptr;
} bpf_loaded_prog;

struct {
int fd;
} close_data;

struct {
int fd;
unsigned long req;
int data;
int ret;
} ioctl_data;
};
};

Expand Down
14 changes: 0 additions & 14 deletions daemon/daemon_config.hpp

This file was deleted.

88 changes: 4 additions & 84 deletions daemon/bpf-utils.h → daemon/kernel/bpf_defs.h
Original file line number Diff line number Diff line change
@@ -1,88 +1,8 @@
#ifndef BPF_UTILS_H
#define BPF_UTILS_H
#ifndef BPFTIME_BPF_DEFS_H
#define BPFTIME_BPF_DEFS_H

#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
#include "bpf-mocker-event.h"

// filter bpf program pid
const volatile int target_pid = 0;
// current bpf program pid, avoid breaking current process
const volatile int current_pid = 0;
// disable modify bpf program
const volatile bool disable_modify = 0;

const volatile int uprobe_perf_type = 0;
const volatile int kprobe_perf_type = 0;

// print event to userspace
struct {
__uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, 256 * 1024);
} rb SEC(".maps");

// pid & fd for all bpf related fds
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 10240);
__type(key, u64);
__type(value, u64);
} bpf_fd_map SEC(".maps");

#define PID_MASK_FOR_PFD 0xffffffff00000000
#define FD_MASK_FOR_PFD 0x00000000ffffffff
#define MAKE_PFD(pid, fd) (((u64)pid << 32) | fd)

static __always_inline bool is_bpf_fd(u32 fd) {
u32 pid = bpf_get_current_pid_tgid() >> 32;
u64 key = MAKE_PFD(pid, fd);
u64 *pfd = bpf_map_lookup_elem(&bpf_fd_map, &key);
if (!pfd) {
return false;
}
return true;
}

static __always_inline void set_bpf_fd_if_positive(u32 fd) {
if (fd < 0) {
return;
}
u32 pid = bpf_get_current_pid_tgid() >> 32;
u64 key = MAKE_PFD(pid, fd);
bpf_map_update_elem(&bpf_fd_map, &key, &key, 0);
}

static __always_inline void clear_bpf_fd(int fd) {
u32 pid = bpf_get_current_pid_tgid() >> 32;
u64 key = MAKE_PFD(pid, fd);
bpf_map_delete_elem(&bpf_fd_map, &key);
}

static __always_inline bool filter_target(void)
{
u64 pid = bpf_get_current_pid_tgid() >> 32;
if (target_pid && pid != target_pid) {
// filter target pid
return false;
}
if (current_pid && pid == current_pid) {
// avoid breaking current process
return false;
}
return true;
}

static __always_inline struct event* fill_basic_event_info(void) {
struct event *event = bpf_ringbuf_reserve(&rb, sizeof(struct event), 0);
if (!event) {
return NULL;
}
event->pid = bpf_get_current_pid_tgid() >> 32;
bpf_get_current_comm(&event->comm, sizeof(event->comm));
return event;
}


/* BPF has 10 general purpose 64-bit registers and stack frame. */
#define MAX_BPF_REG __MAX_BPF_REG
Expand Down Expand Up @@ -189,4 +109,4 @@ static __always_inline struct event* fill_basic_event_info(void) {
.off = 0, \
.imm = 0 })

#endif // BPF_UTILS_H
#endif //BPFTIME_BPF_DEFS_H
36 changes: 36 additions & 0 deletions daemon/kernel/bpf_kernel_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#ifndef BPFTIME_KERNEL_CONFIG_H
#define BPFTIME_KERNEL_CONFIG_H

#include <vmlinux.h>

#define PATH_LENTH 255

// filter bpf program pid
const volatile int target_pid = 0;
// current bpf program pid, avoid breaking current process
const volatile int current_pid = 0;
// enable modify bpf program
const volatile bool enable_replace_prog = 0;
// enable modify uprobe
const volatile bool enable_replace_uprobe = 0;
const char new_uprobe_path[PATH_LENTH] = "\0";

const volatile int uprobe_perf_type = 0;
const volatile int kprobe_perf_type = 0;


static __always_inline bool filter_target(void)
{
u64 pid = bpf_get_current_pid_tgid() >> 32;
if (target_pid && pid != target_pid) {
// filter target pid
return false;
}
if (current_pid && pid == current_pid) {
// avoid breaking current process
return false;
}
return true;
}

#endif // BPFTIME_KERNEL_CONFIG_H
Loading

0 comments on commit e5b1081

Please sign in to comment.