运行 此 ebpf 代码时出现权限被拒绝的错误消息

Permission Denied error message when running this ebpf code

我在 运行 xdp.py 文件

时收到此错误
bpf: Failed to load program: Permission denied
; int dropper(struct xdp_md *ctx) {
0: (b7) r6 = 2
; void *data_end = (void *)(long)ctx->data_end;
1: (61) r2 = *(u32 *)(r1 +4)
; void *data = (void *)(long)ctx->data;
2: (61) r1 = *(u32 *)(r1 +0)
; if (data + ipsize > data_end) {
3: (bf) r3 = r1
4: (07) r3 += 34
; if (data + ipsize > data_end) {
5: (2d) if r3 > r2 goto pc+21
 R1_w=pkt(id=0,off=0,r=34,imm=0) R2_w=pkt_end(id=0,off=0,imm=0) R3_w=pkt(id=0,off=34,r=34,imm=0) R6_w=inv2 R10=fp0
; if (ip->protocol == IPPROTO_TCP) {
6: (71) r2 = *(u8 *)(r1 +23)
; if (ip->protocol == IPPROTO_TCP) {
7: (55) if r2 != 0x6 goto pc+19
 R1_w=pkt(id=0,off=0,r=34,imm=0) R2_w=inv6 R3_w=pkt(id=0,off=34,r=34,imm=0) R6_w=inv2 R10=fp0
8: (b7) r6 = 1
; if (ntohs(tcp->dest) == 4040){
9: (69) r1 = *(u16 *)(r1 +96)
invalid access to packet, off=96 size=2, R1(id=0,off=96,r=34)
R1 offset is outside of the packet
processed 10 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0

Traceback (most recent call last):
  File "/home/kali/Documents/assignment/xdp.py", line 6, in <module>
    fn = b.load_func("dropper", BPF.XDP)
  File "/usr/lib/python3/dist-packages/bcc/__init__.py", line 527, in load_func
    raise Exception("Failed to load BPF program %s: %s" %
Exception: Failed to load BPF program b'dropper': Permission denied

这是我的xdp.py代码

from bcc import BPF #1
from bcc.utils import printb

device = "lo" 
b = BPF(src_file="dropper.c") 
fn = b.load_func("dropper", BPF.XDP)
b.attach_xdp(device, fn, 0) 

b.trace_print()

b.remove_xdp(device, 0)

这是我的dropper.c代码

#include <linux/bpf.h>
#include <linux/in.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/pkt_cls.h>
#include <linux/tcp.h>

#define SEC(NAME) __attribute__((section(NAME), used))
#undef ntohs
#define ntohs(val) ((val)&0x00ff <<8 | (val)&0xff00 >>8)

SEC("dropper_main")
int dropper(struct xdp_md *ctx) {
  int ipsize = 0;

  void *data = (void *)(long)ctx->data;
  void *data_end = (void *)(long)ctx->data_end;

  struct ethhdr *eth = data;

  ipsize = sizeof(*eth);

  struct iphdr *ip = data + ipsize;
  ipsize += sizeof(struct iphdr);
  
  if (data + ipsize > data_end) {
    return XDP_PASS;
  }

  if (ip->protocol == IPPROTO_TCP) {
    struct tcphdr *tcp = (struct tcphdr *)((__u32 *)ip + sizeof(*ip));
    //bpf_trace_printk("Packet dropped");
    if (ntohs(tcp->dest) == 4040){
        bpf_trace_printk("Packet dropped at 4040");
    }
    return XDP_DROP;
  }

  return XDP_PASS;
}

如果数据包落入 Tcp 端口 4040,我正在尝试打印数据包丢弃消息。 每当在 Tcp 端口上发送数据包时,我都能获得 Packet Dropped 消息,但无法仅针对端口 4040 获得结果。

在访问 header 之前,您需要检查数据包是否足够长以包含 TCP header,就像您检查数据包是否足够长以包含 IP header ] 在访问协议字段之前。