首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >给bpf_object__open_file和libbpf_get_error打电话后不久,errno =2什么也不说

给bpf_object__open_file和libbpf_get_error打电话后不久,errno =2什么也不说
EN

Stack Overflow用户
提问于 2022-01-24 09:26:23
回答 1查看 321关注 0票数 2

我写了一个简单的ebpf,所以我用obj = bpf_object__open_file(filename, NULL);打开它

当我做prog = bpf_object__find_program_by_name(obj, "kprobe/__x64_sys_write");的时候

此函数返回NULL并打印消息printf("finding a prog in obj file failed\n");。因此,基本上我的函数或程序无法在对象文件中找到,我想知道原因可能是什么,所以我也发现在调用bpf_object__open_file之后,我的errno被设置为2,所以我想知道究竟发生了什么,为什么在bpf_object__open_file之后将errno设置为2,并确保该文件确实存在。

这种情况也不是完全填充的。

代码语言:javascript
复制
   if (libbpf_get_error(obj)) {
    printf("ERROR: opening BPF object file failed\n");

这是一个加载程序

代码语言:javascript
复制
// 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 <errno.h>
//#include "trace_helpers.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
 */
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]="/home/fawad/bpf/linux-5.13.1/samples/bpf/kern5.o";
    printf("%s\n",filename);
    FILE *f;


//snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
    printf("errono before %d\n",errno);
    obj = bpf_object__open_file(filename, NULL);
    printf("errono after %d\n",errno);
    if (libbpf_get_error(obj)) {
        printf("ERROR: opening BPF object file failed\n");
        return 0;
    }

    printf("errno before %d\n",errno);
    prog =  bpf_object__find_program_by_name(obj, "kprobe/__x64_sys_write");
    printf("errno after %d\n",errno);
    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;
}

这是ebpf程序

代码语言:javascript
复制
/* Copyright (c) 2015 PLUMgrid, http://plumgrid.com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 */
#include <linux/ptrace.h>
#include <linux/version.h>
#include <linux/bpf.h>
#include <linux/seccomp.h>
#include <linux/unistd.h>
//#include "syscall_nrs.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>

#define PROG(F) SEC("kprobe/"__stringify(F)) int bpf_func_##F


struct {
    __uint(type, BPF_MAP_TYPE_PROG_ARRAY);
    __uint(key_size, sizeof(int));
    __uint(value_size, sizeof(int));
#ifdef __mips__
    __uint(max_entries, 6000); /* MIPS n64 syscalls start at 5000 */
#else
    __uint(max_entries, 1024);
#endif
} progs SEC(".maps");

/*SEC("kprobe/SYS__NR_write")
int bpf_prog2(struct pt_regs *ctx)
{
    struct seccomp_data sd;

    bpf_probe_read_kernel(&sd, sizeof(sd), (void *)PT_REGS_PARM2(ctx));
    if (sd.args[2] == 512) {
        char fmt[] = "write(fd=%d, buf=%p, size=%d)\n";
        bpf_trace_printk(fmt, sizeof(fmt),
                 sd.args[0], sd.args[1], sd.args[2]);
    }
    return 0;
}*/

SEC("kprobe/__seccomp_filter")
int bpf_prog1(struct pt_regs *ctx)
{
    int sc_nr = (int)PT_REGS_PARM1(ctx);

    /* 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[] = "syscall=%d (one of get/set uid/pid/gid)\n";
        bpf_trace_printk(fmt, sizeof(fmt), sc_nr);
    }
    return 0;
}

SEC("kprobe/__x64_sys_write")
/* we jump here when syscall number == __NR_write */
//PROG(SYS__NR_write)(struct pt_regs *ctx)
int __x64_sys_write(struct pt_regs *ctx)
{
    struct seccomp_data sd;

    bpf_probe_read_kernel(&sd, sizeof(sd), (void *)PT_REGS_PARM2(ctx));
    if (sd.args[2] == 512) {
        char fmt[] = "write(fd=%d, buf=%p, size=%d)\n";
        bpf_trace_printk(fmt, sizeof(fmt),
                 sd.args[0], sd.args[1], sd.args[2]);
    }
    return 0;
}

/*
PROG(SYS__NR_read)(struct pt_regs *ctx)
{
    struct seccomp_data sd;

    bpf_probe_read_kernel(&sd, sizeof(sd), (void *)PT_REGS_PARM2(ctx));
    if (sd.args[2] > 128 && sd.args[2] <= 1024) {
        char fmt[] = "read(fd=%d, buf=%p, size=%d)\n";
        bpf_trace_printk(fmt, sizeof(fmt),
                 sd.args[0], sd.args[1], sd.args[2]);
    }
    return 0;
}

#ifdef __NR_mmap2
PROG(SYS__NR_mmap2)(struct pt_regs *ctx)
{
    char fmt[] = "mmap2\n";

    bpf_trace_printk(fmt, sizeof(fmt));
    return 0;
}
#endif

#ifdef __NR_mmap
PROG(SYS__NR_mmap)(struct pt_regs *ctx)
{
    char fmt[] = "mmap\n";

    bpf_trace_printk(fmt, sizeof(fmt));
    return 0;
}
#endif
*/
char _license[] SEC("license") = "GPL";
int _version SEC("version") = LINUX_VERSION_CODE;

编译用户空间加载程序,如

代码语言:javascript
复制
 clang -L /usr/lib/usr/lib64/  -I /usr/include/   -I /usr/lib/usr/include/  tracex5_user.c -o user1.o -lbpf

编译内核ebpf程序,如

代码语言:javascript
复制
sudo clang -Wall -O2 -g -target bpf -I  /usr/lib/usr/include -I /usr/include/x86_64-linux-gnu/ -I /usr/include/linux/ -c syscall_tp_kern.c -o kern5.o
EN

回答 1

Stack Overflow用户

发布于 2022-06-01 12:42:10

请试一下这个命令

代码语言:javascript
复制
bpftool prog load bpf_test.o /sys/fs/bpf/vfs_create

在我的场景中,我得到了错误:

代码语言:javascript
复制
libbpf: failed to find BTF for extern 'PT_REGS_PARM2': -3
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70831559

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档