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

6k views Asked by At

Sorry, I am really new to writing eBPF code, so I came upon an error that I can't seem to shake off. Running in sudo does not seem to help. And I wrote a slower crc32 program that compiles but this one does not want to execute no matter what. I am wondering if I'm breaking any convention that I am just not seeing.

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;
}
"""

Here's a quick look at the error message below aswell.

> 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.

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.

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
1

There are 1 answers

0
Qeole On BEST ANSWER

From the verifier's logs, you have some invalid access here:

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

This is likely caused by your pointer being initialised at 0 (the pointer itself, not the value it points to!), and then trying to dereference it without having ever initialized its content (which wouldn't be possible anyway for a null pointer).

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

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

Why not use a regular variable for current, instead of a pointer?