All of lore.kernel.org
 help / color / mirror / Atom feed
* [QUESTION] bpf/tc verifier error: invalid access to map value, min value is outside of the allowed memory range
@ 2023-08-24 20:32 Justin Iurman
  2023-08-26  0:49 ` John Fastabend
  2023-08-28 12:46 ` Eduard Zingerman
  0 siblings, 2 replies; 9+ messages in thread
From: Justin Iurman @ 2023-08-24 20:32 UTC (permalink / raw)
  To: bpf; +Cc: justin.iurman

Hello,

I'm facing a verifier error and don't know how to make it happy (already 
tried lots of checks). First, here is my env:
  - OS: Ubuntu 22.04.3 LTS
  - kernel: 5.15.0-79-generic x86_64 (CONFIG_DEBUG_INFO_BTF=y)
  - clang version: 14.0.0-1ubuntu1.1
  - iproute2-5.15.0 with libbpf 0.5.0

And here is a simplified example of my program (basically, it will 
insert in packets some bytes defined inside a map):

#include "vmlinux.h"
#include <bpf/bpf_endian.h>
#include <bpf/bpf_helpers.h>

#define MAX_BYTES 2048

struct xxx_t {
	__u32 bytes_len;
	__u8 bytes[MAX_BYTES];
};

struct {
	__uint(type, BPF_MAP_TYPE_ARRAY);
	__uint(max_entries, 1);
	__type(key, __u32);
	__type(value, struct xxx_t);
	__uint(pinning, LIBBPF_PIN_BY_NAME);
} my_map SEC(".maps");

char _license[] SEC("license") = "GPL";

SEC("egress")
int egress_handler(struct __sk_buff *skb)
{
	void *data_end = (void *)(long)skb->data_end;
	void *data = (void *)(long)skb->data;
	struct ethhdr *eth = data;
	struct ipv6hdr *ip6;
	struct xxx_t *x;
	__u32 offset;
	__u32 idx = 0;

	offset = sizeof(*eth) + sizeof(*ip6);
	if (data + offset > data_end)
		return TC_ACT_OK;

	if (bpf_ntohs(eth->h_proto) != ETH_P_IPV6)
		return TC_ACT_OK;

	x = bpf_map_lookup_elem(&my_map, &idx);
	if (!x)
		return TC_ACT_OK;

	if (x->bytes_len == 0 || x->bytes_len > MAX_BYTES)
		return TC_ACT_OK;

	if (bpf_skb_adjust_room(skb, x->bytes_len, BPF_ADJ_ROOM_NET, 0))
		return TC_ACT_OK;

	if (bpf_skb_store_bytes(skb, offset, x->bytes, 8/*x->bytes_len*/, 
BPF_F_RECOMPUTE_CSUM))
		return TC_ACT_SHOT;

	/* blah blah blah... */

	return TC_ACT_OK;
}

Let's focus on the line where bpf_skb_store_bytes is called. As is, with 
a constant length (i.e., 8 for instance), the verifier is happy. 
However, as soon as I try to use a map value as the length, it fails:

[...]
; if (bpf_skb_store_bytes(skb, offset, x->bytes, x->bytes_len,
34: (bf) r1 = r7
35: (b7) r2 = 54
36: (bf) r3 = r8
37: (b7) r5 = 1
38: (85) call bpf_skb_store_bytes#9
  R0=inv0 R1_w=ctx(id=0,off=0,imm=0) R2_w=inv54 
R3_w=map_value(id=0,off=4,ks=4,vs=2052,imm=0) 
R4_w=inv(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R5_w=inv1 
R6_w=inv1 R7=ctx(id=0,off=0,imm=0) 
R8_w=map_value(id=0,off=4,ks=4,vs=2052,imm=0) R10=fp0 fp-8=mmmm????
invalid access to map value, value_size=2052 off=4 size=0
R3 min value is outside of the allowed memory range

I guess "size=0" is the problem here, but don't understand why. What 
bothers me is that it looks like it's about R3 (i.e., x->bytes), not R4. 
Anyway, I already tried to add a bunch of checks for both, but did not 
succeed. Any idea?

Thanks,
Justin

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-09-01 11:58 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-08-24 20:32 [QUESTION] bpf/tc verifier error: invalid access to map value, min value is outside of the allowed memory range Justin Iurman
2023-08-26  0:49 ` John Fastabend
2023-08-26 12:54   ` Justin Iurman
2023-08-26 23:13     ` Justin Iurman
2023-08-27 16:56   ` Justin Iurman
2023-08-28 12:46 ` Eduard Zingerman
2023-08-28 13:25   ` Eduard Zingerman
2023-08-29  0:40     ` Yonghong Song
2023-09-01 11:58       ` Justin Iurman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.