I wrote a simple ebpf so I opened it with obj = bpf_object__open_file(filename, NULL);
then when I do prog = bpf_object__find_program_by_name(obj, "kprobe/__x64_sys_write");
This function returns NULL and prints message that printf("finding a prog in obj file failed\n");
. so basically my function or program could not be found in object file, I like to know what might be the reason for this so I also found after the call to bpf_object__open_file
my errno got set to 2
so I like to know what is exactly happening why my errno set to 2 right after bpf_object__open_file
and I made sure that file does exists
this condition is also not fullfilling
if (libbpf_get_error(obj)) {
printf("ERROR: opening BPF object file failed\n");
This is a loader program
// 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;
}
and this is ebpf program
/* 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;
compiling userspace loader like
clang -L /usr/lib/usr/lib64/ -I /usr/include/ -I /usr/lib/usr/include/ tracex5_user.c -o user1.o -lbpf
compiling kernel ebpf program like
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