Skip to content

Commit 5254874

Browse files
committed
packet04-tailgrow: add xdp_prog_kern2.c with more attempts
Still trying to find smarter ways to access data_end. Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
1 parent 4e2fcc8 commit 5254874

2 files changed

Lines changed: 185 additions & 1 deletion

File tree

packet04-tailgrow/Makefile

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

3-
XDP_TARGETS := xdp_prog_kern
3+
XDP_TARGETS := xdp_prog_kern xdp_prog_kern2
44
# USER_TARGETS :=
55

66
LIBBPF_DIR = ../libbpf/src/

packet04-tailgrow/xdp_prog_kern2.c

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#include <linux/bpf.h>
3+
#include <linux/in.h>
4+
#include <bpf/bpf_helpers.h>
5+
#include <bpf/bpf_endian.h>
6+
7+
// The parsing helper functions from the packet01 lesson have moved here
8+
#include "../common/parsing_helpers.h"
9+
#include "../common/rewrite_helpers.h"
10+
11+
/* Defines xdp_stats_map */
12+
#include "../common/xdp_stats_kern_user.h"
13+
#include "../common/xdp_stats_kern.h"
14+
15+
#define MTU 1536
16+
#define MIN_LEN 64
17+
18+
SEC("xdp_test1b")
19+
int _xdp_test1b(struct xdp_md *ctx)
20+
{
21+
void *data_end = (void *)(long)ctx->data_end;
22+
void *data = (void *)(long)ctx->data;
23+
unsigned char *ptr;
24+
unsigned int i;
25+
void *pos;
26+
27+
unsigned int offset = MIN_LEN;
28+
29+
pos = data;
30+
31+
/* Verifier can handle this bounded basic-loop construct */
32+
for (i = 0; i < (MTU - MIN_LEN); i++ ) {
33+
if (pos + offset > data_end) {
34+
/* Promise verifier no access beyond data_end */
35+
goto out;
36+
}
37+
if (pos + offset == data_end) {
38+
/* Found data_end, exit for-loop and read data.
39+
*
40+
* It seems strange, that finding data_end via
41+
* moving pos (data) pointer forward is needed.
42+
* This is because pointer arithmetic on pkt_end is
43+
* prohibited by verifer.
44+
*
45+
* In principle data_end points to byte that is not
46+
* accessible. Thus, accessing last readable byte
47+
* via (data_end - 1) is prohibited by verifer.
48+
*/
49+
goto read;
50+
}
51+
offset++;
52+
}
53+
/* Show verifier all other cases exit program */
54+
goto out;
55+
56+
read:
57+
// ptr = pos + (offset - );
58+
// ptr = pos + (offset - sizeof(*ptr) - 1);
59+
ptr = pos + (offset - sizeof(*ptr));
60+
if (*ptr == 0xFF)
61+
return XDP_ABORTED;
62+
out:
63+
return XDP_PASS;
64+
}
65+
66+
67+
SEC("xdp_test1")
68+
int _xdp_test1(struct xdp_md *ctx)
69+
{
70+
void *data_end = (void *)(long)ctx->data_end;
71+
void *data = (void *)(long)ctx->data;
72+
unsigned char *ptr;
73+
unsigned int i;
74+
void *pos;
75+
76+
unsigned int offset = 64;
77+
78+
pos = data;
79+
80+
if (pos + 64 > data_end)
81+
goto out;
82+
83+
for (i = 0; i < (1536-64); i++ ) {
84+
if (pos + offset > data_end) {
85+
goto out;
86+
}
87+
if (pos + offset == data_end) {
88+
goto read;
89+
}
90+
offset++;
91+
}
92+
goto out;
93+
94+
read:
95+
// ptr = pos + (offset - );
96+
// ptr = pos + (offset - sizeof(*ptr) - 1);
97+
ptr = pos + (offset - sizeof(*ptr));
98+
if (*ptr == 0xFF)
99+
return XDP_ABORTED;
100+
out:
101+
return XDP_PASS;
102+
}
103+
104+
105+
SEC("xdp_test2")
106+
int _xdp_test2(struct xdp_md *ctx)
107+
{
108+
void *data_end = (void *)(long)ctx->data_end;
109+
void *data = (void *)(long)ctx->data;
110+
struct hdr_cursor nh;
111+
unsigned char *ptr;
112+
113+
unsigned int offset = 64;
114+
115+
nh.pos = data;
116+
117+
if (nh.pos + offset > data_end)
118+
goto out;
119+
120+
// ptr = nh.pos + (offset - 1);
121+
ptr = nh.pos + (offset - sizeof(*ptr));
122+
if (*ptr == 0xFF)
123+
return XDP_ABORTED;
124+
out:
125+
return xdp_stats_record_action(ctx, XDP_PASS);
126+
}
127+
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+
155+
/* Also invalid
156+
SEC("xdp_test4")
157+
int _xdp_test4(struct xdp_md *ctx)
158+
{
159+
void *data_end = (void *)(long)ctx->data_end;
160+
volatile unsigned char *ptr;
161+
volatile void *pos;
162+
163+
pos = data_end;
164+
165+
#pragma clang optimize off
166+
if (pos - 1 > data_end)
167+
goto out;
168+
169+
ptr = pos - 2; //Err: "pointer arithmetic on pkt_end prohibited"
170+
if (*ptr == 0xFF)
171+
return XDP_ABORTED;
172+
#pragma clang optimize on
173+
out:
174+
return XDP_PASS;
175+
}
176+
*/
177+
178+
179+
SEC("xdp_pass")
180+
int xdp_pass_f1(struct xdp_md *ctx)
181+
{
182+
return xdp_stats_record_action(ctx, XDP_PASS);
183+
}
184+

0 commit comments

Comments
 (0)