]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
netlink: add a nla_nest_end_safe() helper
authorHangbin Liu <liuhangbin@gmail.com>
Wed, 8 Apr 2026 07:08:52 +0000 (15:08 +0800)
committerJakub Kicinski <kuba@kernel.org>
Sun, 12 Apr 2026 18:23:50 +0000 (11:23 -0700)
The nla_len field in struct nlattr is a __u16, which can only hold
values up to 65535. If a nested attribute grows beyond this limit,
nla_nest_end() silently truncates the length, producing a corrupted
netlink message with no indication of the problem.

Since nla_nest_end() is used everywhere and this issue rarely happens,
let's add a new helper to check the length.

Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Link: https://patch.msgid.link/20260408-b4-ynl_ethtool-v2-4-7623a5e8f70b@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/net/netlink.h

index 1a8356ca4b786fbac95dbfbba4409939d7001dff..546d10586576e7b1c44348ac48762667ebb00f61 100644 (file)
@@ -2264,6 +2264,25 @@ static inline int nla_nest_end(struct sk_buff *skb, struct nlattr *start)
        return skb->len;
 }
 
+/**
+ * nla_nest_end_safe - Validate and finalize nesting of attributes
+ * @skb: socket buffer the attributes are stored in
+ * @start: container attribute
+ *
+ * Corrects the container attribute header to include all appended
+ * attributes.
+ *
+ * Returns: the total data length of the skb, or -EMSGSIZE if the
+ * nested attribute length exceeds U16_MAX.
+ */
+static inline int nla_nest_end_safe(struct sk_buff *skb, struct nlattr *start)
+{
+       if (skb_tail_pointer(skb) - (unsigned char *)start > U16_MAX)
+               return -EMSGSIZE;
+
+       return nla_nest_end(skb, start);
+}
+
 /**
  * nla_nest_cancel - Cancel nesting of attributes
  * @skb: socket buffer the message is stored in