0

So I have this function in my driver for network NIC and this function appears in proc/kallsyms[https://stackoverflow.com/a/67766463/4808760] file with base address this is the function

static int rtl8169_poll(struct napi_struct *napi, int budget)
{
    struct rtl8169_private *tp = container_of(napi, struct rtl8169_private, napi);
    struct net_device *dev = tp->dev;
    int work_done;

    rtl_tx(dev, tp, budget);

    work_done = rtl_rx(dev, tp, budget);

    if (work_done < budget && napi_complete_done(napi, work_done))
        rtl_irq_enable(tp);

    return work_done;
}

appears as

 ffffffffc02d2210 t rtl8169_poll    [r8169]

and this is my ebpf program

SEC("kprobe/rtl8169_poll")
int bpf_prog2(struct pt_regs *ctx)
{
    int sc_nr = (int)PT_REGS_PARM1(ctx);
    char *fmt="HELLO from FWDALI %d %d";
    bpf_trace_printk(fmt,1,sc_nr);
    bpf_trace_printk(fmt ,2,sc_nr);
    /* dispatch into next BPF program depending on syscall number */
    //bpf_tail_call(ctx, &progs, sc_nr);

    /* fall through -> unknown syscall */
    //if (sc_nr >= __NR_getuid && sc_nr <= __NR_getsid) {
    //  char fmt[] = "-----FWD-------------------------syscall=%d (one of get/set uid/pid/gid)\n";
    //  bpf_trace_printk(fmt, sizeof(fmt), sc_nr);
    //}
    return 0;
}

And this is my simple userspace code

// SPDX-License-Identifier: GPL-2.0
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/filter.h>
#include <linux/seccomp.h>
#include <sys/prctl.h>
#include <bpf/bpf.h>
#include <bpf/libbpf.h>
#include <sys/resource.h>
#include <fcntl.h>


#ifdef __mips__
#define MAX_ENTRIES  6000 /* MIPS n64 syscalls start at 5000 */
#else
#define MAX_ENTRIES  1024
#endif

/* install fake seccomp program to enable seccomp code path inside the kernel,
 * so that our kprobe attached to seccomp_phase1() can be triggered
 */
 
 
 
void read_trace_pipe(void)
{
    int trace_fd;
    //printf("-%s-\n",DEBUGFS);
    trace_fd = open( "/sys/kernel/debug/tracing/trace_pipe", O_RDONLY, 0);
    if (trace_fd < 0)
        return;

    while (1) {
        static char buf[4096];
        ssize_t sz;

        sz = read(trace_fd, buf, sizeof(buf) - 1);
        if (sz > 0) {
            buf[sz] = 0;
            puts(buf);
        }
    }
}
static void install_accept_all_seccomp(void)
{
    struct sock_filter filter[] = {
        BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
    };
    struct sock_fprog prog = {
        .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
        .filter = filter,
    };
    if (prctl(PR_SET_SECCOMP, 2, &prog))
        perror("prctl");
}

int main(int ac, char **argv)
{
    struct bpf_link *link = NULL;
    struct bpf_program *prog;
    struct bpf_object *obj;
    int key, fd, progs_fd;
    const char *section;
    char filename[256];
    FILE *f;

    snprintf(filename, sizeof(filename), "%s_kern.o", argv[1]);
    obj = bpf_object__open_file(filename, NULL);
    if (libbpf_get_error(obj)) {
        fprintf(stderr, "ERROR: opening BPF object file failed\n");
        return 0;
    }

    prog = bpf_object__find_program_by_name(obj, "bpf_prog2");
    if (!prog) {
        printf("finding a prog in obj file failed\n");
        goto cleanup;
    }

    /* load BPF program */
    if (bpf_object__load(obj)) {
        fprintf(stderr, "ERROR: loading BPF object file failed\n");
        goto cleanup;
    }

    link = bpf_program__attach(prog);
    if (libbpf_get_error(link)) {
        fprintf(stderr, "ERROR: bpf_program__attach failed\n");
        link = NULL;
        goto cleanup;
    }

    progs_fd = bpf_object__find_map_fd_by_name(obj, "progs");
    if (progs_fd < 0) {
        fprintf(stderr, "ERROR: finding a map in obj file failed\n");
        goto cleanup;
    }

    bpf_object__for_each_program(prog, obj) {
        section = bpf_program__section_name(prog);
        /* register only syscalls to PROG_ARRAY */
        if (sscanf(section, "kprobe/%d", &key) != 1)
            continue;

        fd = bpf_program__fd(prog);
        bpf_map_update_elem(progs_fd, &key, &fd, BPF_ANY);
    }

    install_accept_all_seccomp();

    f = popen("dd if=/dev/zero of=/dev/null count=5", "r");
    (void) f;

    read_trace_pipe();

cleanup:
    bpf_link__destroy(link);
    bpf_object__close(obj);
    return 0;
}

SO i like if some take a look at above and explain what exactly I need to add to my ebpf program for kprobe and also what I need to do in my userspace loader program..

I am still having tough time with getting to loads of stuff that tells its simple to implement to use this magical line SEC("kprobe/rtl8169_poll") or something with just loading the program from userspace and its done, But I havent started thinking much of ebpf since ebpf is kind of failed in this simple function hook

this link gave me the idea that I can hook to this function https://stackoverflow.com/a/67766463/4808760

user786
  • 3,902
  • 4
  • 40
  • 72
  • 1
    You could maybe start by checking that your program is correctly running and attached (`bpftool prog list`, `bpftool perf list`), maybe with stats enabled (`sysctl -w kernel.bpf_stats_enabled=1` then look for stats in `bpftool prog`'s output). This should let you know how many times your program has been called (to check that you _do_ call `rtl8169_poll()` after the programs has been attached for example). Also how do you check the prints happen? `cat /sys/kernel/debug/tracing/trace` or `bpftool prog tracelog` should both work. – Qeole Jan 27 '22 at 10:27
  • @Qeole `bpftool prog list` displays my program so it does exists `195: kprobe name bpf_prog2 tag 2493cc384be28239 gpl loaded_at 2022-01-27T14:58:04+0500 uid 0 xlated 104B jited 67B memlock 4096B map_ids 24 btf_id 156` – user786 Jan 27 '22 at 10:50
  • @Qeole `then look for stats in bpftool prog's output)` is there any command for this to look at my prog2 stats – user786 Jan 27 '22 at 10:56
  • `bpftool prog list` will show you the stats as part of the program info if you have enabled them through the `kernel.bpf_stats_enabled` knob ([example](https://qmonnet.github.io/whirl-offload/2021/09/23/bpftool-features-thread/#programs-statistics)). `bpftool prog list` shows your program was successfully loaded, it should be attached as well if you want it to run (should display in `bpftool perf list`). But if you get no error from `bpf_program__attach()`, then it should be attached correctly. – Qeole Jan 27 '22 at 11:03

0 Answers0