bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Accessing XDP packet memory from the end
@ 2022-04-21 15:56 Larysa Zaremba
  2022-04-21 16:27 ` Jesper Dangaard Brouer
  2022-04-21 17:17 ` Toke Høiland-Jørgensen
  0 siblings, 2 replies; 6+ messages in thread
From: Larysa Zaremba @ 2022-04-21 15:56 UTC (permalink / raw)
  To: bpf
  Cc: Larysa Zaremba, netdev, Andrii Nakryiko, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, Toke Hoiland-Jorgensen,
	Magnus Karlsson, Maciej Fijalkowski, Alexander Lobakin

Dear all,
Our team has encountered a need of accessing data_meta in a following way:

int xdp_meta_prog(struct xdp_md *ctx)
{
	void *data_meta_ptr = (void *)(long)ctx->data_meta;
	void *data_end = (void *)(long)ctx->data_end;
	void *data = (void *)(long)ctx->data;
	u64 data_size = sizeof(u32);
	u32 magic_meta;
	u8 offset;

	offset = (u8)((s64)data - (s64)data_meta_ptr);
	if (offset < data_size) {
		bpf_printk("invalid offset: %ld\n", offset);
		return XDP_DROP;
	}

	data_meta_ptr += offset;
	data_meta_ptr -= data_size;

	if (data_meta_ptr + data_size > data) {
		return XDP_DROP;
	}
		
	magic_meta = *((u32 *)data);
	bpf_printk("Magic: %d\n", magic_meta);
	return XDP_PASS;
}

Unfortunately, verifier claims this code attempts to access packet with
an offset of -2 (a constant part) and negative offset is generally forbidden.

For now we have 2 solutions, one is using bpf_xdp_adjust_meta(),
which is pretty good, but not ideal for the hot path.
The second one is the patch at the end.

Do you see any other way of accessing memory from the end of data_meta/data?
What do you think about both suggested solutions?

Best regards,
Larysa Zaremba

---

--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -3576,8 +3576,11 @@ static int check_packet_access(struct bpf_verifier_env *env, u32 regno, int off,
 	}
 
 	err = reg->range < 0 ? -EINVAL :
-	      __check_mem_access(env, regno, off, size, reg->range,
-				 zero_size_allowed);
+	      __check_mem_access(env, regno, off + reg->smin_value, size,
+				 reg->range + reg->smin_value, zero_size_allowed);
+	err = err ? :
+	      __check_mem_access(env, regno, off + reg->umax_value, size,
+				 reg->range + reg->umax_value, zero_size_allowed);
 	if (err) {
 		verbose(env, "R%d offset is outside of the packet\n", regno);
 		return err;

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-04-23 20:05 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-21 15:56 Accessing XDP packet memory from the end Larysa Zaremba
2022-04-21 16:27 ` Jesper Dangaard Brouer
2022-04-22 10:06   ` Alexander Lobakin
2022-04-21 17:17 ` Toke Høiland-Jørgensen
2022-04-22 16:41   ` Alexander Lobakin
2022-04-23 20:05     ` Toke Høiland-Jørgensen

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).