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

warning: "Attempt to use kernel headers from user space #47

Closed
system-thoughts opened this issue Nov 8, 2021 · 4 comments
Closed

warning: "Attempt to use kernel headers from user space #47

system-thoughts opened this issue Nov 8, 2021 · 4 comments

Comments

@system-thoughts
Copy link

I imitated Minimal Makefile and wrote an out-of-kernel tree BPF program which is not CO-RE.
Hence, I include some kernel header which comes form kernel-devel in BPF program. Then I got some error:

/usr/src/kernels/4.19.90-2106.3.0.0095.oe1.x86_64/include/uapi/linux/types.h:10:2: warning: "Attempt to use kernel headers from user space, see http://kernelnewbies.org/KernelHeaders" [-W#warnings]
#warning "Attempt to use kernel headers from user space, see http://kernelnewbies.org/KernelHeaders"
 ^
readahead_tune.bpf.c:64:24: error: unknown type name 'bool'
static __always_inline bool is_expected_file(void *name)
                       ^
readahead_tune.bpf.c:71:16: error: use of undeclared identifier 'false'; did you mean 'else'?
        return false;
               ^~~~~
               else
readahead_tune.bpf.c:71:16: error: expected expression
readahead_tune.bpf.c:85:30: error: use of undeclared identifier 'FMODE_WILLNEED'
        rd_ctx->set_f_mode = FMODE_WILLNEED;
                             ^
readahead_tune.bpf.c:91:5: error: use of undeclared identifier 'bool'
    bool first = false;
    ^
readahead_tune.bpf.c:97:9: error: use of undeclared identifier 'first'
        first = true;
...

And the Makefile:

OUTPUT := .output
CLANG ?= clang -v
BPFTOOL ?= bpftool
LINUX_HEADER ?= /usr/src/kernels/`uname -r` 
LINUX_INCLUDE = -I $(LINUX_HEADER)/include/uapi \
                -I $(LINUX_HEADER)/include
...
# Build BPF code
$(OUTPUT)/%.bpf.o: %.bpf.c $(wildcard %.h) | $(OUTPUT)
    $(call msg,BPF,$@)
    $(Q)$(CLANG) -g -O2 -target bpf \
    -D__TARGET_ARCH_$(ARCH) \
    $(LINUX_INCLUDE) $(CLANG_BPF_SYS_INCLUDES) -c $(filter %.c,$^) -o $@

The BPF program:

#include <linux/stddef.h> // for true/false
#include <linux/types.h> // for bool
#include <linux/fs.h> // for FMODE_WILLNEED
...

So what do we need something else to make out-of-kernel tree Non-CO-RE BPF program build successfully?

@system-thoughts
Copy link
Author

This warning can be elimated by add -D__KERNEL__:

# Build BPF code
$(OUTPUT)/%.bpf.o: %.bpf.c $(wildcard %.h) | $(OUTPUT)
    $(call msg,BPF,$@)
    $(Q)$(CLANG) -g -O2 -target bpf \
    -D__KERNEL__ -D__TARGET_ARCH_$(ARCH) \
    $(LINUX_INCLUDE) $(CLANG_BPF_SYS_INCLUDES) -c $(filter %.c,$^) -o $@

However, other undeclared identifier error still exist.

@anakryiko
Copy link
Member

The recommendation is to use CO-RE and vmlinux.h. If you can't or don't want to, you'll have to make sure you are including the right headers with the right definitions. bool should come from just <stdbool.h>, there rest would come from either UAPI or kernel-internal headers (and kernel-internal is where you are running into issues, probably).

Check out bootstrap example for vmlinux.h usage. That makes everything much-much simpler (but you'll need kernel BTF, of course). You might want to check https://github.com/aquasecurity/btfhub and follow the BTFGen discussion which is currently happening upstream.

@system-thoughts
Copy link
Author

The recommendation is to use CO-RE and vmlinux.h. If you can't or don't want to, you'll have to make sure you are including the right headers with the right definitions. bool should come from just <stdbool.h>, there rest would come from either UAPI or kernel-internal headers (and kernel-internal is where you are running into issues, probably).

Thanks for your reply. Because the BPF program will run Non-BTF OS(CONFIG_DEBUG_INFO_BTF is not set), So I imitated Minimal APP to write this BPF program.
Now, I decided to use vmlinux.h to slove the linux header problem, Howerver, is it possible to run such BPF program on Non-BTF OS?
Even though I delete #include <linux/stddef.h> line, the problem still exist, and the <stdbool.h> you mentioned is from standard libc or kernel internal implementaion?

@anakryiko
Copy link
Member

You can safely use vmlinux.h if you generated it from exactly the same vmlinux image that you are going to run on. Or if you are absolutely sure that you are using only types defined in kernel UAPI (which means they won't change their layout). But the latter doesn't seem true in your case, because you've tried to use internal kernel headers.

So, you can use vmlinux.h without relying on CO-RE, you'll just need to make sure that you have a matching vmlinux image. And you'll need to #define BPF_NO_PRESERVE_ACCESS_INDEX before #include "vmlinux.h" to disable CO-RE annotations.

stdbool.h was from standard libc, but you won't need it with vmlinux.h

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