Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libbpf: load bpf program failed: Invalid argument #82

Closed
jiangfeng15 opened this issue Mar 29, 2023 · 1 comment
Closed

libbpf: load bpf program failed: Invalid argument #82

jiangfeng15 opened this issue Mar 29, 2023 · 1 comment

Comments

@jiangfeng15
Copy link

jiangfeng15 commented Mar 29, 2023

testing environment:

Linux admin-pc 4.18.0-10-generic #11-Ubuntu SMP Thu Oct 11 15:13:55 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
I compile a simple test program,when I run with btf file, I obtained the following error message:

error message

    libbpf: loading openat2_kern.o
    libbpf: elf: section(3) kprobe/, size 16, link 0, flags 6, type=1
    libbpf: sec 'kprobe/': found program 'bpf_prog' at insn offset 0 (0 bytes), code size 2 insns (16 bytes)
    libbpf: elf: section(4) license, size 4, link 0, flags 3, type=1
    libbpf: license of openat2_kern.o is GPL
    libbpf: elf: section(5) .eh_frame, size 48, link 0, flags 2, type=1
    libbpf: elf: skipping unrecognized data section(5) .eh_frame
    libbpf: elf: section(6) .rel.eh_frame, size 16, link 7, flags 0, type=9
    libbpf: elf: skipping relo section(6) .rel.eh_frame for section(5) .eh_frame
    libbpf: elf: section(7) .symtab, size 120, link 1, flags 0, type=2
    libbpf: looking for externs among 5 symbols...
    libbpf: collected 0 externs total
    kernel is 267008
    find program is ok
    libbpf: load bpf program failed: Invalid argument
    libbpf: failed to load program 'bpf_prog'
    libbpf: failed to load object 'openat2_kern.o'
    load object file error!

The btf file I'm using comes from the github repository: https://github.com/aquasecurity/btfhub-archive/

test code

// openat2_kern.c
#define BPF_NO_GLOBAL_DATA
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>

SEC("kprobe/__x64_sys_write")
int bpf_prog(struct pt_regs *ctx)
{
  char msg[] = "hello world!\n";
 // bpf_trace_printk(msg, sizeof(msg));
  return 0;
}

char _license[] SEC("license")="GPL";
//openat2_user.c
#include <bpf/bpf.h>
#include <bpf/libbpf.h>
#include <linux/bpf.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/resource.h>
#define DEBUGFS "/sys/kernel/debug/tracing/"

void read_trace_pipe(void){
	int trace_fd;
	trace_fd = open(DEBUGFS "trace_pipe", O_RDONLY,0);
	if(trace_fd < 0)
		return ;
	while(1){
		static char buf[4096]={0x00};
		ssize_t sz;
		sz = read(trace_fd, buf, sizeof(buf) - 1);
		if(sz > 0){
			buf[sz] = 0;
			puts(buf);
		}
	}
}

static void bump_memlock_rlimit(void)
{
	struct rlimit rlim_new = {
		.rlim_cur = RLIM_INFINITY,
		.rlim_max = RLIM_INFINITY,
	};

	if (setrlimit(RLIMIT_MEMLOCK, &rlim_new)) {
		fprintf(stderr, "Failed to increase RLIMIT_MEMLOCK limit!\n");
		exit(1);
	}
}
static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)
{
		return vfprintf(stdout, format, args);
}


int load_bpf_file(const char * object_name){

	struct bpf_object * objs;
	struct bpf_program * prog;
	struct bpf_link * link = NULL;

	bump_memlock_rlimit();
	/* Set up libbpf errors and debug info callback */
	libbpf_set_print(libbpf_print_fn);

	struct bpf_object_open_opts openopts = {};
	openopts.sz = sizeof(struct bpf_object_open_opts);
	openopts.btf_custom_path = strdup("4.18.0-13-generic.btf");
	

	printf("%s\n",openopts.btf_custom_path);
	objs = bpf_object__open_file(object_name,&openopts);
	if(objs&&libbpf_get_error(objs)){
		fprintf(stderr, "open object file error!\n");
		goto cleanup;
	}
	prog = bpf_object__find_program_by_name(objs, "bpf_prog");
	if(!prog){
		fprintf(stderr, "ERROR: finding a prog in obj file failed\n");
		fprintf(stderr, "%s\n",strerror(errno));
		goto cleanup;
	}
	printf("find program is ok\n");
	if(bpf_object__load(objs)){
		fprintf(stderr, "load object file error!\n");
		goto cleanup;
	}
	printf("load prog is ok\n");
	link = bpf_program__attach(prog);
	if(libbpf_get_error(link)){
		fprintf(stderr, "ERROR: bpf_program__attach failed.\n");
		goto cleanup;
	}
	return 0;
cleanup:
	bpf_link__destroy(link);
	bpf_object__close(objs);
	return -1;
}

int main(void)
{
    if(load_bpf_file("openat2_kern.o")){
        return -1;
  }
  read_trace_pipe();
  return 0;
}
@rafaeldtinoco
Copy link
Contributor

Your running kernel is 4.18.0-10 and the BTF is for 4.18.0-13, why is that ? Although it might work, having types from another kernel build might not be good (or sometimes work).

Apart from that, can u make it work with a simple "return" ? Have you tried other kprobes ? Or raw tracepoints ? Unfortunately old verifiers are very lousy in their error messages and one good practice is to "bisect" your source code until "it works", thus trying to have a kprobe with a single return could git you a good indication (iirc char * will be placed in rodata, which is something that might not work in older kernels, it is worth checking).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants