rta_addattr_l() copies alen bytes but advances the parent by RTA_ALIGN(len), so the 1-3 padding bytes are never written. This affects every caller that passes an unaligned length. Nests built in stack buffers (lwtunnel encap, RTA_MULTIPATH, RTA_METRICS) then send those bytes to the kernel. For example, in ip nexthop add id 53 encap mpls 101 ttl 10 via 192.0.2.1 dev d0 the three bytes after MPLS_IPTUNNEL_TTL are stack contents: 05 00 02 00 0a 7f 00 00 MPLS_IPTUNNEL_TTL, ttl 10, stack bytes 05 00 02 00 0a 00 00 00 with this patch and valgrind reports "sendmsg(msg.msg_iov[0]) points to uninitialised byte(s)". The kernel skips padding when parsing, so nothing fails, but its own encoder zeroes it (__nla_reserve()), and so does addraw_l() here. Do the same. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Dave Seddon --- v2: - Drop the Fixes: tag; the gap goes back to the initial import (Stephen) - Cite addraw_l() as the precedent - Correct the note on addattr_l() addattr_l() doesn't zero its padding either (07f9436201eb added the memset to addraw_l()), but its callers zero their request first, so it is left alone. I can send that as a separate patch if wanted. v1: https://lore.kernel.org/netdev/20261104052901.2735000-1-dave.seddon.ca@gmail.com/ --- lib/libnetlink.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/libnetlink.c b/lib/libnetlink.c index edf3a8ba..c4a8e694 100644 --- a/lib/libnetlink.c +++ b/lib/libnetlink.c @@ -1502,6 +1502,7 @@ int rta_addattr_l(struct rtattr *rta, int maxlen, int type, subrta->rta_len = len; if (alen) memcpy(RTA_DATA(subrta), data, alen); + memset((void *)subrta + len, 0, RTA_ALIGN(len) - len); rta->rta_len = NLMSG_ALIGN(rta->rta_len) + RTA_ALIGN(len); return 0; } -- 2.56.0