iovisor / gobpf

Go bindings for creating BPF programs.
Apache License 2.0
2.14k stars 313 forks source link

go run -race err: checkptr: pointer arithmetic computed bad pointer value #323

Open xiaonuoz opened 1 year ago

xiaonuoz commented 1 year ago

hi! Can you help me to see where my example is going wrong, it's easy.

package main

import (
    "bytes"
    "encoding/binary"
    "fmt"
    "strings"

    bpf "github.com/iovisor/gobpf/bcc"
)

const (
    file_read_c = `
    #include <asm/ptrace.h>
    #include <linux/fs.h>
    #include <linux/sched.h>

    struct readfile_event_t {
        u32 pid;
        char file_name[256];
    };

    BPF_PERF_OUTPUT(watch_readfile_events);

    int trace_vfs_read(struct pt_regs *ctx, struct file *file, char __user *buf, size_t count, loff_t *pos)
    {
        u32 pid = bpf_get_current_pid_tgid() >>32;

        struct readfile_event_t event = {};
        event.pid = pid;

        bpf_probe_read_kernel_str(&event.file_name, sizeof(event.file_name), (void *)file->f_path.dentry->d_name.name);
        watch_readfile_events.perf_submit(ctx, &event, sizeof(event));
        return 0;
    }
    `
)

func main() {
    BpfModule := bpf.NewModule(file_read_c, []string{})

    traceVfsRead, err := BpfModule.LoadKprobe("trace_vfs_read")
    if err != nil {
        fmt.Println("traceVfsWrite err:", err)
        return
    }

    err = BpfModule.AttachKprobe("vfs_read", traceVfsRead, -1)
    if err != nil {
        fmt.Println("AttachKprobe err:", err)
        return
    }
    table := bpf.NewTable(BpfModule.TableId("watch_readfile_events"), BpfModule)

    channel := make(chan []byte, 2048)

    perfMap, err := bpf.InitPerfMap(table, channel, nil)
    if err != nil {
        fmt.Println("InitPerfMap err:", err)
        return
    }

    perfMap.Start()
    defer perfMap.Stop()

    for data := range channel {
        getWriteEvent(data)
    }
}

type WatchFileEventsC struct {
    Pid      uint32
    FileName [256]byte
}

func getWriteEvent(data []byte) {
    var watchEvent WatchFileEventsC
    err := binary.Read(bytes.NewBuffer(data), binary.LittleEndian, &watchEvent)
    if err != nil {
        return
    }

    file_name := string(watchEvent.FileName[:bytes.IndexByte(watchEvent.FileName[:], 0)])
    if len(file_name) == 0 {
        return
    }

    if !strings.Contains(file_name, ".txt") {
        return
    }
    fmt.Printf("file_name:%v\n", file_name)
}

error: image