-
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
598 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,5 +4,4 @@ eunomia-bpf | |
GPTtrace | ||
docs/setup | ||
docs/tutorials | ||
docs/bpftime | ||
.cache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# available kernel features in userspace | ||
|
||
## avalibale map types | ||
|
||
Userspace eBPF shared memory map types: | ||
|
||
- BPF_MAP_TYPE_HASH | ||
- BPF_MAP_TYPE_ARRAY | ||
- BPF_MAP_TYPE_RINGBUF | ||
- BPF_MAP_TYPE_PERF_EVENT_ARRAY | ||
- BPF_MAP_TYPE_PERCPU_ARRAY | ||
- BPF_MAP_TYPE_PERCPU_HASH | ||
|
||
User-kernel shared maps: | ||
|
||
- BPF_MAP_TYPE_HASH | ||
- BPF_MAP_TYPE_ARRAY | ||
- BPF_MAP_TYPE_PERCPU_ARRAY | ||
- BPF_MAP_TYPE_PERF_EVENT_ARRAY | ||
|
||
## avaliable program types | ||
|
||
Compatible with kernel eBPF program types: | ||
|
||
- tracepoint:raw_syscalls:sys_enter | ||
- tracepoint:syscalls:sys_exit_* | ||
- tracepoint:syscalls:sys_enter_* | ||
- uretprobe:* | ||
- uprobe:* | ||
|
||
## available helpers | ||
|
||
### maps | ||
|
||
- `bpf_map_lookup_elem`: Helper function for looking up an element in a BPF map. | ||
- `bpf_map_update_elem`: Helper function for updating an element in a BPF map. | ||
- `bpf_map_delete_elem`: Helper function for deleting an element from a BPF map. | ||
|
||
### kernel_helper_group | ||
|
||
- `bpf_probe_read`: Helper function for reading data from a kernel address. | ||
- `bpf_ktime_get_ns`: Helper function for getting the current time in nanoseconds. | ||
- `bpf_trace_printk`: Helper function for printing debug messages from eBPF programs. | ||
- `bpf_get_current_pid_tgid`: Helper function for getting the current PID and TGID (Thread Group ID). | ||
- `bpf_get_current_uid_gid`: Helper function for getting the current UID (User ID) and GID (Group ID). | ||
- `bpf_get_current_comm`: Helper function for getting the current process's name. | ||
- `bpf_strncmp`: Helper function for comparing two strings. | ||
- `bpf_get_func_arg`: Helper function for getting the value of a function argument. | ||
- `bpf_get_func_ret`: Helper function for getting the value of a function return ID. | ||
- `bpf_get_retval`: Helper function for getting the return value of a function. | ||
- `bpf_set_retval`: Helper function for setting the return value of a function. | ||
- `bpf_probe_read_str`: Helper function for reading a null-terminated string from a user address. | ||
- `bpf_get_stack`: Helper function for retrieving the current kernel stack. | ||
|
||
## Others | ||
|
||
- Support kernel or userspace verifier | ||
- Test JIT with bpf_conformance |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
# Bpftime: A High-Performance User-Space eBPF Runtime | ||
|
||
Yusheng Zheng, Tong Yu | ||
|
||
Today, we are thrilled to introduce Bpftime, a Open-sourced full-featured, high-performance eBPF runtime, designed to operate in user space. It supports eBPF kernel features like uprobe, syscall trace, can be attached to other process, having a shared interprocess map, with LLVM jit, a handcrafted x86 jit. It also can be used with existing eBPF toolchains like libbpf and clang without any changed. | ||
|
||
It can speed up eBPF programs by 10x compared to kernel uprobes, and can be used in embedded systems, IoT, edge computing, smart contracts, and cloud-native solutions. | ||
|
||
The github repo is: <https://github.com/eunomia-bpf/bpftime> | ||
|
||
## Bpftime vs. Alternatives | ||
|
||
### WebAssembly (Wasm) in User Space | ||
|
||
While Wasm has its advantages, it also comes with limitations: | ||
|
||
- High performance costs due to security concerns with external APIs like Wasi, which require additional validation and runtime checks, often necessitating extra memory copies. | ||
- Manual integration needed, with embedding in compile times instead of dynamic uprobe/kprobe. | ||
- Less adaptable to API version changes due to lack of BTF CO-RE support. | ||
- Reliance on underlying libraries for complex operations. | ||
|
||
### eBPF in Kernel Space | ||
|
||
The kernel space eBPF also presents its own set of challenges: | ||
|
||
- Kernel UProbe implementation necessitates two kernel context switches, resulting in significant performance overhead. | ||
- Limited features and unsuitability for plugin or other use cases. | ||
- Running eBPF programs in kernel mode requires root access, increasing the attack surface and posing risks like container escape. | ||
- Inherent vulnerabilities in eBPF can lead to Kernel Exploits. | ||
|
||
### Other User-Space eBPF Runtimes | ||
|
||
There are other user-space eBPF runtimes available, such as Ubpf and Rbpf: | ||
|
||
- Ubpf: Ubpf offers ELF parsing, a simple hash map, and JIT for arm64 and x86. | ||
- Rbpf: Rbpf provides a helper mechanism, x86 JIT, and a VM. | ||
|
||
However, it has several limitations: | ||
|
||
- Complex integration and usage. | ||
- Inability to use kernel eBPF libraries and toolchains like libbpf, bpftrace, or clang. | ||
- Lack of attach support. | ||
- Absence of interprocess maps. | ||
- Limited functionality in user space. | ||
- JIT support only for arm64 or x86. | ||
|
||
Despite these limitations, existing user-space eBPF runtimes have been used in several innovative projects, including: | ||
|
||
- **Qemu+uBPF**: This project combines Qemu, an open-source machine emulator and virtualizer, with uBPF to enhance its capabilities. You can check out a demonstration in this [video](https://www.youtube.com). | ||
- **Oko**: Oko extends Open vSwitch-DPDK with BPF, enhancing tools for better integration. More details are available on its [GitHub](https://github.com/oko) page. | ||
- **Solana**: Solana uses user-space eBPF for high-performance smart contracts. You can explore more on its [GitHub](https://github.com/solana-labs/solana) page. | ||
- **DPDK eBPF**: DPDK eBPF provides libraries for fast packet processing, further enhanced by user-space eBPF. | ||
- **eBPF for Windows**: This project brings eBPF toolchains and runtime to the Windows kernel, expanding the reach of eBPF. | ||
|
||
Additionally, user-space eBPF runtimes have been discussed in academic papers like "Rapidpatch: Firmware Hotpatching for Real-Time Embedded Devices" and "Femto-Containers: Lightweight Virtualization and Fault Isolation For Small Software Functions on Low-Power IoT Microcontrollers". | ||
|
||
These projects demonstrate the versatility and potential of user-space eBPF runtimes in diverse areas such as network plugins, edge runtime, smart contracts, hotpatching, and even Windows support. The future of eBPF is indeed promising! | ||
|
||
## Why Bpftime? | ||
|
||
Bpftime addresses these limitations and offers a host of powerful features: | ||
|
||
- Runs eBPF in user space just like in the kernel, achieving a 10x speedup vs. kernel uprobes. | ||
- Uses shared eBPF maps for data & control. | ||
- Compatible with clang, libbpf, and existing eBPF toolchains; supports CO-RE & BTF. | ||
- Supports `external functions`(ffi) and pointers like kfunc. | ||
- Includes a cross-platform interpreter, fast LLVM JIT compiler, and a handcrafted x86 JIT in C for limited resources. | ||
- Can inject eBPF runtime into any running process without the need for a restart or manual recompilation. | ||
- Runs not only in Linux but also in all Unix systems, Windows, and even IoT devices. | ||
|
||
## benchmark | ||
|
||
How is the performance of `userspace uprobe` compared to `kernel uprobes`? Let's take a look at the following benchmark results: | ||
|
||
TODO: results | ||
|
||
It can be attached to functions in running process just like the kernel uprobe does. | ||
|
||
How is the performance of LLVM JIT/AOT compared to other eBPF userspace runtimes, native code or wasm runtimes? Let's take a look at the following benchmark results: | ||
|
||
You can find detail benchmark results in [https://github.com/eunomia-bpf/bpf-benchmark](https://github.com/eunomia-bpf/bpf-benchmark) | ||
|
||
## AI for eBPF Code Generation | ||
|
||
Bpftime is also exploring the use of AI for eBPF code generation. GPT4, with the help of AI agents, can generate eBPF code with up to 80% accuracy. More information about this can be found on: | ||
|
||
- [NL2eBPF online website](https://gpt-2-bpftrace.vercel.app/) | ||
- [GPTtrace](https://github.com/eunomia-bpf/GPTtrace). | ||
|
||
## The Future of Bpftime | ||
|
||
The Bpftime project is continuously evolving, with more features in the pipeline: | ||
|
||
- An AOT compiler for eBPF can be easily added based on the LLVM IR. | ||
- More map types and distribution maps support. | ||
- User-space eBPF to speed up fuse. | ||
- eBPF for GPU sharing programs. | ||
- RDMA with distribution eBPF runtimes. | ||
- User-space eBPF syscall bypass. | ||
|
||
Bpftime is an open-source project and can be found on [GitHub](https://github.com/eunomia-bpf/bpftime). | ||
|
||
In conclusion, Bpftime is set to revolutionize the tech sphere with its high performance, compatibility with existing eBPF toolchains, and potential for AI-enhanced code generation. Stay tuned for more developments from this promising project! |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# Building and run bpftime | ||
|
||
## Install Dependencies | ||
|
||
Install the required packages: | ||
|
||
```bash | ||
sudo apt install -y --no-install-recommends \ | ||
libelf1 libelf-dev zlib1g-dev make git libboost1.74-all-dev \ | ||
binutils-dev libyaml-cpp-dev llvm | ||
git submodule update --init --recursive | ||
``` | ||
|
||
We've tested on Ubuntu 23.04. The recommended `gcc` >= 12.0.0 `clang` >= 16.0.0 | ||
|
||
On Ubuntu 20.04, you may need to manually switch to gcc-12. | ||
|
||
### Build and install cli tool | ||
|
||
```bash | ||
sudo apt-get install libelf-dev zlib1g-dev # Install dependencies | ||
make release && make install # Build and install the runtime | ||
export PATH=$PATH:~/.bpftime | ||
``` | ||
|
||
Then you can run cli: | ||
|
||
```console | ||
$ bpftime | ||
Usage: bpftime [OPTIONS] <COMMAND> | ||
... | ||
``` | ||
|
||
## Compilation for vm | ||
|
||
Build the complete runtime: | ||
|
||
```bash | ||
make build | ||
``` | ||
|
||
On old systems, you may need to buil with old binutils version(TODO: fix it): | ||
|
||
```bash | ||
make build-old-binutils | ||
``` | ||
|
||
For a lightweight build without the runtime (only vm library and LLVM JIT): | ||
|
||
```bash | ||
make build-vm # build the simple vm with a simple jit | ||
make build-llvm # build the vm with llvm jit | ||
``` | ||
|
||
## Testing | ||
|
||
Run the test suite for runtime to validate the implementation: | ||
|
||
```bash | ||
make unit-test | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# the design and implementation of bpftime | ||
|
||
The hook implementation is based on binary rewriting and the underly technique is inspired by: | ||
|
||
- Userspace function hook: [frida-gum](https://github.com/frida/frida-gum) | ||
- Syscall hooks: [zpoline: a system call hook mechanism based on binary rewriting](https://www.usenix.org/conference/atc23/presentation/yasukata) | ||
|
||
![How it works](bpftime.png) | ||
|
||
TODO |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
# Usgae | ||
|
||
It's at a very early stage and may contain bugs on more platforms and eBPF programs. | ||
|
||
## Run with JIT enabled | ||
|
||
Set `BPFTIME_USE_JIT=true` in the server to enable JIT, for example, when running the server: | ||
|
||
```sh | ||
LD_PRELOAD=~/.bpftime/libbpftime-syscall-server.so BPFTIME_USE_JIT=true example/malloc/malloc | ||
``` | ||
|
||
## Uprobe and uretprobe | ||
|
||
With `bpftime`, you can build eBPF applications using familiar tools like clang and libbpf, and execute them in userspace. For instance, the `malloc` eBPF program traces malloc calls using uprobe and aggregates the counts using a hash map. | ||
|
||
You can refer to [documents/build-and-test.md](build-and-test.md) for how to build the project. | ||
|
||
To get started, you can build and run a libbpf based eBPF program starts with `bpftime` cli: | ||
|
||
```console | ||
make -C example/malloc # Build the eBPF program example | ||
bpftime load ./example/malloc/malloc | ||
``` | ||
|
||
In another shell, Run the target program with eBPF inside: | ||
|
||
```console | ||
$ bpftime start ./example/malloc/test | ||
Hello malloc! | ||
malloc called from pid 250215 | ||
continue malloc... | ||
malloc called from pid 250215 | ||
``` | ||
|
||
You can also dynamically attach the eBPF program with a running process: | ||
|
||
```console | ||
$ ./example/malloc/test & echo $! # The pid is 101771 | ||
[1] 101771 | ||
101771 | ||
continue malloc... | ||
continue malloc... | ||
``` | ||
|
||
And attach to it: | ||
|
||
```console | ||
$ sudo bpftime attach 101771 # You may need to run make install in root | ||
Inject: "/root/.bpftime/libbpftime-agent.so" | ||
Successfully injected. ID: 1 | ||
``` | ||
|
||
You can see the output from original program: | ||
|
||
```console | ||
$ bpftime load ./example/malloc/malloc | ||
... | ||
12:44:35 | ||
pid=247299 malloc calls: 10 | ||
pid=247322 malloc calls: 10 | ||
``` | ||
|
||
Alternatively, you can also run our sample eBPF program directly in the kernel eBPF, to see the similar output: | ||
|
||
```console | ||
$ sudo example/malloc/malloc | ||
15:38:05 | ||
pid=30415 malloc calls: 1079 | ||
pid=30393 malloc calls: 203 | ||
pid=29882 malloc calls: 1076 | ||
pid=34809 malloc calls: 8 | ||
``` | ||
|
||
## Syscall tracing | ||
|
||
An example can be found at [benchmark/hash_maps](../benchmark/hash_maps/). | ||
|
||
Build the example: | ||
|
||
```sh | ||
make -C benchmark/hash_maps | ||
``` | ||
|
||
Start server: | ||
|
||
```sh | ||
$ sudo ~/.bpftime/bpftime load benchmark/hash_maps/opensnoop | ||
[2023-10-01 16:46:43.409] [info] manager constructed | ||
[2023-10-01 16:46:43.409] [info] global_shm_open_type 0 for bpftime_maps_shm | ||
[2023-10-01 16:46:43.410] [info] Closing 3 | ||
[2023-10-01 16:46:43.411] [info] mmap64 0 | ||
[2023-10-01 16:46:43.411] [info] Calling mocked mmap64 | ||
[2023-10-01 16:46:43.411] [info] Closing 3 | ||
[2023-10-01 16:46:43.411] [info] Closing 3 | ||
[2023-10-01 16:46:43.423] [info] Closing 3 | ||
[2023-10-01 16:46:43.423] [info] Closing 3 | ||
``` | ||
|
||
Start victim: | ||
|
||
```console | ||
$ sudo ~/.bpftime/bpftime start -s benchmark/hash_maps/victim | ||
[2023-10-01 16:46:58.855] [info] Entering new main.. | ||
[2023-10-01 16:46:58.855] [info] Using agent /root/.bpftime/libbpftime-agent.so | ||
[2023-10-01 16:46:58.856] [info] Page zero setted up.. | ||
[2023-10-01 16:46:58.856] [info] Rewriting segment from 559a839b4000 to 559a839b5000 | ||
[2023-10-01 16:46:58.859] [info] Rewriting segment from 7f130aa22000 to 7f130ab9a000 | ||
[2023-10-01 16:46:59.749] [info] Rewriting segment from 7f130acc3000 to 7f130adb0000 | ||
[2023-10-01 16:47:00.342] [info] Rewriting segment from 7f130ae9c000 to 7f130afcd000 | ||
[2023-10-01 16:47:01.072] [info] Rewriting segment from 7f130b125000 to 7f130b1a3000 | ||
..... | ||
[2023-10-01 16:47:02.084] [info] Attach successfully | ||
[2023-10-01 16:47:02.084] [info] Transformer exiting.. | ||
|
||
Opening test.txt.. | ||
VICTIM: get fd 3 | ||
VICTIM: closing fd | ||
Opening test.txt.. | ||
VICTIM: get fd 3 | ||
VICTIM: closing f | ||
``` |
Binary file not shown.
Oops, something went wrong.