簡體   English   中英

不斷收到 bpf:無法加載程序:嘗試運行 eBPF 代碼時權限被拒絕

[英]Keep getting bpf: Failed to load program: Permission denied when trying to run eBPF code

抱歉,我對編寫 eBPF 代碼真的很陌生,所以我遇到了一個我似乎無法擺脫的錯誤。 在 sudo 中運行似乎沒有幫助。 我寫了一個速度較慢的 crc32 程序,它可以編譯,但無論如何這個程序都不想執行。 我想知道我是否違反了我沒有看到的任何約定。

bpf_text2 = """
#include <uapi/linux/ptrace.h>

int crc32(struct pt_regs *ctx) {
char str[256] = {};
bpf_probe_read(&str, sizeof(str), (void *)PT_REGS_RC(ctx));
const uint32_t Polynomial = 0xEDB88320;

u64 startTime = bpf_ktime_get_ns();

uint32_t previousCrc32 = 0;
uint32_t crc = ~previousCrc32;
unsigned char* current = 0;

int maxVal = sizeof(str);
while (maxVal--) {
    crc ^= *current++;
    for (unsigned int j = 0; j < 8; j++) {
        crc = (crc >> 1) ^ ((0 - (crc & 1)) & Polynomial);
    }
}
int result = ~crc;
u64 totalTime = bpf_ktime_get_ns() - startTime;

bpf_trace_printk(">> BCC - CRC of `\\"%s\\" is: 0x%x \\n",str, result);
bpf_trace_printk(">> BCC - CRC took: %lu cycles\\n", totalTime);
bpf_trace_printk("BCC - Test Complete.\\n\\n\\n");

return 0;
}
"""

這里也快速瀏覽一下下面的錯誤消息。

> Compiling BPF
Attaching to uretprobe
bpf: Failed to load program: Permission denied
btf_vmlinux is malformed
Unrecognized arg#0 type PTR
; int crc32(struct pt_regs *ctx) {
0: (b7) r8 = 0
; char str[256] = {};
1: (7b) *(u64 *)(r10 -8) = r8
last_idx 1 first_idx 0
regs=100 stack=0 before 0: (b7) r8 = 0
2: (7b) *(u64 *)(r10 -16) = r8
3: (7b) *(u64 *)(r10 -24) = r8
4: (7b) *(u64 *)(r10 -32) = r8
5: (7b) *(u64 *)(r10 -40) = r8
6: (7b) *(u64 *)(r10 -48) = r8
7: (7b) *(u64 *)(r10 -56) = r8
8: (7b) *(u64 *)(r10 -64) = r8
9: (7b) *(u64 *)(r10 -72) = r8
10: (7b) *(u64 *)(r10 -80) = r8
11: (7b) *(u64 *)(r10 -88) = r8
12: (7b) *(u64 *)(r10 -96) = r8
13: (7b) *(u64 *)(r10 -104) = r8
14: (7b) *(u64 *)(r10 -112) = r8
15: (7b) *(u64 *)(r10 -120) = r8
16: (7b) *(u64 *)(r10 -128) = r8
17: (7b) *(u64 *)(r10 -136) = r8
18: (7b) *(u64 *)(r10 -144) = r8
19: (7b) *(u64 *)(r10 -152) = r8
20: (7b) *(u64 *)(r10 -160) = r8
21: (7b) *(u64 *)(r10 -168) = r8
22: (7b) *(u64 *)(r10 -176) = r8
23: (7b) *(u64 *)(r10 -184) = r8
24: (7b) *(u64 *)(r10 -192) = r8
25: (7b) *(u64 *)(r10 -200) = r8
26: (7b) *(u64 *)(r10 -208) = r8
27: (7b) *(u64 *)(r10 -216) = r8
28: (7b) *(u64 *)(r10 -224) = r8
29: (7b) *(u64 *)(r10 -232) = r8
30: (7b) *(u64 *)(r10 -240) = r8
31: (7b) *(u64 *)(r10 -248) = r8
32: (7b) *(u64 *)(r10 -256) = r8
; bpf_probe_read(&str, sizeof(str), (void *)PT_REGS_RC(ctx));
33: (79) r3 = *(u64 *)(r1 +0)
34: (bf) r1 = r10
; 
35: (07) r1 += -256
; bpf_probe_read(&str, sizeof(str), (void *)PT_REGS_RC(ctx));
36: (b7) r2 = 256
37: (85) call bpf_probe_read#4
last_idx 37 first_idx 0
regs=4 stack=0 before 36: (b7) r2 = 256
38: (18) r7 = 0xffffffff
40: (18) r9 = 0xffffff00
; u64 startTime = bpf_ktime_get_ns();
42: (85) call bpf_ktime_get_ns#5
43: (7b) *(u64 *)(r10 -304) = r0
44: (18) r1 = 0xfffffffe
46: (18) r2 = 0xedb88320
; crc ^= *current++;
48: (71) r3 = *(u8 *)(r8 +0)
R8 invalid mem access 'inv'
processed 45 insns (limit 1000000) max_states_per_insn 0 total_states 1 peak_states 1 mark_read 1
> 
> HINT: The invalid mem access 'inv' error can happen if you try to
> dereference memory without first using bpf_probe_read() to copy it to
> the BPF stack. Sometimes the bpf_probe_read is automatic by the bcc
> rewriter, other times you'll need to be explicit.

提示:如果您嘗試取消引用 memory 而不先使用 bpf_probe_read() 將其復制到 BPF 堆棧,則可能會發生無效的 mem 訪問“inv”錯誤。 有時 bpf_probe_read 由 bcc 重寫器自動執行,有時您需要明確。

 Traceback (most recent call last): File "/home/pi/Desktop/crc32.py", line 116, in <module> b.attach_uretprobe(name="/bin/bash", sym="readline", fn_name="crc32") File "/usr/lib/python3/dist-packages/bcc/__init__.py", line 1058, in attach_uretprobe fn = self.load_func(fn_name, BPF.KPROBE) File "/usr/lib/python3/dist-packages/bcc/__init__.py", line 394, in load_func raise Exception("Failed to load BPF program %s: %s" % Exception: Failed to load BPF program b'crc32': Permission denied

從驗證者的日志中,您在這里有一些無效的訪問權限:

; crc ^= *current++;
48: (71) r3 = *(u8 *)(r8 +0)
R8 invalid mem access 'inv'

這可能是由於您的指針被初始化為0 (指針本身,而不是它指向的值)。 然后嘗試在沒有初始化其內容的情況下取消引用它(對於 null 指針無論如何都不可能)。

unsigned char* current = 0;  // current is 0

[...]
while (maxVal--) {
    crc ^= *current++;       // read at address 0 and increment this value??
    ...
}

為什么不對current使用常規變量,而不是指針?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM