Skip to content

Commit

Permalink
stash
Browse files Browse the repository at this point in the history
  • Loading branch information
mozillazg committed Mar 12, 2023
1 parent 2f2472f commit 88c7503
Show file tree
Hide file tree
Showing 115 changed files with 5,056 additions and 19 deletions.
6 changes: 3 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "chapter8/libbpf"]
path = chapter8/libbpf
url = https://github.com/libbpf/libbpf.git
[submodule "libbpf"]
path = libbpf
url = https://github.com/libbpf/libbpf.git
34 changes: 34 additions & 0 deletions chapter10/Vagrantfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/jammy64"
config.vm.box_version = "20220902.0.0"
config.vm.disk :disk, size: "20GB"
config.vm.synced_folder "../", "/home/vagrant/go/src/github.com/mozillazg/cloud-native-security-with-ebpf", create: true
config.ssh.extra_args = ["-t", "cd /home/vagrant/go/src/github.com/mozillazg/cloud-native-security-with-ebpf/chapter9; bash --login"]
config.vm.provider "virtualbox" do |v|
v.memory = 2048
v.cpus = 2
end

# install dependencies
config.vm.provision "shell", inline: <<-SHELL
cd /home/vagrant/go/src/github.com/mozillazg/cloud-native-security-with-ebpf/chapter9
sed -i "s@http://.*archive.ubuntu.com@https://mirrors.tuna.tsinghua.edu.cn@g" /etc/apt/sources.list
sed -i "s@http://.*security.ubuntu.com@https://mirrors.tuna.tsinghua.edu.cn@g" /etc/apt/sources.list
apt-get update
apt-get update
apt-get install --yes build-essential pkgconf libelf-dev llvm-12 clang-12 linux-tools-$(uname -r)
for tool in "clang" "llc" "llvm-strip"
do
path=$(which $tool-12)
ln -s -f $path ${path%-*}
done
snap install go --channel=1.18/stable --classic
chown vagrant -R /home/vagrant/go/
grep GOPROXY /home/vagrant/.bashrc || \
echo 'export GOPROXY=https://goproxy.cn,direct' >> /home/vagrant/.bashrc
SHELL
end
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
SHELL = /bin/sh

OUTPUT = ../output
LIBBPF = ../libbpf
LIBBPF = ../../libbpf


LIBBPF_SRC = $(abspath $(LIBBPF)/src)
Expand Down
5 changes: 5 additions & 0 deletions chapter10/bpf_override_return/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/mozillazg/cloud-native-security-with-ebpf/chapter9/bpf_override_return

go 1.18

require github.com/aquasecurity/libbpfgo v0.4.5-libbpf-1.0.1 // indirect
2 changes: 2 additions & 0 deletions chapter10/bpf_override_return/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/aquasecurity/libbpfgo v0.4.5-libbpf-1.0.1 h1:Et7WT8CEpaO03v7FIVk85GMRRbwjF7sgoBgQhH5T30k=
github.com/aquasecurity/libbpfgo v0.4.5-libbpf-1.0.1/go.mod h1:v+Nk+v6BtHLfdT4kVdsp+fYt4AeUa3cIG2P0y+nBuuY=
116 changes: 116 additions & 0 deletions chapter10/bpf_override_return/main.bpf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
#include "main.h"

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 10240);
__type(key, pid_t);
__type(value, struct event_t);
} entries SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1024);
__type(key, pid_t);
__type(value, u64);
} override_tasks SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
__uint(key_size, sizeof(u32));
__uint(value_size, sizeof(u32));
} events SEC(".maps");

static inline bool str_eq(const char *a, const char *b, int len)
{
for (int i = 0; i < len; i++) {
if (a[i] != b[i])
return false;
if (a[i] == '\0')
break;
}
return true;
}

static __always_inline int str_len(char *s, int max_len)
{
for (int i = 0; i < max_len; i++) {
if (s[i] == '\0')
return i;
}
if (s[max_len - 1] != '\0')
return max_len;
return 0;
}

SEC("tracepoint/syscalls/sys_enter_openat")
int tracepoint_syscalls__sys_enter_openat(struct trace_event_raw_sys_enter *ctx) {
pid_t tid;
struct event_t event = {};
char *filename;
u64 err = -1;
char target_comm[TASK_COMM_LEN] = "cat";

tid = (pid_t)bpf_get_current_pid_tgid();
event.pid = bpf_get_current_pid_tgid() >> 32;
bpf_get_current_comm(&event.comm, sizeof(event.comm));
// 获取文件打开模式
event.fmode = (int)BPF_CORE_READ(ctx, args[3]);
// 从 ctx->args[1] 中获取被打开的文件名称
filename = (char *)BPF_CORE_READ(ctx, args[1]);
bpf_probe_read_user_str(event.filename, sizeof(event.filename), filename);

// 保存获取到的 event 信息
bpf_map_update_elem(&entries, &tid, &event, BPF_NOEXIST);

// 决策是否需要替换返回值 ...
if (!str_eq(event.comm, target_comm, str_len(target_comm, TASK_COMM_LEN)))
return 0;
// 然后保存要替换的返回值
bpf_map_update_elem(&override_tasks, &tid, &err, BPF_NOEXIST);

return 0;
}

SEC("tracepoint/syscalls/sys_exit_openat")
int tracepoint_syscalls__sys_exit_openat(struct trace_event_raw_sys_exit *ctx) {
pid_t tid;
struct event_t *event;

tid = (pid_t)bpf_get_current_pid_tgid();
event = bpf_map_lookup_elem(&entries, &tid);
if (!event)
return 0;

// 保存执行结果
event->ret = (int)BPF_CORE_READ(ctx, ret);
// 将事件提交到 events 中供用户态程序消费
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, event, sizeof(*event));

// 删除保存的 event 信息
bpf_map_delete_elem(&entries, &tid);
return 0;
}

SEC("kprobe/__x64_sys_openat")
int BPF_KPROBE(kprobe_sys_openat_with_override)
{
pid_t tid;
u64 *err;

// 查找是否需要替换返回值
tid = (pid_t)bpf_get_current_pid_tgid();
err = bpf_map_lookup_elem(&override_tasks, &tid);
if (!err)
return 0;

// 替换返回值
bpf_override_return(ctx, *err);
bpf_map_delete_elem(&override_tasks, &tid);
return 0;
}

char _license[] SEC("license") = "GPL";
90 changes: 90 additions & 0 deletions chapter10/bpf_override_return/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package main

import (
"bytes"
"context"
"encoding/binary"
"log"
"os"
"os/signal"
"syscall"

bpf "github.com/aquasecurity/libbpfgo"
)

type Event struct {
Pid uint32
Fmode int32
Ret int32
Comm [16]byte
Filename [16]byte
}

func parseEvent(data []byte) (*Event, error) {
var event Event
err := binary.Read(bytes.NewBuffer(data), binary.LittleEndian, &event)
if err != nil {
return nil, err
}
return &event, nil
}

func goString(data []byte) string {
return string(bytes.Split(data, []byte("\x00"))[0])
}

func main() {
bpfModule, err := bpf.NewModuleFromFile("main.bpf.o")
if err != nil {
log.Fatalln(err)
}
defer bpfModule.Close()
if err := bpfModule.BPFLoadObject(); err != nil {
log.Fatalln(err)
}
progIter := bpfModule.Iterator()
for {
prog := progIter.NextProgram()
if prog == nil {
break
}
_, err := prog.AttachGeneric()
if err != nil {
log.Fatalln(err)
}
}
log.Println("tracing...")
eventsChannel := make(chan []byte)
lostChannel := make(chan uint64)
pb, err := bpfModule.InitPerfBuf("events", eventsChannel, lostChannel, 1024)
if err != nil {
log.Fatalln(err)
}
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)

pb.Start()
defer func() {
pb.Stop()
pb.Close()
stop()
}()

loop:
for {
select {
case data := <-eventsChannel:
event, err := parseEvent(data)
if err != nil {
log.Println(err)
} else {
log.Printf("pid: %d comm: %s filename: %s mode: %d ret: %d", event.Pid,
goString(event.Comm[:]), goString(event.Filename[:]), event.Fmode, event.Ret)
}
case n := <-lostChannel:
log.Printf("lost %d events", n)
case <-ctx.Done():
break loop
}
}
log.Println("bye bye~")
}
9 changes: 9 additions & 0 deletions chapter10/bpf_override_return/main.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#define TASK_COMM_LEN 16

struct event_t {
pid_t pid;
int fmode;
int ret;
char comm[TASK_COMM_LEN];
char filename[16];
};
Loading

0 comments on commit 88c7503

Please sign in to comment.