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
From the verifier's logs, you have some invalid access here:
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).Why not use a regular variable for
current, instead of a pointer?