Skip to content

Commit 0bbd18c

Browse files
committed
experiment01-tailgrow: copy xdp_prog_fail1.c to xdp_prog_kern3.c
Trying to follow Daniel's advice and convert xdp_prog_fail1.c to a working edition. Start off with xdp_prog_fail1.c to be able to git follow the changes. Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
1 parent 4a627a5 commit 0bbd18c

2 files changed

Lines changed: 47 additions & 0 deletions

File tree

experiment01-tailgrow/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
22

33
XDP_TARGETS := xdp_prog_kern xdp_prog_kern2
4+
XDP_TARGETS += xdp_prog_kern3
45
XDP_TARGETS += xdp_prog_fail1
56
XDP_TARGETS += xdp_prog_fail2
67

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#include <linux/bpf.h>
3+
#include <bpf/bpf_helpers.h>
4+
5+
/*
6+
* This BPF-prog will FAIL, due to verifier rejecting it.
7+
*
8+
* General idea: Use packet length to find and access last byte in
9+
* packet. The verifier cannot see this is safe, as it cannot deduce
10+
* the packet length at verification time.
11+
*/
12+
13+
SEC("xdp_fail1")
14+
int _xdp_fail1(struct xdp_md *ctx)
15+
{
16+
void *data_end = (void *)(long)ctx->data_end;
17+
void *data = (void *)(long)ctx->data;
18+
unsigned char *ptr;
19+
void *pos;
20+
21+
/* (Correct me if I'm wrong)
22+
*
23+
* The verifier cannot use this packet length calculation as
24+
* part of its static analysis. It chooses to use zero as the
25+
* offset value static value.
26+
*/
27+
unsigned int offset = data_end - data;
28+
29+
pos = data;
30+
31+
if (pos + offset > data_end)
32+
goto out;
33+
34+
/* Fails at this line with:
35+
* "invalid access to packet, off=-1 size=1, R1(id=2,off=0,r=0)"
36+
* "R1 offset is outside of the packet"
37+
*
38+
* Because verifer used offset==0 it thinks that we are trying
39+
* to access (data - 1), which is not within [data,data_end)
40+
*/
41+
ptr = pos + (offset - sizeof(*ptr));
42+
if (*ptr == 0xFF)
43+
return XDP_ABORTED;
44+
out:
45+
return XDP_PASS;
46+
}

0 commit comments

Comments
 (0)