drop_monitor: add missing call to genlmsg_end
authorReiter Wolfgang <wr0112358@gmail.com>
Sat, 31 Dec 2016 20:11:57 +0000 (21:11 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 2 Jan 2017 03:00:26 +0000 (22:00 -0500)
Update nlmsg_len field with genlmsg_end to enable userspace processing
using nlmsg_next helper. Also adds error handling.

Signed-off-by: Reiter Wolfgang <wr0112358@gmail.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/drop_monitor.c

index 8e0c063..f465bad 100644 (file)
@@ -75,6 +75,7 @@ static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data)
        struct nlattr *nla;
        struct sk_buff *skb;
        unsigned long flags;
+       void *msg_header;
 
        al = sizeof(struct net_dm_alert_msg);
        al += dm_hit_limit * sizeof(struct net_dm_drop_point);
@@ -82,17 +83,31 @@ static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data)
 
        skb = genlmsg_new(al, GFP_KERNEL);
 
-       if (skb) {
-               genlmsg_put(skb, 0, 0, &net_drop_monitor_family,
-                               0, NET_DM_CMD_ALERT);
-               nla = nla_reserve(skb, NLA_UNSPEC,
-                                 sizeof(struct net_dm_alert_msg));
-               msg = nla_data(nla);
-               memset(msg, 0, al);
-       } else {
-               mod_timer(&data->send_timer, jiffies + HZ / 10);
+       if (!skb)
+               goto err;
+
+       msg_header = genlmsg_put(skb, 0, 0, &net_drop_monitor_family,
+                                0, NET_DM_CMD_ALERT);
+       if (!msg_header) {
+               nlmsg_free(skb);
+               skb = NULL;
+               goto err;
+       }
+       nla = nla_reserve(skb, NLA_UNSPEC,
+                         sizeof(struct net_dm_alert_msg));
+       if (!nla) {
+               nlmsg_free(skb);
+               skb = NULL;
+               goto err;
        }
+       msg = nla_data(nla);
+       memset(msg, 0, al);
+       genlmsg_end(skb, msg_header);
+       goto out;
 
+err:
+       mod_timer(&data->send_timer, jiffies + HZ / 10);
+out:
        spin_lock_irqsave(&data->lock, flags);
        swap(data->skb, skb);
        spin_unlock_irqrestore(&data->lock, flags);