From: Stephen Hemminger <stephen@networkplumber.org>
To: netdev@vger.kernel.org
Cc: dsahern@kernel.org,
Stephen Hemminger <stephen@networkplumber.org>,
Florian Fainelli <f.fainelli@gmail.com>
Subject: [PATCH iproute2 1/5] netlink: use a counter for sequence numbers
Date: Sun, 8 Nov 2026 17:43:58 -0800 [thread overview]
Message-ID: <20261109014434.115922-2-stephen@networkplumber.org> (raw)
In-Reply-To: <20261109014434.115922-1-stephen@networkplumber.org>
Seeding the sequence number from time() breaks with a 32-bit time_t
after 2038: time() returns -1, the first request gets sequence zero,
and the range check in __rtnl_talk_iov() underflows, leaving ip
blocked in recvmsg(). The seed adds nothing since replies are already
matched by port id.
Drop the seed so libnetlink starts at 1, make the range check
wrap-safe, and replace the per-message time() in the mnl helpers with
a counter that starts at 1 and skips zero.
Reported-by: Florian Fainelli <f.fainelli@gmail.com>
Reported-by: Anthropic OSS scanner (ANT-2026-E6IHJA62)
Reported-by: Anthropic OSS scanner (ANT-2026-1UC2GBCD)
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
include/mnl_utils.h | 1 +
lib/libnetlink.c | 4 +---
lib/mnl_utils.c | 13 +++++++++++--
rdma/utils.c | 2 +-
4 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/include/mnl_utils.h b/include/mnl_utils.h
index 4df9e398..d809383c 100644
--- a/include/mnl_utils.h
+++ b/include/mnl_utils.h
@@ -25,6 +25,7 @@ int mnlu_gen_socket_sndrcv(struct mnlu_gen_socket *nlg, const struct nlmsghdr *n
struct mnl_socket *mnlu_socket_open(int bus);
int mnl_add_nl_group(struct mnl_socket *nl, unsigned int group);
+uint32_t mnlu_next_seq(void);
struct nlmsghdr *mnlu_msg_prepare(void *buf, uint32_t nlmsg_type, uint16_t flags,
void *extra_header, size_t extra_header_size);
int mnlu_socket_recv_run(struct mnl_socket *nl, unsigned int seq, void *buf, size_t buf_size,
diff --git a/lib/libnetlink.c b/lib/libnetlink.c
index edf3a8ba..6ff9cace 100644
--- a/lib/libnetlink.c
+++ b/lib/libnetlink.c
@@ -15,7 +15,6 @@
#include <netinet/in.h>
#include <string.h>
#include <errno.h>
-#include <time.h>
#include <sys/uio.h>
#include <linux/fib_rules.h>
#include <linux/if_addrlabel.h>
@@ -246,7 +245,6 @@ int rtnl_open_byproto(struct rtnl_handle *rth, unsigned int subscriptions,
rth->local.nl_family);
goto err;
}
- rth->seq = time(NULL);
return 0;
err:
rtnl_close(rth);
@@ -1092,7 +1090,7 @@ next:
if (nladdr.nl_pid != 0 ||
h->nlmsg_pid != rtnl->local.nl_pid ||
- h->nlmsg_seq > seq || h->nlmsg_seq < seq - iovlen) {
+ (unsigned int)(seq - h->nlmsg_seq) >= iovlen) {
/* Don't forget to skip that message. */
status -= NLMSG_ALIGN(len);
h = (struct nlmsghdr *)((char *)h + NLMSG_ALIGN(len));
diff --git a/lib/mnl_utils.c b/lib/mnl_utils.c
index 43b4cd1a..44e54aa8 100644
--- a/lib/mnl_utils.c
+++ b/lib/mnl_utils.c
@@ -5,7 +5,6 @@
#include <errno.h>
#include <string.h>
-#include <time.h>
#include <libmnl/libmnl.h>
#include <linux/genetlink.h>
@@ -40,6 +39,16 @@ int mnl_add_nl_group(struct mnl_socket *nl, unsigned int group)
return mnl_socket_bind(nl, group, MNL_SOCKET_AUTOPID);
}
+/* Sequence number for next request, zero is reserved for kernel events */
+uint32_t mnlu_next_seq(void)
+{
+ static uint32_t seq;
+
+ if (++seq == 0)
+ seq = 1;
+ return seq;
+}
+
struct nlmsghdr *mnlu_msg_prepare(void *buf, uint32_t nlmsg_type, uint16_t flags,
void *extra_header, size_t extra_header_size)
{
@@ -49,7 +58,7 @@ struct nlmsghdr *mnlu_msg_prepare(void *buf, uint32_t nlmsg_type, uint16_t flags
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = nlmsg_type;
nlh->nlmsg_flags = flags;
- nlh->nlmsg_seq = time(NULL);
+ nlh->nlmsg_seq = mnlu_next_seq();
eh = mnl_nlmsg_put_extra_header(nlh, extra_header_size);
memcpy(eh, extra_header, extra_header_size);
diff --git a/rdma/utils.c b/rdma/utils.c
index f6605eef..a85e8422 100644
--- a/rdma/utils.c
+++ b/rdma/utils.c
@@ -685,7 +685,7 @@ int rd_exec_cmd(struct rd *rd, const struct rd_cmd *cmds, const char *str)
void rd_prepare_msg(struct rd *rd, uint32_t cmd, uint32_t *seq, uint16_t flags)
{
- *seq = time(NULL);
+ *seq = mnlu_next_seq();
rd->nlh = mnl_nlmsg_put_header(rd->buff);
rd->nlh->nlmsg_type = RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, cmd);
--
2.53.0
next prev parent reply other threads:[~2026-11-09 1:44 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-09 1:43 [PATCH iproute2 0/5] netlink receive path hardening Stephen Hemminger
2026-11-09 1:43 ` Stephen Hemminger [this message]
2026-11-09 1:43 ` [PATCH iproute2 2/5] netlink: ignore messages not sent by the kernel Stephen Hemminger
2026-11-09 1:44 ` [PATCH iproute2 3/5] netlink: connect sockets to " Stephen Hemminger
2026-11-09 1:44 ` [PATCH iproute2 4/5] netlink: handle unpadded last message in receive loops Stephen Hemminger
2026-11-09 1:44 ` [PATCH iproute2 5/5] libnetlink: do not read past datagram when recording dump Stephen Hemminger
2026-11-11 17:30 ` [PATCH iproute2 0/5] netlink receive path hardening patchwork-bot+netdevbpf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261109014434.115922-2-stephen@networkplumber.org \
--to=stephen@networkplumber.org \
--cc=dsahern@kernel.org \
--cc=f.fainelli@gmail.com \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.