Skip to content

Commit a617989

Browse files
committed
packet04-tailgrow: make verifier happy
It is rather difficult to make the BPF verifier accept accessing the end-of-packet area. This code is very fragile, and the slightest change will make verifier reject this code again. Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
1 parent 07ef7a4 commit a617989

1 file changed

Lines changed: 25 additions & 9 deletions

File tree

packet04-tailgrow/xdp_prog_kern.c

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,14 @@ int xdp_tailgrow3(struct xdp_md *ctx)
163163
return xdp_stats_record_action(ctx, XDP_PASS);
164164
}
165165

166+
167+
#define compiler_barrier() __asm__ __volatile__("": : :"memory")
168+
166169
SEC("xdp_tailgrow_parse")
167170
int grow_parse(struct xdp_md *ctx)
168171
{
169-
void *data_end = (void *)(long)ctx->data_end;
170-
void *data = (void *)(long)ctx->data;
172+
void *data_end; // = (void *)(long)ctx->data_end;
173+
void *data; // = (void *)(long)ctx->data;
171174

172175
int action = XDP_PASS;
173176
int eth_type, ip_type;
@@ -179,10 +182,12 @@ int grow_parse(struct xdp_md *ctx)
179182

180183
struct my_timestamp *ts;
181184

182-
int offset = sizeof(*ts);
185+
/* Increase packet size and reload data pointers */
186+
__u8 offset = sizeof(*ts);
183187
bpf_xdp_adjust_tail(ctx, offset);
184188
data_end = (void *)(long)ctx->data_end;
185189
data = (void *)(long)ctx->data;
190+
// compiler_barrier();
186191

187192
/* These keep track of the next header type and iterator pointer */
188193
nh.pos = data;
@@ -205,18 +210,29 @@ int grow_parse(struct xdp_md *ctx)
205210
/* Packet size in bytes, including IP header and data */
206211
ip_tot_len = bpf_ntohs(iphdr->tot_len);
207212

208-
// ip_tot_len &= 0xFFF; /* Max 4095 - not allowed by verifier*/
209-
ip_tot_len &= 0xFF; /* Max 255 - allowed by verifier */
213+
/*
214+
* Tricks to get pass the verifier. Being allowed to use
215+
* packet value iphdr->tot_len, involves bounding possible
216+
* values to please verifier.
217+
*/
218+
if (ip_tot_len < 2) {
219+
/* This check seems strange on unsigned ip_tot_len,
220+
* but is needed, else verifier complains:
221+
* "unbounded min value is not allowed"
222+
*/
223+
goto out;
224+
}
225+
ip_tot_len &= 0xFFF; /* Max 4095 */
210226

211-
/* Finding end of packet + offset */
227+
/* Finding end of packet + offset, and bound access */
212228
if ((void *)iphdr + ip_tot_len + offset > data_end) {
213229
action = XDP_ABORTED;
214230
goto out;
215231
}
232+
233+
/* Point ts to end-of-packet, that have been offset extended */
216234
ts = (void *)iphdr + ip_tot_len;
217-
//ts = nh.pos + ip_tot_len - sizeof(*ts);
218-
//ts = nh.pos + ip_tot_len;
219-
ts->magic = 0x5354; // String "TS" in network-byte-order
235+
ts->magic = 0x5354; /* String "TS" in network-byte-order */
220236
ts->time = bpf_ktime_get_ns();
221237
}
222238
out:

0 commit comments

Comments
 (0)