在一个简单的程序中加载 ebpf 程序时,以 sudo 和 root 身份运行会给出错误权限被拒绝
Posted
技术标签:
【中文标题】在一个简单的程序中加载 ebpf 程序时,以 sudo 和 root 身份运行会给出错误权限被拒绝【英文标题】:running as sudo with root gives error permission denies when loading ebpf program in a simple program 【发布时间】:2022-01-19 09:40:57 【问题描述】:这是我的简单 ebpf 程序
#include <linux/bpf.h>
#include <linux/version.h>
#include <linux/ip.h>
#include <linux/if_ether.h>
#include <bpf_helpers.h>
#include <bpf_endian.h>// iproute specifically looks for this ELF section
//#include <net/sock.h>
#include <linux/bpf.h>
#include <linux/version.h>
#include <bpf_helpers.h>
#define bpf_printk(fmt, ...) \
( \
char ____fmt[] = fmt; \
bpf_trace_printk(____fmt, sizeof(____fmt), \
##__VA_ARGS__); \
)
SEC("kprobe/tcp_connect")
int connect(struct pt_regs *ctx)
bpf_printk("connect called -- Hello from [fawad] \n");
return 0;
char _license[] SEC("license") = "GPL";
用这个命令编译上面的程序
clang -O2 -Wall -target bpf -c -o xdp.o -I /build/root/usr/include/bpf -I /usr/src/linux-headers-5.11.0-41/arch/alpha/include/ -I /usr/src/linux-headers-5.11.0-41/arch/alpha/include/ xdp.c
这是一个加载程序
#include <stdlib.h>
#include <unistd.h>
#include <sys/resource.h>
#include <bpf/libbpf.h>
#include <bpf_load.h>
int main() // raise the rlimit or see
// failed to create a map: 1 Operation not permitted
// when load_bpf_file is run
if (load_bpf_file("xdp.o"))
printf("%s\n", bpf_log_buf);
return 1;
while(1)
sleep(1);
return 0;
像这样编译我的 ebpf 加载程序
clang -O2 -Wall -target bpf -c -o user.o -I /build/root/usr/include/bpf -I /home/ubuntu/Desktop/linux/test/linux-5.14.1/samples/bpf/ -I /usr/src/linux-headers-5.11.0-41/arch/alpha/include/ -I /usr/src/linux-headers-5.11.0-41/arch/alpha/include/ user.c
当我运行像 #./user.o 这样的加载程序时
报错
bash: ./user.o: Permission denied
使用 sudo 运行甚至无法识别文件
root@this:/home/ubuntu/Desktop/ebpf# sudo ./user.o
sudo: ./user.o: command not found
root@this:/home/ubuntu/Desktop/ebpf#
【问题讨论】:
我正在将 ebpf 程序作为编译后的新文件加载。我读到我需要在加载 ebpf 程序之前从 elf 文件中去除标题是真的吗? 您不能运行目标文件。您需要将它们链接到可执行文件中。 你只编译了user.c到user.o。那还没有通过另一个调用生成可执行文件。比如clang -o user user.o xdp.o
(这是链接器)
@Someprogrammerdude 如果我不提供 -c 来创建可执行文件,clang 会抛出没有输入文件的错误,如何解决这个问题?取自这里***.com/a/1847104/4808760
"loader" 程序是一个纯 C 程序,不应使用 -target bpf
选项。那么它不应该使用-c
选项。它确实有一个“输入”,即user.c
源文件。因此,您应该在没有-target bpf
或-c
选项的情况下构建您的程序,并将您的程序命名为user
而不是user.o
。然后运行./user
。
【参考方案1】:
只有您的 eBPF 程序需要编译为 eBPF,目标为 -t bpf
。只需使用clang
或gcc
定期编译您的加载程序即可:
$ clang -Wall -o user user.c
然后您应该能够在此之后运行您的可执行文件(尽管我没有检查您的程序是否按预期工作):
$ sudo ./user
(注意:编译时您可能仍需要传递一些包含路径,-I /home/ubuntu/Desktop/linux/test/linux-5.14.1/samples/bpf/
用于<bpf_load.h>
,可能还需要传递到<bpf/libbpf.h>
的路径)
【讨论】:
也请告诉我找不到load_bpf_file
函数如何包含此函数的头文件。你能给我一个加载ebpf程序的简单例子吗?我在 linux 5.14.1
load_bpf_file
来自内核示例,但它有些过时,越来越多的示例放弃了它,转而支持 libbpf。您必须从内核目录中的 samples/bpf/ 获取标头,我不记得是否也有单独的 .c 程序,可能检查现有示例。如果你想用 libbpf 构建你的加载程序,这可能是一个更好的选择,我强烈建议你查看libbpf-boostrap。以上是关于在一个简单的程序中加载 ebpf 程序时,以 sudo 和 root 身份运行会给出错误权限被拒绝的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 WKWebVIew 或 JSC 在 iOS 应用程序中加载 WebAssembly
我可以从捆绑的 javascript 应用程序中加载文件吗?
在本地加载 CSS,但不在 Heroku 中加载 Rails 应用程序