lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 21 Apr 2022 17:56:20 +0200
From:   Larysa Zaremba <larysa.zaremba@...el.com>
To:     bpf <bpf@...r.kernel.org>
Cc:     Larysa Zaremba <larysa.zaremba@...el.com>,
        netdev <netdev@...r.kernel.org>,
        Andrii Nakryiko <andrii@...nel.org>,
        Alexei Starovoitov <ast@...nel.org>,
        Daniel Borkmann <daniel@...earbox.net>,
        Jesper Dangaard Brouer <brouer@...hat.com>,
        Toke Hoiland-Jorgensen <toke@...hat.com>,
        Magnus Karlsson <magnus.karlsson@...el.com>,
        Maciej Fijalkowski <maciej.fijalkowski@...el.com>,
        Alexander Lobakin <alexandr.lobakin@...el.com>
Subject: Accessing XDP packet memory from the end

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;

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ