Open
Description
ENV
kernel: 6.3.1-arch1-1
Clang: 15.0.7 x86_64-pc-linux-gnu
Code
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
char LICENSE[] SEC("license") = "Dual BSD/GPL";
struct trace_event_raw_sys_enter {
short unsigned int type;
unsigned char flags;
unsigned char preempt_count;
int pid;
int __syscall_nr;
long unsigned int args[6];
char __data[0];
};
struct {
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
__uint(max_entries, 1);
__type(key, unsigned int);
__type(value, char [4096]);
} map SEC(".maps");
SEC("tracepoint/syscalls/sys_enter_execve")
int tracepoint__syscalls__sys_enter_execve(struct trace_event_raw_sys_enter *ctx)
{
int key = 0 ;
char *buf = (char *)bpf_map_lookup_elem(&map, &key); // get ptr of inner buffer
if (buf == 0)
return 0;
char *ptr_name = (char *)ctx->args[0];
char **argv = (char **)ctx->args[1];
char *ptr_argv0;
bpf_probe_read(&ptr_argv0, sizeof(ptr_argv0), argv + 0);
/* read filename into buffer */
unsigned int offset = bpf_probe_read_str(buf, 4096, ptr_name);
/* read argv0 into buffer */
if (offset > 4096 || offset < 0)
return 0;
int len = bpf_probe_read_str(buf + offset, 4096 - offset, ptr_argv0);
bpf_printk("len : %d\n", len);
return 0;
}
compile this code with clang -O2 -g -target bpf -c llvbpf.c -o llvbpf.o
and load this ebpf by sudo bpftool prog load -L -d llvbpf.o
occur error:
29: (bf) r2 = r7 ; R2_w=scalar(id=4,umax=8191,var_off=(0x0; 0x1fff)) R7_w=scalar(id=4,umax=8191,var_off=(0x0; 0x1fff))
30: (85) call bpf_probe_read_str#45
invalid access to map value, value_size=4096 off=0 size=8191
R1 min value is outside of the allowed memory range
Reason
in source code:
int len = bpf_probe_read_str(buf + offset, 4096 - offset, ptr_argv0);
in bytecode:
21: bf 01 00 00 00 00 00 00 r1 = r0
22: 67 01 00 00 20 00 00 00 r1 <<= 32
23: 77 01 00 00 20 00 00 00 r1 >>= 32
24: 25 01 0b 00 00 10 00 00 if r1 > 4096 goto +11 <LBB0_3>
25: 1f 07 00 00 00 00 00 00 r7 -= r0 // 4096 - offset
26: 0f 16 00 00 00 00 00 00 r6 += r1 // buf + offset
27: 79 a3 f0 ff 00 00 00 00 r3 = *(u64 *)(r10 - 16)
28: bf 61 00 00 00 00 00 00 r1 = r6
29: bf 72 00 00 00 00 00 00 r2 = r7
30: 85 00 00 00 2d 00 00 00 call 45
on line 25, offset is r0
, there is no scope constraint after the if judgment, on line 26, offset is r1
is correct
so, the correct line 25 should be: r7 -= r1
Problem
So, why does this problem occur when Clang compiles ebpf?