在一个简单的程序中加载 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。只需使用clanggcc 定期编译您的加载程序即可:

$ clang -Wall -o user user.c

然后您应该能够在此之后运行您的可执行文件(尽管我没有检查您的程序是否按预期工作):

$ sudo ./user

(注意:编译时您可能仍需要传递一些包含路径,-I /home/ubuntu/Desktop/linux/test/linux-5.14.1/samples/bpf/ 用于&lt;bpf_load.h&gt;,可能还需要传递到&lt;bpf/libbpf.h&gt; 的路径)

【讨论】:

也请告诉我找不到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 应用程序

如何在页面加载时调度 redux 操作以在 useEffect 中加载数据

滚动以在 UIView 中加载内容

Google Adsense 广告未在 UIWebView 中加载