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]
Message-Id: <20211209120327.551952-1-emmanuel.deloget@eho.link>
Date:   Thu,  9 Dec 2021 13:03:27 +0100
From:   Emmanuel Deloget <emmanuel.deloget@....link>
To:     Björn Töpel <bjorn@...nel.org>,
        Magnus Karlsson <magnus.karlsson@...el.com>,
        Jonathan Lemon <jonathan.lemon@...il.com>,
        Alexei Starovoitov <ast@...nel.org>,
        Daniel Borkmann <daniel@...earbox.net>,
        Andrii Nakryiko <andrii@...nel.org>,
        Martin KaFai Lau <kafai@...com>,
        Song Liu <songliubraving@...com>, Yonghong Song <yhs@...com>,
        John Fastabend <john.fastabend@...il.com>,
        KP Singh <kpsingh@...nel.org>
Cc:     Emmanuel Deloget <emmanuel.deloget@....link>,
        netdev@...r.kernel.org, bpf@...r.kernel.org,
        linux-kernel@...r.kernel.org
Subject: [PATCH v1 bpf 1/1] libbpf: don't force user-supplied ifname string to be of fixed size

When calling either xsk_socket__create_shared() or xsk_socket__create()
the user supplies a const char *ifname which is implicitely supposed to
be a pointer to the start of a char[IFNAMSIZ] array. The internal
function xsk_create_ctx() then blindly copy IFNAMSIZ bytes from this
string into the xsk context.

This is counter-intuitive and error-prone.

For example,

        int r = xsk_socket__create(..., "eth0", ...)

may result in an invalid object because of the blind copy. The "eth0"
string might be followed by random data from the ro data section,
resulting in ctx->ifname being filled with the correct interface name
then a bunch and invalid bytes.

The same kind of issue arises when the ifname string is located on the
stack:

        char ifname[] = "eth0";
        int r = xsk_socket__create(..., ifname, ...);

Or comes from the command line

        const char *ifname = argv[n];
        int r = xsk_socket__create(..., ifname, ...);

In both case we'll fill ctx->ifname with random data from the stack.

In practice, we saw that this issue caused various small errors which,
in then end, prevented us to setup a valid xsk context that would have
allowed us to capture packets on our interfaces. We fixed this issue in
our code by forcing our char ifname[] to be of size IFNAMSIZ but that felt
weird and unnecessary.

Fixes: 2f6324a3937f8 (libbpf: Support shared umems between queues and devices)
Signed-off-by: Emmanuel Deloget <emmanuel.deloget@....link>
---
 tools/lib/bpf/xsk.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/tools/lib/bpf/xsk.c b/tools/lib/bpf/xsk.c
index 81f8fbc85e70..8dda80bcefcc 100644
--- a/tools/lib/bpf/xsk.c
+++ b/tools/lib/bpf/xsk.c
@@ -944,6 +944,7 @@ static struct xsk_ctx *xsk_create_ctx(struct xsk_socket *xsk,
 {
 	struct xsk_ctx *ctx;
 	int err;
+	size_t ifnamlen;
 
 	ctx = calloc(1, sizeof(*ctx));
 	if (!ctx)
@@ -965,8 +966,10 @@ static struct xsk_ctx *xsk_create_ctx(struct xsk_socket *xsk,
 	ctx->refcount = 1;
 	ctx->umem = umem;
 	ctx->queue_id = queue_id;
-	memcpy(ctx->ifname, ifname, IFNAMSIZ - 1);
-	ctx->ifname[IFNAMSIZ - 1] = '\0';
+
+	ifnamlen = strnlen(ifname, IFNAMSIZ);
+	memcpy(ctx->ifname, ifname, ifnamlen);
+	ctx->ifname[IFNAMSIZ - 1] = 0;
 
 	ctx->fill = fill;
 	ctx->comp = comp;
-- 
2.32.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ