[PATCH 1/3] rtnetlink: return EMSGSIZE when first dump entry does not fit
From: Stephen Hemminger
Date: Sun Nov 08 2026 - 20:29:29 EST
If a route entry is too large for the dump skb, the dump is silently
truncated and no error is returned.
For handlers with RTNL_FLAG_DUMP_SPLIT_NLM_DONE, rtnl_dumpit() drops
-EMSGSIZE and returns skb->len. With an empty skb this is 0, so the
dump ends with NLMSG_DONE and status 0, and the remaining entries are
lost.
The first dump skb is allocated from __netlink_dump_start() while
max_recvmsg_len is still 0, so it is only NLMSG_GOODSIZE. On a 4K page
kernel that is under 4000 bytes, and a 500 way multipath route does not
fit:
ip link add dummy0 type dummy
ip link set dummy0 up
ip route add 198.51.100.0/24 table 100 \
$(for i in $(seq 500); do echo -n "nexthop dev dummy0 "; done)
ip route show table 100
The dump prints nothing and exits 0, although "ip route get
198.51.100.1 table 100" still shows the route.
Only ignore -EMSGSIZE when the skb has data, so that an entry which
does not fit in an empty skb reports the error to user space.
Fixes: 5b4b62a169e1 ("rtnetlink: make the "split" NLM_DONE handling generic")
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Stephen Hemminger <stephen@xxxxxxxxxxxxxxxxxx>
---
net/core/rtnetlink.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index e141340172ce..2777796a4ed2 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -7043,7 +7043,10 @@ static int rtnl_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
* Some applications which parse netlink manually depend on this.
*/
if (cb->flags & RTNL_FLAG_DUMP_SPLIT_NLM_DONE) {
- if (err < 0 && err != -EMSGSIZE)
+ /* -EMSGSIZE with nothing in the skb is an error, as returning
+ * a length of 0 would end the dump as if it was complete.
+ */
+ if (err < 0 && (err != -EMSGSIZE || !skb->len))
return err;
if (!err)
cb->data = NULL;
--
2.53.0