[PATCH net-next] devlink: Replace strlcat() with seq_buf
From: Ian Bridges <hidden>
Date: 2026-07-04 03:49:12
Also in:
linux-hardening, lkml
Subsystem:
devlink, networking [general], the rest · Maintainers:
Jiri Pirko, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
In preparation for removing the strlcat() API[1], replace its uses in __devlink_compat_running_version(). The function accumulates a variable number of version strings into a fixed buffer, which is what seq_buf is for. The seq_buf is anchored at the end of any existing string in the buffer and each version string is appended with a single seq_buf_printf(). The output is unchanged, including under truncation. Link: https://github.com/KSPP/linux/issues/370 [1] Signed-off-by: Ian Bridges <redacted> --- The patch was tested as follows, on top of net-next: - x86_64 allmodconfig and allyesconfig builds of net/devlink/dev.o at W=1 produce no warnings. - A userspace comparison of the old and new construction ran with randomized version lists and buffer contents across all buffer fill levels. The outputs are byte-identical in every case, including on overflow. - The changed path was exercised in a QEMU guest through the ethtool GDRVINFO ioctl against a netdevsim device, before and after the change, with identical fw_version output. net/devlink/dev.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/net/devlink/dev.c b/net/devlink/dev.c
index 57b2b8f03543..0d4301267171 100644
--- a/net/devlink/dev.c
+++ b/net/devlink/dev.c@@ -5,6 +5,7 @@ */ #include <linux/device.h> +#include <linux/seq_buf.h> #include <net/genetlink.h> #include <net/sock.h> #include "devl_internal.h"
@@ -1188,8 +1189,10 @@ static void __devlink_compat_running_version(struct devlink *devlink, char *buf, size_t len) { struct devlink_info_req req = {}; + size_t used = strnlen(buf, len); const struct nlattr *nlattr; struct sk_buff *msg; + struct seq_buf sb; int rem, err; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
@@ -1201,6 +1204,8 @@ static void __devlink_compat_running_version(struct devlink *devlink, if (err) goto free_msg; + seq_buf_init(&sb, buf + used, len - used); + nla_for_each_attr_type(nlattr, DEVLINK_ATTR_INFO_VERSION_RUNNING, (void *)msg->data, msg->len, rem) { const struct nlattr *kv;
@@ -1208,8 +1213,8 @@ static void __devlink_compat_running_version(struct devlink *devlink, nla_for_each_nested_type(kv, DEVLINK_ATTR_INFO_VERSION_VALUE, nlattr, rem_kv) { - strlcat(buf, nla_data(kv), len); - strlcat(buf, " ", len); + seq_buf_printf(&sb, "%s ", + (const char *)nla_data(kv)); } } free_msg:
--
2.47.3