[<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