* 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).