XDP程序ip链接错误:Prog部分被拒绝:不允许操作 [英] XDP program ip link error: Prog section rejected: Operation not permitted

查看:307
本文介绍了XDP程序ip链接错误:Prog部分被拒绝:不允许操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I try to get into XDP, for this I have this very small program:

// 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中,则会出现此错误:

But if I try to load it into a virtual interface veth-basic02, I get this error:

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

$ sudo ip -force link set dev veth-basic02 xdp object xdpsock_kern.o section xdp_sock

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

Prog section 'xdp_sock' rejected: Operation not permitted (1)! - Type: 6 - Instructions: 2 (0 over limit) - License:

验证者分析:

获取程序/地图时出错!

Error fetching program/map!

内核版本:5.3.0-28-generic

这是我正在使用的Makefile:

This is the Makefile I am using:

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-Program了!虽然有趣的复活节彩蛋.谢谢@Qeole!

echo 1 > /proc/sys/kernel/sysrq + echo x > /proc/sysrq-trigger + Alt+SysRq+x indeed solves the problem - I can finally load the XDP-Program! Funny easter egg though. Thank you @Qeole!

推荐答案

eBPF:不允许操作

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

eBPF: Operation not permitted

There are several possible causes for a permission error (-EPERM returned by bpf(), which you can observe with strace -e bpf <command>) when working with eBPF. But no so many. Usually, they fall under one of the following items:

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

  • User does not have the required capabilities (CAP_SYS_ADMIN, CAP_NET_ADMIN, ... typically depending on the types of the programs being used). This is usually solved by running as root, who has all necessary capabilities. In your case you run with sudo, so you are covered.

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

Creating the BPF object (new map, or loading a program) would exceed the limit for the amount of memory that can be locked in the kernel by the user. This is usually solved (for root) by using ulimit -l <something_big> in the terminal, or setrlimit() in a C program. Very unlikely in your case, your program is very small and you did not mention having a lot of BPF objects loaded on your system.

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

There are a few more possibilies, like trying to write on maps that are "frozen" or read-only etc., or trying to use function calls for non-root users. These are usually for more advanced use cases and should not be hit with a program as simple as yours.

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

But the problem that you seem to be hitting could be related to something else. "Lockdown" is a security module that was merged into Linux 5.5 kernel. It aims at preventing users to modify the running Linux image. It turns out that several distributions decided to backport Lockdown to their kernels, and sometimes they picked patches that predated the final version that was merged to mainline Linux.

Ubuntu和Fedora具有完全禁用bpf()系统调用,这意味着无法创建地图或加载BPF程序.此外,它们已启用激活安全启动后默认情况下会锁定,我认为这是使用EFI引导计算机的默认设置.

Ubuntu and Fedora, for example, have a bunch of custom patches to backport that feature to the kernels used in Disco/19.04 and Eoan/19.10 (kernel 5.3 for the latter, I don't remember for Disco). It includes a patch that completely disables the bpf() system call when Lockdown is activated, meaning that creating maps or loading BPF programs is not possible. Also, they enabled Lockdown by default when Secure Boot is activated, which, I think, is the default for machines booting with EFI.

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

See also this blog post: a good way to check if Lockdown is affecting your BPF usage is to try and load minimal programs, or to run dmesg | grep Lockdown to see if it says something like:

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

例如,对于 Ubuntu 19.04和19.10 ,您必须禁用锁定才能使用eBPF .这可以通过 SysRq键+ x 的物理笔触来完成(我尚未测试),但不是通过写/proc/sysrq-trigger来完成(Ubuntu

So for Ubuntu 19.04 and 19.10, for example, you have to disable Lockdown to work with eBPF. This may be done with a physical stroke of the SysRq key + x (I have not tested), but NOT by writing to /proc/sysrq-trigger (Ubuntu disabled it for this operation). Alternatively, you can disable Secure Boot (in the BIOS or with mokutil, search for the relevant options on the Internet, and do not forget to check the security implications).

请注意,Linux内核5.4或最新版本具有主线限制bpf()的a>不会取消激活系统调用,因此Focal/20.04和最新版本不会受到影响. 升级到新内核可能是另一种解决方法.我几天前提交了罚单要回传的更改(而不是停用bpf())并且工作正在进行中,因此,当新读者看到答案时,锁定对eBPF的影响可能会得到缓解(应该修复在具有内核5.3.0-43的Ubuntu 19.10上).不确定其他发行版如何处理此问题.不过,它仍然对使用eBPF进行跟踪具有强大的含义.

Note that Linux kernel 5.4 or newest has the mainline restrictions for bpf(), which do not deactivate the system call, so Focal/20.04 and newest will not be affected. Upgrading to a new kernel might thus be another workaround. I filed a ticket a few days ago to ask for this change to be backported (instead of deactivating bpf()) and the work is in progress, so by the time new readers look at the answer Lockdown impact on eBPF might well be mitigated ( Should be fixed on Ubuntu 19.10 with kernel 5.3.0-43). Not sure how other distros handle this. And it will still have strong implications for tracing with eBPF, though.

这篇关于XDP程序ip链接错误:Prog部分被拒绝:不允许操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆