Skip to content

Commit

Permalink
runtime: add mpk support
Browse files Browse the repository at this point in the history
  • Loading branch information
yunwei37 committed Nov 17, 2023
1 parent 5f2426f commit 4e664a6
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 11 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ documents/dlsym/dlsym
documents/elfoffset/myprogram
documents/elfoffset/*.txt
documents/elfoffset/maps
Catch2
libebpf.off.txt
test/pyvenv.cfg
ecli
Expand Down
6 changes: 3 additions & 3 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
"name": "(gdb) runtime",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/example/malloc/test",
"program": "${workspaceFolder}/example/malloc/victim",
"args": [],
"stopAtEntry": true,
"cwd": "${workspaceFolder}/build/runtime/test/",
"cwd": "${workspaceFolder}/",
"environment": [
{
"name": "LD_PRELOAD",
"value": "/home/yunwei/bpftime/build/runtime/agent/libbpftime-agent.so"
"value": "${workspaceFolder}/build/runtime/agent/libbpftime-agent.so"
},
// {
// "name": "LD_PRELOAD",
Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

`bpftime`, a full-featured, high-performance eBPF runtime designed to operate in userspace. It offers fast Uprobe and Syscall hook capabilities: Userspace uprobe can be **10x faster than kernel uprobe!** and can programmatically **hook all syscalls of a process** safely and efficiently.

📦 [Features](#key-features) \
📦 [Key Features](#key-features) \
🔨 [Quick Start](#quick-start) \
⌨️ [Linux Plumbers 23 talk](https://lpc.events/event/17/contributions/1639/) \
📖 [Slides](https://github.com/eunomia-bpf/bpftime/tree/master/documents/userspace-ebpf-bpftime-lpc.pdf) \
Expand Down Expand Up @@ -144,12 +144,12 @@ see [arxiv preprint: https://arxiv.org/abs/2311.07923](https://arxiv.org/abs/231

How is the performance of `userspace uprobe` compared to `kernel uprobes`?

| Probe/Tracepoint Types | Kernel (ns) | Userspace (ns) | Insn Count |
|------------------------|-------------:|---------------:|---------------:|
| Uprobe | 3224.172760 | 314.569110 | 4 |
| Uretprobe | 3996.799580 | 381.270270 | 2 |
| Syscall Tracepoint | 151.82801 | 232.57691 | 4 |
| Embedding runtime | Not avaliable | 110.008430 | 4 |
| Probe/Tracepoint Types | Kernel (ns) | Userspace (ns) |
|------------------------|-------------:|---------------:|
| Uprobe | 3224.172760 | 314.569110 |
| Uretprobe | 3996.799580 | 381.270270 |
| Syscall Tracepoint | 151.82801 | 232.57691 |
| Embedding runtime | Not avaliable | 110.008430 |

It can be attached to functions in running process just like the kernel uprobe does.

Expand Down
5 changes: 5 additions & 0 deletions runtime/include/bpftime_shm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ void bpftime_destroy_global_shm();
// remove the global shared memory from system
void bpftime_remove_global_shm();

// enable memory protect, e.g. mpk
void bpftime_protect_enable();
// disable memory protect
void bpftime_protect_disable();

// import the global shared memory from json file
int bpftime_import_global_shm_from_json(const char *filename);
// export the global shared memory to json file
Expand Down
2 changes: 2 additions & 0 deletions runtime/src/attach/bpf_attach_ctx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ bool bpf_attach_ctx::check_syscall_trace_setup(int pid)
{
return shm_holder.global_shared_memory.check_syscall_trace_setup(pid);
}

// Set whether a certain pid was already equipped with syscall tracer
// Using a set stored in the shared memory
void bpf_attach_ctx::set_syscall_trace_setup(int pid, bool whether)
Expand Down Expand Up @@ -519,4 +520,5 @@ bpf_attach_ctx::bpf_attach_ctx(void)
spdlog::debug("Initialzing frida gum");
current_id = CURRENT_ID_OFFSET;
}

} // namespace bpftime
4 changes: 4 additions & 0 deletions runtime/src/bpf_map/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# bpf maps source

- shared: maps between kernel and userspace
- userspace: maps runs only in userspace
4 changes: 4 additions & 0 deletions runtime/src/bpftime_prog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ int bpftime_prog::bpftime_prog_exec(void *memory, size_t memory_size,
{
uint64_t val = 0;
int res = 0;
// set share memory read and write able
bpftime_protect_disable();
spdlog::debug(
"Calling bpftime_prog::bpftime_prog_exec, memory={:x}, memory_size={}, return_val={:x}, prog_name={}",
(uintptr_t)memory, memory_size, (uintptr_t)return_val,
Expand All @@ -88,6 +90,8 @@ int bpftime_prog::bpftime_prog_exec(void *memory, size_t memory_size,
}
}
*return_val = val;
// set share memory read only
bpftime_protect_enable();
return res;
}

Expand Down
13 changes: 13 additions & 0 deletions runtime/src/bpftime_shm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ long bpftime_map_delete_elem(int fd, const void *key)
{
return shm_holder.global_shared_memory.bpf_delete_elem(fd, key, true);
}

int bpftime_map_get_next_key(int fd, const void *key, void *next_key)
{
return shm_holder.global_shared_memory.bpf_map_get_next_key(
Expand Down Expand Up @@ -156,6 +157,18 @@ int bpftime_is_ringbuf_map(int fd)
return shm_holder.global_shared_memory.is_ringbuf_map_fd(fd);
}

void bpftime_protect_enable() {
#if BPFTIME_ENABLE_MPK
return shm_holder.global_shared_memory.enable_mpk();
#endif
}

void bpftime_protect_disable() {
#if BPFTIME_ENABLE_MPK
return shm_holder.global_shared_memory.disable_mpk();
#endif
}

int bpftime_is_map_fd(int fd)
{
return shm_holder.global_shared_memory.is_map_fd(fd);
Expand Down
40 changes: 40 additions & 0 deletions runtime/src/bpftime_shm_internal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <sys/epoll.h>
#include <unistd.h>
#include <variant>
#include <sys/mman.h>

static bool global_shm_initialized = false;

Expand Down Expand Up @@ -432,6 +433,28 @@ void bpftime_shm::close_fd(int fd)
}
}

#if BPFTIME_ENABLE_MPK
void bpftime_shm::enable_mpk()
{
if (manager == nullptr|| !is_mpk_init) {
return;
}
if (pkey_set(pkey, PKEY_DISABLE_WRITE) == -1) {
spdlog::error("pkey_set read only failed");
}
}

void bpftime_shm::disable_mpk()
{
if (manager == nullptr || !is_mpk_init) {
return;
}
if (pkey_set(pkey, 0) == -1) {
spdlog::error("pkey_set disable failed");
}
}
#endif

bool bpftime_shm::is_exist_fake_fd(int fd) const
{
if (manager == nullptr || fd < 0 ||
Expand Down Expand Up @@ -518,6 +541,23 @@ bpftime_shm::bpftime_shm(const char *shm_name, shm_open_type type)
"NOT creating global shm. This is only for testing purpose.");
return;
}

#if BPFTIME_ENABLE_MPK
// init mpk key
pkey = pkey_alloc(0, PKEY_DISABLE_WRITE);
if (pkey == -1) {
spdlog::error("pkey_alloc failed");
return;
}

// protect shm segment
if (pkey_mprotect(segment.get_address(), segment.get_size(),
PROT_READ | PROT_WRITE, pkey) == -1) {
spdlog::error("pkey_mprotect failed");
return;
}
is_mpk_init = true;
#endif
}

bpftime_shm::bpftime_shm(bpftime::shm_open_type type)
Expand Down
11 changes: 11 additions & 0 deletions runtime/src/bpftime_shm_internal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ class bpftime_shm {
// Configuration for the agent. e.g, which helpers are enabled
struct bpftime::agent_config *agent_config = nullptr;

#if BPFTIME_ENABLE_MPK
// mpk key for protect shm
bool is_mpk_init = false;
int pkey = 0;
#endif

public:
// Get the configuration object
const struct agent_config &get_agent_config()
Expand Down Expand Up @@ -126,6 +132,11 @@ class bpftime_shm {
void close_fd(int fd);
bool is_exist_fake_fd(int fd) const;

#if BPFTIME_ENABLE_MPK
void enable_mpk();
void disable_mpk();
#endif

// initialize the shared memory globally
bpftime_shm(bpftime::shm_open_type type);
// initialize the shared memory with a given name
Expand Down

0 comments on commit 4e664a6

Please sign in to comment.