0

(sorry for posting here, couldn't create ticket on github/libbpf ) libbf failure on system with BTF disabled. Issue : we are doing negative testing for our product like disabling BTF INFO from kernel.

Current failure test we have BPF_SYSCALL enabled but disabled CONFIG_DEBUG_INFO_BTF=n. meaning we don't have /sys/kernel/btf/vmlinux.

we have code with both CORE dependent and non CORE bpf kernel code handlers. Features are enabled or disabled based on config.

some of CORE depended programs are not loaded ( bpf_program__set_autoload(). but user space failing with following error because libbpf looking for vmlinux.

libbpf: kernel BTF is missing at '/sys/kernel/btx/vmlinux', was CONFIG_DEBUG_INFO_BTF enabled?

obj_needs_vmlinux_btf-> hitting if (obj->btf_ext && obj->btf_ext->core_relo_info.len && !obj->btf_custom_path) -> true;

Question is, How do we stop libbpf to stop looking for BTF and vmlinux when CORE related programs are disabled. is there way to set some flags for bpf object to stop this.

Tried to simulate our product code with libbpf-bootstrap/examples/c /bootstrap.bpf.c

userspace CORE handlers disabled while loading bootstrap.bpf.c.

    +       bpf_program__set_autoload(skel->progs.handle_exec, false);
    +       bpf_program__set_autoload(skel->progs.handle_exit, false);
    

added extra tracepoint (non core) in bootstrap.bpf.c (along with core handlers)

    +SEC("tp/syscalls/sys_enter_write")
    +int handle_tp(void *ctx)
    +{
    +       int my_pid = 0;
    +        int pid = bpf_get_current_pid_tgid() >> 32;
    +
    +        if (pid != my_pid)
    +                return 0;
    +
    +        bpf_printk("BPF triggered from PID %d.\n", pid);
    +
    +        return 0;
    +}

following error we are getting because while opening bpf object , libbpf inpsecting and preparing btf

libbpf: kernel BTF is missing at '/sys/kernel/btf/vmlinux', was CONFIG_DEBUG_INFO_BTF enabled?
libbpf: failed to find '.BTF' ELF section in /lib/modules/6.0.7/build/vmlinux
libbpf: failed to find valid kernel BTF
libbpf: Error loading vmlinux BTF: -ESRCH
libbpf: failed to load BPF skeleton 'bootstrap_bpf': -ESRCH

FYI : using latest libbpf version from github (updated libbpf-bootstrap libbpf )

OS Details : Linux Ubuntu 24.04 LTS-64 Distribution Details : "Ubuntu 24.04 LTS" Kernel Details : 6.0.7

Giving smaller reproducer code ,sorry for confusion.

Adding code : example is taken from https://github.com/libbpf/libbpf-bootstrap.git

Files : user kprobe.c kernel : kprobe.bpf.c

Modifications : added non core handler code tp/syscalls/sys_enter_write

user space code:

// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
/* Copyright (c) 2021 Sartura
 * Based on minimal.c by Facebook */

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <sys/resource.h>
#include <bpf/libbpf.h>
#include "kprobe.skel.h"

static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)
{
        return vfprintf(stderr, format, args);
}

static volatile sig_atomic_t stop;

static void sig_int(int signo)
{
        stop = 1;
}

int main(int argc, char **argv)
{
        struct kprobe_bpf *skel;
        int err;

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

        /* Open load and verify BPF application */
        skel = kprobe_bpf__open_and_load();
        if (!skel) {
                fprintf(stderr, "Failed to open BPF skeleton\n");
                return 1;
        }

        /* Attach tracepoint handler */
        err = kprobe_bpf__attach(skel);
        if (err) {
                fprintf(stderr, "Failed to attach BPF skeleton\n");
                goto cleanup;
        }

        if (signal(SIGINT, sig_int) == SIG_ERR) {
                fprintf(stderr, "can't set signal handler: %s\n", strerror(errno));
                goto cleanup;
        }

        printf("Successfully started! Please run `sudo cat /sys/kernel/debug/tracing/trace_pipe` "
               "to see output of the BPF programs.\n");

        while (!stop) {
                fprintf(stderr, ".");
                sleep(1);
        }

cleanup:
        kprobe_bpf__destroy(skel);
     

kerne space code

// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright (c) 2021 Sartura */
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>

char LICENSE[] SEC("license") = "Dual BSD/GPL";

// CORE dependent code
SEC("kprobe/do_unlinkat")
int BPF_KPROBE(do_unlinkat, int dfd, struct filename *name)
{
        pid_t pid;
        const char *filename;

        pid = bpf_get_current_pid_tgid() >> 32;
        filename = BPF_CORE_READ(name, name);
        bpf_printk("KPROBE ENTRY pid = %d, filename = %s\n", pid, filename);
        u64 ip = PT_REGS_IP(ctx);
        bpf_printk("KPROBE entry pid = %d, ip  %llx\n", pid, ip);

        return 0;
}

SEC("kretprobe/do_unlinkat")
int BPF_KRETPROBE(do_unlinkat_exit, long ret)
{
        pid_t pid;

        pid = bpf_get_current_pid_tgid() >> 32;
        bpf_printk("KPROBE EXIT: pid = %d, ret = %ld\n", pid, ret);
        u64 ip = PT_REGS_IP(ctx);
        bpf_printk("KPROBE exit pid = %d, ip  %llx\n", pid, ip);
        return 0;
}

//


// Non core code
SEC("tp/syscalls/sys_enter_write")
int handle_tp(void *ctx)
{
    int my_pid = 0;
    int pid = bpf_get_current_pid_tgid() >> 32;

    if (pid != my_pid)
        return 0;

    bpf_printk("BPF triggered from PID %d.\n", pid);

    return 0;
}
4
  • Could you share your loader code? Commented Mar 28 at 10:19
  • This and subfunctions is what libbpf uses to know if your program requires BTF. So we'll also need to see the BPF program to answer :) Commented Mar 28 at 10:25
  • @pchaigno An example has been added at the end of the post. The question pertains to scenarios where we have CORE related code, specifically code that is dependent on BTF, alongside non-BTF dependent code (which supports older kernels). Depending on whether BTF support is available, we decide to disable certain features. However, it appears that the kernel BTF bytecode is already embedded in the skeleton program, which libbpf is attempting to parse. Is there a method for users of libbpf to open a BPF object while disabling BTF lookup? (like open_opts options for compatibility?) Commented Apr 1 at 4:38
  • @pchaigno please let me know if my understanding is correct or not. Seems like there is no off switch for skipping btf information parsing while creating bpf object creation. let me know if we need any more information. Commented Apr 2 at 6:26

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.