Skip to content

Commit 54c4d33

Browse files
committed
experiment01-tailgrow: add example that fail xdp_prog_fail1.c
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
1 parent ffc979d commit 54c4d33

4 files changed

Lines changed: 63 additions & 27 deletions

File tree

experiment01-tailgrow/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
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_fail1
5+
46
# USER_TARGETS :=
57

68
LIBBPF_DIR = ../libbpf/src/

experiment01-tailgrow/README.org

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,18 @@ the overhead when doing =XDP_TX=. Selecting others BPF programs via
3535
sudo ./xdp_loader --dev mlx5p1 --force --prog xdp_tailgrow
3636
sudo ./xdp_loader --dev mlx5p1 --force --prog xdp_tailgrow_tx
3737
#+end_src
38+
39+
* Methods that fail
40+
41+
Methods for accessing access BPF packet data at XDP =data_end=.
42+
43+
** Fail#1: Using packet length
44+
45+
In example [[file:xdp_prog_fail1.c]], we try to use the packet length
46+
(calculated as =data_end - data=) to access the last byte as an offset
47+
added to =data=. The verifier rejects this, as the dynamic length
48+
calculation cannot be used for static analysis.
49+
50+
#+begin_src sh
51+
sudo ./xdp_loader --dev mlx5p1 --force --file xdp_prog_fail1.o
52+
#+end_src
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+
}

experiment01-tailgrow/xdp_prog_kern2.c

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -125,33 +125,6 @@ int _xdp_test2(struct xdp_md *ctx)
125125
return xdp_stats_record_action(ctx, XDP_PASS);
126126
}
127127

128-
/* Invalid:
129-
SEC("xdp_test3")
130-
int _xdp_test3(struct xdp_md *ctx)
131-
{
132-
void *data_end = (void *)(long)ctx->data_end;
133-
void *data = (void *)(long)ctx->data;
134-
unsigned char *ptr;
135-
void *pos;
136-
137-
unsigned int offset = data_end - data;
138-
139-
if (offset < 2)
140-
goto out;
141-
142-
pos = data;
143-
144-
if (pos + offset > data_end)
145-
goto out;
146-
147-
ptr = pos + (offset - sizeof(*ptr));
148-
if (*ptr == 0xFF)
149-
return XDP_ABORTED;
150-
out:
151-
return XDP_PASS;
152-
}
153-
*/
154-
155128
/* Also invalid
156129
SEC("xdp_test4")
157130
int _xdp_test4(struct xdp_md *ctx)

0 commit comments

Comments
 (0)