当前位置: 首页 > 面试题库 >

XDP程序ip链接错误:Prog部分被拒绝:不允许操作

包建义
2023-03-14
问题内容

我尝试进入XDP,为此,我有一个非常小的程序:

// SPDX-License-Identifier: GPL-2.0
#include <linux/bpf.h>
#include "bpf/bpf_helpers.h"
#include "xdpsock.h"

struct {
    __uint(type, BPF_MAP_TYPE_ARRAY);
    __uint(max_entries, MAX_SOCKS);
    __uint(key_size, sizeof(int));
    __uint(value_size, sizeof(int));
} xsks_map SEC(".maps");

SEC("xdp_sock") int xdp_sock_prog(struct xdp_md *ctx) {

    return XDP_DROP;
}

但是,如果我尝试将其加载到虚拟接口中veth-basic02,则会出现此错误:

$ sudo ip -force链接集dev veth-basic02 xdp对象xdpsock_kern.o部分xdp_sock

编节“ xdp_sock”被拒绝:不允许操作(1)!-类型:6-说明:2(超出限制0)-许可证:

验证者分析:

提取程序/地图时出错!

内核版本: 5.3.0-28-generic

这是我正在使用的Makefile:

OBJS = xdpsock_kern.o

LLC ?= llc
CLANG ?= clang
INC_FLAGS = -nostdinc -isystem `$(CLANG) -print-file-name=include`
EXTRA_CFLAGS ?= -O2 -emit-llvm

# In case up-to-date headers are not installed locally in /usr/include,
# use source build.

linuxhdrs ?= /usr/src/linux-headers-5.1.0-050100

LINUXINCLUDE =  -I$(linuxhdrs)/arch/x86/include/uapi \
                -I$(linuxhdrs)/arch/x86/include/generated/uapi \
                -I$(linuxhdrs)/include/generated/uapi \
                -I$(linuxhdrs)/include/uapi \
                -I$(linuxhdrs)/include  \
                -I/bpf

prefix ?= /usr/local

INSTALLPATH = $(prefix)/lib/bpf

install_PROGRAM = install
install_DIR = install -dv

all:    $(OBJS)

.PHONY: clean

clean:
    rm -f $(OBJS)

INC_FLAGS = -nostdinc -isystem `$(CLANG) -print-file-name=include`

$(OBJS):  %.o:%.c
    $(CLANG) $(INC_FLAGS) \
                -D__KERNEL__ -D__ASM_SYSREG_H \
                -Wno-unused-value -Wno-pointer-sign \
                -Wno-compare-distinct-pointer-types \
                -Wno-gnu-variable-sized-type-not-at-end \
                -Wno-address-of-packed-member -Wno-tautological-compare \
                -Wno-unknown-warning-option \
                -I../include $(LINUXINCLUDE) \
                $(EXTRA_CFLAGS) -c $< -o -| $(LLC) -march=bpf -filetype=obj -o $@

install: $(OBJS)
    $(install_DIR) -d $(INSTALLPATH) ; \
    $(install_PROGRAM) $^ -t $(INSTALLPATH)

uninstall: $(OBJS)
    rm -rf $(INSTALLPATH)

封锁:

$ dmesg | grep Lockdown
[    1.283355] Lockdown: swapper/0: Hibernation is restricted; see man kernel_lockdown.7
[   11.313219] Lockdown: systemd: /dev/mem,kmem,port is restricted; see man kernel_lockdown.7
[   11.337794] Lockdown: systemd: BPF is restricted; see man kernel_lockdown.7
[   17.147844] Lockdown: Xorg: ioperm is restricted; see man kernel_lockdown.7

编辑: echo 1> /proc/sys/kernel/sysrq+ echo x > /proc/sysrq-trigger+
Alt+SysRq+x确实解决了这个问题-我终于可以加载XDP-计划!虽然有趣的复活节彩蛋。谢谢@Qeole!


问题答案:

eBPF:不允许操作

使用eBPF时,有几种可能的原因导致权限错误(-EPERM由返回bpf(),您可以通过观察到strace -e bpf <command>)。但是没有那么多。通常,它们属于以下项目之一:

  • 用户没有所需的功能CAP_SYS_ADMIN,,CAP_NET_ADMIN…,通常取决于所使用程序的类型)。通常可以通过 运行root具有所有必要功能的来解决。在您的情况下,您可以使用sudo,因此可以满足要求。

  • 创建BPF对象(新映射或加载程序)将 超出用户可以在内核中锁定的内存量的限制 。这通常可以root通过 ulimit -l<something_big>在终端或 setrlimit() C程序中使用来解决。在您的情况下,您的程序非常小,并且您没有提到在系统上加载了很多BPF对象。

  • 还有更多的可能性,例如 尝试在“冻结”或只读 等的 地图上进行写操作 ,或 尝试对非root用户使用函数调用。这些通常用于更高级的用例,不应被像您这样简单的程序所破坏。

锁定,安全启动,EFI和(不幸的)反向端口的bpf()限制

但是,您似乎遇到的问题可能与其他原因有关。“锁定”是一个安全模块,已合并到Linux
5.5内核中。它旨在防止用户修改正在运行的Linux映像。事实证明,有几个发行版决定将Lockdown移植到他们的内核中,有时他们选择了在最终版本合并到主线Linux之前的补丁。

例如,Ubuntu和Fedora有许多自定义补丁程序可以向后移植,以适应Disco / 19.04和Eoan /
19.10(后者为5.3,我不记得Disco的内核)中使用的内核。它包含一个修补程序,当锁定功能被激活时,该修补程序将完全禁用bpf()系统调用,这意味着无法创建地图或加载BPF程序。另外,它们在激活安全启动时默认情况下启用了锁定,我认为这是使用EFI引导的计算机的默认设置。

另请参见此博客文章:检查锁定是否影响您的BPF使用的一种好方法是尝试加载最少的程序,或者运行dmesg | grep Lockdown以查看是否显示类似以下内容:

Lockdown: systemd: BPF is restricted; see man kernel_lockdown.7

因此 ,例如 对于 Ubuntu 19.04和19.10, 必须 禁用Lockdown才能与eBPF一起使用
。可以通过SysRq按键+x的物理笔划来完成此操作(我尚未测试),但不能通过写操作来完成/proc/sysrq-trigger。另外,您可以禁用安全启动(在BIOS中或通过mokutil,在Internet上搜索相关选项,并且不要忘记检查安全隐患)。

需要注意的是Linux内核5.4或最新的有主线限制的bpf(),不取消的系统调用,所以焦/
20.04和最新不会受到影响。 因此,升级到新内核可能是另一个解决方法
。我几天前提交了一份票证,要求将此更改回移植(而不是停用bpf()),并且该工作正在进行中,因此,到新读者看到答案时,锁定对eBPF的影响可能会得到缓解(编辑:应该已在内核5.3.0-43的Ubuntu19.10上修复)。不确定其他发行版如何处理此问题。但是,它对于使用eBPF进行跟踪仍然具有重要意义。



 类似资料:
  • Meteor 的安全系统不需要我们在每次修改数据的时候,在各自的函数里面进行手动检查。 例如,对于一个博客系统,我们常常需要做很多操作,往新帖子上添加属性,当发布帖子的时候进行特定检查。这些操作都是围绕帖子(post)这个对象进行的,所以我们应该为帖子设置一个专门的函数进行安全检查。 但在另一方面,我们又不希望为修改帖子或删除帖子这些简单的操作编写特定的函数。我们只需要在这些操作之前,检查用户是否

  • 线程“main”org.springframework.web.client.resourceAccessException中的异常:“http://localhost:8081/footballershirt/footballershirts”的GET请求上的I/O错误:拒绝连接:连接;嵌套的异常是java.net.connectException:Connection:Connection a

  • 问题内容: 我正在尝试运行一个Python脚本,该脚本使用由后链接程序创建的二进制文件(xFiles.bin.addr_patched)。但是,我收到此错误。 当我通过ls-l检查此xFiles.bin的权限时,它表明 我认为错误是因为此文件是由其他应用程序创建的,我正在运行的python脚本无法访问它。因为我是ubuntu的初学者,所以我真的不知道如何解决它。对于如何解决这个问题,有任何的建议吗

  • 问题内容: 我正在尝试将Redis用作我的使用Docker Compose的Django项目的Celery的代理。我无法弄清楚我到底做错了什么,但是尽管控制台日志消息告诉我Redis正在运行并接受连接(实际上,当我这样做时,我可以看到容器正在运行),但我仍然会收到有关拒绝连接的错误消息。我什至做到了 看到回应是。 这是my中的Celery设置: 这是my中的Redis容器设置: 我还记得将容器与我

  • 有一个关于阿帕奇的 php 文件: 和节点js在同一个目录中 浏览器抛出错误:GEThttp://192.168.100.31/socket.io/?EIO=4 如果替换let套接字=io.connect('http://localhost:3000')在let套接字=io.connect('http://192.168.100.31:3000');浏览器将给出另一个错误:访问XMLHttp请求在

  • 问题内容: 我在用 Windows 7的 Netbeans IDE 7.1.2 SQL Server管理Studio Express 2005 JDK1.6 连接到数据库时出现以下错误: com.microsoft.sqlserver.jdbc.SQLServerException:与主机的TCP / IP连接失败。java.net.ConnectException:连接被拒绝:connect 我