]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: shaper: fix undersized reply skb allocation in GROUP command
authorJakub Kicinski <kuba@kernel.org>
Sun, 10 May 2026 19:29:00 +0000 (12:29 -0700)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 12 May 2026 14:14:59 +0000 (16:14 +0200)
net_shaper_group_send_reply() writes both the NET_SHAPER_A_IFINDEX
attribute (via net_shaper_fill_binding()) and the nested
NET_SHAPER_A_HANDLE attribute (via net_shaper_fill_handle()), but
the reply skb at the call site in net_shaper_nl_group_doit() is
allocated using net_shaper_handle_size(), which only accounts for
the nested handle.

The allocation is therefore short by nla_total_size(sizeof(u32))
(8 bytes) for the IFINDEX attribute.  In practice the slab allocator
rounds up the small allocation so the bug is latent, but the size
accounting is wrong and could bite if the reply grew further.

Introduce net_shaper_group_reply_size() that accounts for the full
reply payload and use it both at the genlmsg_new() call site and in
the defensive WARN_ONCE message.

Fixes: 5d5d4700e75d ("net-shapers: implement NL group operation")
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Link: https://patch.msgid.link/20260510192904.3987113-7-kuba@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
net/shaper/shaper.c

index 12e5e0c18643b946cc900a7651088b2cc1cb1b08..08fde2d9e8aa8ec676b845bf5d4bd6a9d37e7441 100644 (file)
@@ -90,6 +90,12 @@ static int net_shaper_handle_size(void)
                              nla_total_size(sizeof(u32)));
 }
 
+static int net_shaper_group_reply_size(void)
+{
+       return nla_total_size(sizeof(u32)) +    /* NET_SHAPER_A_IFINDEX */
+              net_shaper_handle_size();        /* NET_SHAPER_A_HANDLE */
+}
+
 static int net_shaper_fill_binding(struct sk_buff *msg,
                                   const struct net_shaper_binding *binding,
                                   u32 type)
@@ -1227,7 +1233,7 @@ static int net_shaper_group_send_reply(struct net_shaper_binding *binding,
 free_msg:
        /* Should never happen as msg is pre-allocated with enough space. */
        WARN_ONCE(true, "calculated message payload length (%d)",
-                 net_shaper_handle_size());
+                 net_shaper_group_reply_size());
        nlmsg_free(msg);
        return -EMSGSIZE;
 }
@@ -1275,7 +1281,7 @@ int net_shaper_nl_group_doit(struct sk_buff *skb, struct genl_info *info)
        /* Prepare the msg reply in advance, to avoid device operation
         * rollback on allocation failure.
         */
-       msg = genlmsg_new(net_shaper_handle_size(), GFP_KERNEL);
+       msg = genlmsg_new(net_shaper_group_reply_size(), GFP_KERNEL);
        if (!msg) {
                ret = -ENOMEM;
                goto free_leaves;