Last active
March 10, 2024 12:40
-
-
Save zigelboim-misha/c497b674c08dd15e231a84658472c4f2 to your computer and use it in GitHub Desktop.
eBPF Kernel Side - Print all System Write Events
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
FROM ubuntu:22.04 | |
RUN apt update && apt upgrade && apt install -y wget clang llvm curl | |
RUN wget https://aka.pw/bpf-ecli -O ecli && chmod +x ./ecli | |
RUN wget https://github.com/eunomia-bpf/eunomia-bpf/releases/latest/download/ecc && chmod +x ./ecc | |
ENTRYPOINT [ "tail", "-f", "/dev/null" ] |
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
// This code is taken from eunomia eBPF tutorial | |
// https://eunomia.dev/tutorials/1-helloworld/#hello-world-minimal-ebpf-program | |
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ | |
#define BPF_NO_GLOBAL_DATA | |
#include <linux/bpf.h> | |
#include <bpf/bpf_helpers.h> | |
#include <bpf/bpf_tracing.h> | |
typedef unsigned int u32; | |
typedef int pid_t; | |
const pid_t pid_filter = 0; | |
char LICENSE[] SEC("license") = "Dual BSD/GPL"; | |
SEC("tp/syscalls/sys_enter_write") | |
int handle_tp(void *ctx) | |
{ | |
pid_t pid = bpf_get_current_pid_tgid() >> 32; | |
if (pid_filter && pid != pid_filter) | |
return 0; | |
bpf_printk("BPF triggered sys_enter_write from PID %d.\n", pid); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This gist is for creating a basic
eBPF
function that will be injected into the kernel.Everything Explained
eBPF file
Header Files
#define BPF_NO_GLOBAL_DATA
- This macro is defined to indicate that the BPF program does not use any global data.#include <linux/bpf.h>
- This includes the main BPF header file.#include <bpf/bpf_helpers.h>
- This includes BPF helper functions.#include <bpf/bpf_tracing.h>
- This includes BPF tracing related functions.Type Definitions
typedef unsigned int u32;
- This defines an unsigned 32-bit integer type u32.typedef int pid_t;
- This defines thepid_t
type, which represents a process ID.Variables
const pid_t pid_filter = 0;
- This defines a constantpid_filter
with a default value of 0. This variable will be used to filter which process IDs to trace. If set to 0, it will trace all process IDs.char LICENSE[] SEC("license") = "Dual BSD/GPL";
- This specifies the license of the BPF program. In this case, it's dual licensed under the BSD and GPL licenses.BPF Program Section
SEC("tp/syscalls/sys_enter_write")
- This is a section specifier indicating that this BPF program should be attached to thesyscalls/sys_enter_write tracepoint
. It means the program will run when thesys_enter_write
tracepoint is hit.BPF Program:
int handle_tp(void *ctx)
- This is the main function of the BPF program. It takes a context pointer as an argument.pid_t pid = bpf_get_current_pid_tgid() >> 32;
- This line extracts the process ID from the context. Thebpf_get_current_pid_tgid()
function returns a 64-bit value where the high 32 bits represent the process ID. Shifting by 32 bits gets the process ID alone.if (pid_filter && pid != pid_filter) return 0;
- This checks ifpid_filter
is set and if the current process ID does not match the filtered PID. If it doesn't match, the program returns early, effectively skipping the tracing for this process.bpf_printk("BPF triggered sys_enter_write from PID %d.\n", pid);
- This line prints a message to the kernel log usingbpf_printk()
. It will log a message every time the writesyscall
is called, showing the process ID that triggered it. This will be written to/sys/kernel/debug/tracing/trace_pipe
.return 0;
- The function ends by returning 0.Output Example
Dockerfile
The
Dockerfile
contains everything that is needed to compile the.c
code:docker build -t ebpf .
Dockerfile
usingdocker run --privileged -v C:\Path\To\Files:/ebpf ebpf:latest
Compile the code
To compile the code, run the
./ecc minimal.bpf.c
command from inside the container.Run the code on the kernel
To run the code itself, you can inject the code using 3rd party tools or run it using
./ecli run package.json
.Enabling Tracing
If your Linux distribution (e.g. Ubuntu) does not have the tracing subsystem enabled by default, you may not see any output. Use the following command to enable this feature:
sudo mount -t debugfs none /sys/kernel/debug
sudo echo 1 > /sys/kernel/debug/tracing/tracing_on