Basically I want to read bytes from the array map via index and offset, but I get invalid access to map value
even though I have performed bounds checking
I really have no idea what's going wrong, may be related to an overflow risk?
Any comments are appreciated, thanks!
Here's the code:
struct bpf_elf_map __section("maps") data_store = {
.type = BPF_MAP_TYPE_ARRAY,
.size_key = sizeof(__u32),
.size_value = 1024,
.max_elem = 4096,
.pinning = PIN_GLOBAL_NS,
};
static __always_inline void read_data(__u32 idx, __u32 offset, void *dst,
__u32 size) {
if (size > 512 || offset >= 1024) {
// for the ebpf verifier
return;
}
void *b = bpf_map_lookup_elem(&data_store, &idx);
if (!b) {
// shouldn't happen
return;
}
if (offset + size <= 1024) {
for (__u32 i = 0; i < size && i < 512; ++i) {
if (offset + i >= 1024) {
return;
}
// !! where the verifier complains
memcpy(dst + i, b + offset + i, sizeof(__u8));
}
} else {
// ...
}
}
verifier log:
; for (__u32 i = 0; i < size && i < 512; ++i) {
197: (25) if r1 > 0x1fe goto pc+8
;
198: (bf) r2 = r1
199: (07) r2 += 1
; for (__u32 i = 0; i < size && i < 512; ++i) {
200: (3d) if r2 >= r8 goto pc+5
R0=map_value(id=0,off=0,ks=4,vs=1024,umax_value=1023,var_off=(0x0; 0x3ff)) R1=invP0 R2_w=invP1 R3_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff)) R6=map_value(id=0,off=0,ks=4,vs=32,imm=0) R7=map_value(id=0,off=0,ks=4,vs=512,imm=0) R8=inv(id=261,umin_value=2,umax_value=512,var_off=(0x0; 0x3ff)) R9=invP(id=0,umin_value=1,umax_value=1024,var_off=(0x0; 0x7ff)) R10=fp0 fp-8=mmmmm??? fp-48=????mmmm
201: (bf) r3 = r9
202: (0f) r3 += r1
203: (bf) r1 = r2
204: (25) if r3 > 0x3ff goto pc+1
R0=map_value(id=0,off=0,ks=4,vs=1024,umax_value=1023,var_off=(0x0; 0x3ff)) R1=invP1 R2=invP1 R3=invP(id=0,umin_value=1,umax_value=1023,var_off=(0x0; 0x3ff)) R6=map_value(id=0,off=0,ks=4,vs=32,imm=0) R7=map_value(id=0,off=0,ks=4,vs=512,imm=0) R8=inv(id=261,umin_value=2,umax_value=512,var_off=(0x0; 0x3ff)) R9=invP(id=263,umin_value=1,umax_value=1024,var_off=(0x0; 0x7ff)) R10=fp0 fp-8=mmmmm??? fp-48=????mmmm
205: (05) goto pc-15
; memcpy(dst + i, b + offset + i, sizeof(__u8));
191: (bf) r2 = r7
192: (0f) r2 += r1
193: (bf) r3 = r0
194: (0f) r3 += r1
195: (71) r3 = *(u8 *)(r3 +0)
R0=map_value(id=0,off=0,ks=4,vs=1024,umax_value=1023,var_off=(0x0; 0x3ff)) R1=invP1 R2_w=map_value(id=0,off=1,ks=4,vs=512,imm=0) R3_w=map_value(id=0,off=1,ks=4,vs=1024,umax_value=1023,var_off=(0x0; 0x3ff)) R6=map_value(id=0,off=0,ks=4,vs=32,imm=0) R7=map_value(id=0,off=0,ks=4,vs=512,imm=0) R8=inv(id=261,umin_value=2,umax_value=512,var_off=(0x0; 0x3ff)) R9=invP(id=263,umin_value=1,umax_value=1024,var_off=(0x0; 0x7ff)) R10=fp0 fp-8=mmmmm??? fp-48=????mmmm
invalid access to map value, value_size=1024 off=1024 size=1
R3 max value is outside of the allowed memory range