All of lore.kernel.org
 help / color / mirror / Atom feed
* XDP invalid mem access
@ 2022-04-16 11:36 ctxspi
  0 siblings, 0 replies; only message in thread
From: ctxspi @ 2022-04-16 11:36 UTC (permalink / raw)
  To: xdp-newbies

Hi

On my virtual machine with kernel: Linux host.mydomain.cxm 5.16.9-1.el8.elrepo.x86_64 #1 SMP PREEMPT Thu Feb 10 10:45:17 EST 2022 x86_64 x86_64 x86_64 GNU/Linux

I'am trying to add vlan support ETH_P_8021Q, but when I load this code on interface:

static __always_inline int mienro_process_packet(struct xdp_md *ctx, u32 flags)
{
	const __u32 ifingress = ctx->ingress_ifindex;
	void *data_end = (void *)(long)ctx->data_end;
	void *data = (void *)(long)ctx->data;
	struct bpf_fib_lookup fib_params;
	struct ipv6hdr *ip6h = NULL;
	struct iphdr *iph = NULL;
	u16 h_proto = 0;
	u64 nh_off = 0;
	int rc;

	if (data + sizeof(struct ethhdr) > data_end)
		return XDP_DROP;

	if (((struct ethhdr *)data)->h_proto == htons(ETH_P_8021Q))
	{
		nh_off = sizeof(struct vlan_ethhdr);

		if (data + sizeof(struct vlan_ethhdr) > data_end)
			return XDP_DROP;

		h_proto = ((struct vlan_ethhdr *)data)->h_vlan_encapsulated_proto;
	}
	else
	{
		nh_off = sizeof(struct ethhdr); // layer 2 header length
		h_proto = ((struct ethhdr *)data)->h_proto;
	}

	if (data + nh_off > data_end)
		return XDP_DROP;

	if (h_proto == htons(ETH_P_IP))
	{
		iph = data + nh_off;

		if (iph + 1 > data_end)
			return XDP_DROP;

		__builtin_memset(&fib_params, 0, sizeof(fib_params));
		fib_params.ifindex = ctx->ingress_ifindex;
		fib_params.family	= AF_INET;
		fib_params.tos		= iph->tos;
		fib_params.l4_protocol	= iph->protocol;
		fib_params.sport	= 0;
		fib_params.dport	= 0;
		fib_params.tot_len	= ntohs(iph->tot_len);
		fib_params.ipv4_src	= iph->saddr;
		fib_params.ipv4_dst	= iph->daddr;
	}
	else if (h_proto == htons(ETH_P_IPV6))
	{
		ip6h = data + nh_off;

		if (ip6h + 1 > data_end)
			return XDP_DROP;

		__builtin_memset(&fib_params, 0, sizeof(fib_params));
		fib_params.ifindex = ctx->ingress_ifindex;
		fib_params.family				= AF_INET6;
		fib_params.flowinfo				= *(__be32 *)ip6h & IPV6_FLOWINFO_MASK;
		fib_params.l4_protocol			= ip6h->nexthdr;
		fib_params.sport				= 0;
		fib_params.dport				= 0;
		fib_params.tot_len				= ntohs(ip6h->payload_len);
		*((struct in6_addr *)fib_params.ipv6_src)	= ip6h->saddr;
		*((struct in6_addr *)fib_params.ipv6_dst)	= ip6h->daddr;
	}
	else
		return XDP_DROP;

	rc = bpf_fib_lookup(ctx, &fib_params, sizeof(fib_params), flags);

	if (rc == BPF_FIB_LKUP_RET_SUCCESS)
	{
		if (h_proto == htons(ETH_P_IP))
		{
			if (iph->protocol == IPPROTO_TCP)
				return XDP_PASS;

			return XDP_DROP;
		}
		else if (h_proto == htons(ETH_P_IPV6))
		{
			if (ip6h && ip6h->nexthdr == IPPROTO_TCP)
				return XDP_PASS;

			return XDP_DROP;
		}

		return XDP_DROP;
	}
	else if (rc == BPF_FIB_LKUP_RET_NOT_FWDED)
	{
		if (h_proto   == htons(ETH_P_IP))
		{
			if (iph->protocol == IPPROTO_TCP)
				return XDP_PASS;

			return XDP_DROP;
		}
		else if (h_proto == htons(ETH_P_IPV6))
		{
			if (ip6h && ip6h->nexthdr == IPPROTO_TCP)
				return XDP_PASS;

			return XDP_DROP;
		}

		return XDP_DROP;
	}

	return XDP_DROP;
}

SEC("mienro_lan") int mienro_lan_prog(struct xdp_md *ctx)
{
	return mienro_process_packet(ctx, 0);
}

SEC("mienro_lan_direct") int mienro_lan_direct_prog(struct xdp_md *ctx)
{
	return mienro_process_packet(ctx, BPF_FIB_LOOKUP_DIRECT);
}

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


... libbpf return me a good: R6 invalid mem access 'inv'.

Where I'am wrong, I'am missing some validation?
I intentionally preferred to use XDP_PASS everywhere just to simplify the code.

Also I would be curious to understand what the last two lines between these four indicate above all.

libbpf: elf: skipping unrecognized data section(19) .eh_frame
libbpf: elf: skipping relo section(20) .rel.eh_frame for section(19)
libbpf: load bpf program failed: Permission denied
btf_vmlinux is malformed

Thanks

Marco



================================================================================================================

libbpf: elf: skipping unrecognized data section(19) .eh_frame
libbpf: elf: skipping relo section(20) .rel.eh_frame for section(19)
.eh_frame
libbpf: load bpf program failed: Permission denied
libbpf: -- BEGIN DUMP LOG ---
libbpf:
btf_vmlinux is malformed
R1 type=ctx expected=fp
; SEC("mienro_lan") int mienro_lan_prog(struct xdp_md *ctx)
0: (b7) r0 = 1
; void *data_end = (void *)(long)ctx->data_end;
1: (61) r2 = *(u32 *)(r1 +4)
; void *data = (void *)(long)ctx->data;
2: (61) r6 = *(u32 *)(r1 +0)
; if (data + sizeof(struct ethhdr) > data_end)
3: (bf) r3 = r6
4: (07) r3 += 14
; if (data + sizeof(struct ethhdr) > data_end)
5: (2d) if r3 > r2 goto pc+139
 R0_w=inv1 R1=ctx(id=0,off=0,imm=0) R2_w=pkt_end(id=0,off=0,imm=0)
R3_w=pkt(id=0,off=14,r=14,imm=0) R6_w=pkt(id=0,off=0,r=14,imm=0) R10=fp0
; if (((struct ethhdr *)data)->h_proto == htons(ETH_P_8021Q))
6: (71) r3 = *(u8 *)(r6 +12)
7: (71) r7 = *(u8 *)(r6 +13)
8: (67) r7 <<= 8
9: (4f) r7 |= r3
10: (b7) r3 = 14
; if (((struct ethhdr *)data)->h_proto == htons(ETH_P_8021Q))
11: (55) if r7 != 0x81 goto pc+6
 R0_w=inv1 R1=ctx(id=0,off=0,imm=0) R2_w=pkt_end(id=0,off=0,imm=0)
R3_w=inv14 R6_w=pkt(id=0,off=0,r=14,imm=0) R7_w=inv129 R10=fp0
; if (data + sizeof(struct vlan_ethhdr) > data_end)
12: (bf) r3 = r6
13: (07) r3 += 18
;
14: (b7) r0 = 1
; if (data + sizeof(struct vlan_ethhdr) > data_end)
15: (2d) if r3 > r2 goto pc+129
 R0=inv1 R1=ctx(id=0,off=0,imm=0) R2=pkt_end(id=0,off=0,imm=0)
R3=pkt(id=0,off=18,r=18,imm=0) R6=pkt(id=0,off=0,r=18,imm=0) R7=inv129
R10=fp0
16: (b7) r3 = 18
; h_proto = ((struct vlan_ethhdr *)data)->h_vlan_encapsulated_proto;
17: (69) r7 = *(u16 *)(r6 +16)
; if (data + nh_off > data_end)
18: (0f) r6 += r3
last_idx 18 first_idx 15
regs=8 stack=0 before 17: (69) r7 = *(u16 *)(r6 +16)
regs=8 stack=0 before 16: (b7) r3 = 18
;
19: (b7) r0 = 1
; if (data + nh_off > data_end)
20: (2d) if r6 > r2 goto pc+124
 R0_w=inv1 R1=ctx(id=0,off=0,imm=0) R2=pkt_end(id=0,off=0,imm=0)
R3_w=invP18 R6_w=pkt(id=0,off=18,r=18,imm=0)
R7_w=inv(id=0,umax_value=65535,var_off=(0x0; 0xffff)) R10=fp0
; if (h_proto == htons(ETH_P_IP))
21: (bf) r3 = r7
22: (57) r3 &= 65535
; if (h_proto == htons(ETH_P_IP))
23: (55) if r3 != 0x8 goto pc+31

from 23 to 55: R0=inv1 R1=ctx(id=0,off=0,imm=0)
R2=pkt_end(id=0,off=0,imm=0) R3=inv(id=0,umax_value=65535,var_off=(0x0;
0xffff)) R6=pkt(id=0,off=18,r=18,imm=0)
R7=inv(id=1,umax_value=65535,var_off=(0x0; 0xffff)) R10=fp0
;
55: (b7) r0 = 1
; else if (h_proto == htons(ETH_P_IPV6))
56: (55) if r3 != 0xdd86 goto pc+88
 R0=inv1 R1=ctx(id=0,off=0,imm=0) R2=pkt_end(id=0,off=0,imm=0) R3=inv56710
R6=pkt(id=0,off=18,r=18,imm=0) R7=inv(id=1,umax_value=65535,var_off=(0x0;
0xffff)) R10=fp0
; if (ip6h + 1 > data_end)
57: (bf) r3 = r6
58: (07) r3 += 40
;
59: (b7) r0 = 1
; if (ip6h + 1 > data_end)
60: (2d) if r3 > r2 goto pc+84
 R0_w=inv1 R1=ctx(id=0,off=0,imm=0) R2=pkt_end(id=0,off=0,imm=0)
R3_w=pkt(id=0,off=58,r=58,imm=0) R6=pkt(id=0,off=18,r=58,imm=0)
R7=inv(id=1,umax_value=65535,var_off=(0x0; 0xffff)) R10=fp0
61: (b7) r2 = 0
; __builtin_memset(&fib_params, 0, sizeof(fib_params));
62: (7b) *(u64 *)(r10 -8) = r2
last_idx 62 first_idx 56
regs=4 stack=0 before 61: (b7) r2 = 0
63: (7b) *(u64 *)(r10 -16) = r2
64: (7b) *(u64 *)(r10 -24) = r2
65: (7b) *(u64 *)(r10 -32) = r2
66: (7b) *(u64 *)(r10 -40) = r2
67: (7b) *(u64 *)(r10 -48) = r2
68: (7b) *(u64 *)(r10 -56) = r2
69: (7b) *(u64 *)(r10 -64) = r2
; fib_params.ifindex = ctx->ingress_ifindex;
70: (61) r3 = *(u32 *)(r1 +12)
71: (b7) r4 = 10
; fib_params.family = AF_INET6;
72: (73) *(u8 *)(r10 -64) = r4
; fib_params.ifindex = ctx->ingress_ifindex;
73: (63) *(u32 *)(r10 -56) = r3
; fib_params.flowinfo = *(__be32 *)ip6h & IPV6_FLOWINFO_MASK;
74: (61) r3 = *(u32 *)(r6 +0)
75: (18) r4 = 0xffffff0f
; fib_params.flowinfo = *(__be32 *)ip6h & IPV6_FLOWINFO_MASK;
77: (5f) r3 &= r4
; fib_params.flowinfo = *(__be32 *)ip6h & IPV6_FLOWINFO_MASK;
78: (63) *(u32 *)(r10 -52) = r3
; fib_params.l4_protocol = ip6h->nexthdr;
79: (71) r3 = *(u8 *)(r6 +6)
; fib_params.l4_protocol = ip6h->nexthdr;
80: (73) *(u8 *)(r10 -63) = r3
; fib_params.dport = 0;
81: (6b) *(u16 *)(r10 -60) = r2
; fib_params.sport = 0;
82: (6b) *(u16 *)(r10 -62) = r2
; fib_params.tot_len = ntohs(ip6h->payload_len);
83: (69) r2 = *(u16 *)(r6 +4)
84: (dc) r2 = be16 r2
; fib_params.tot_len = ntohs(ip6h->payload_len);
85: (6b) *(u16 *)(r10 -58) = r2
; *((struct in6_addr *)fib_params.ipv6_src) = ip6h->saddr;
86: (61) r2 = *(u32 *)(r6 +12)
87: (67) r2 <<= 32
88: (61) r3 = *(u32 *)(r6 +8)
89: (4f) r2 |= r3
90: (7b) *(u64 *)(r10 -48) = r2
91: (61) r2 = *(u32 *)(r6 +20)
92: (67) r2 <<= 32
93: (61) r3 = *(u32 *)(r6 +16)
94: (4f) r2 |= r3
95: (7b) *(u64 *)(r10 -40) = r2
; *((struct in6_addr *)fib_params.ipv6_dst) = ip6h->daddr;
96: (61) r2 = *(u32 *)(r6 +36)
97: (67) r2 <<= 32
98: (61) r3 = *(u32 *)(r6 +32)
99: (4f) r2 |= r3
100: (7b) *(u64 *)(r10 -24) = r2
101: (61) r2 = *(u32 *)(r6 +28)
102: (67) r2 <<= 32
103: (61) r3 = *(u32 *)(r6 +24)
104: (4f) r2 |= r3
105: (7b) *(u64 *)(r10 -32) = r2
;
106: (bf) r8 = r6
107: (b7) r6 = 0
108: (bf) r2 = r10
109: (07) r2 += -64
; rc = bpf_fib_lookup(ctx, &fib_params, sizeof(fib_params), flags);
110: (b7) r3 = 64
111: (b7) r4 = 0
112: (85) call bpf_fib_lookup#69
last_idx 112 first_idx 108
regs=8 stack=0 before 111: (b7) r4 = 0
regs=8 stack=0 before 110: (b7) r3 = 64
113: (bf) r1 = r0
114: (67) r1 <<= 32
115: (77) r1 >>= 32
; if (rc == BPF_FIB_LKUP_RET_SUCCESS) // FORWARD_SECTION
116: (15) if r1 == 0x4 goto pc+8
 R0_w=inv(id=3) R1_w=inv(id=0,umax_value=4294967295,var_off=(0x0;
0xffffffff)) R6=inv0 R7=inv(id=1,umax_value=65535,var_off=(0x0; 0xffff))
R8=pkt(id=0,off=18,r=58,imm=0) R10=fp0 fp-8=mmmmmmmm fp-16=mmmmmmmm
fp-24=mmmmmmmm fp-32=mmmmmmmm fp-40=mmmmmmmm fp-48=mmmmmmmm fp-56=mmmmmmmm
fp-64=mmmmmmmm
;
117: (b7) r0 = 1
; if (rc == BPF_FIB_LKUP_RET_SUCCESS) // FORWARD_SECTION
118: (55) if r1 != 0x0 goto pc+26
 R0=inv1 R1=inv0 R6=inv0 R7=inv(id=1,umax_value=65535,var_off=(0x0;
0xffff)) R8=pkt(id=0,off=18,r=58,imm=0) R10=fp0 fp-8=mmmmmmmm
fp-16=mmmmmmmm fp-24=mmmmmmmm fp-32=mmmmmmmm fp-40=mmmmmmmm fp-48=mmmmmmmm
fp-56=mmmmmmmm fp-64=mmmmmmmm
; if (h_proto == htons(ETH_P_IP))
119: (57) r7 &= 65535
; if (h_proto == htons(ETH_P_IP))
120: (55) if r7 != 0x8 goto pc+10
 R0=inv1 R1=inv0 R6=inv0 R7_w=inv8 R8=pkt(id=0,off=18,r=58,imm=0) R10=fp0
fp-8=mmmmmmmm fp-16=mmmmmmmm fp-24=mmmmmmmm fp-32=mmmmmmmm fp-40=mmmmmmmm
fp-48=mmmmmmmm fp-56=mmmmmmmm fp-64=mmmmmmmm
; if (iph->protocol == IPPROTO_TCP)
121: (71) r1 = *(u8 *)(r6 +9)
R6 invalid mem access 'inv'
processed 165 insns (limit 1000000) max_states_per_insn 1 total_states 10
peak_states 10 mark_read 3

libbpf: -- END LOG --

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-04-16 11:32 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-04-16 11:36 XDP invalid mem access ctxspi

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.