aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-02-01 02:16:40 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2007-02-08 15:38:41 -0500
commit26932566a42d46aee7e5d526cb34fba9380cad10 (patch)
tree3991d9209ddf2454ba4c71daccdc33951811dcf1 /net
parent2cf6c36cb46d69057db2ebae0d8ec352e065f48b (diff)
[NETLINK]: Don't BUG on undersized allocations
Currently netlink users BUG when the allocated skb for an event notification is undersized. While this is certainly a kernel bug, its not critical and crashing the kernel is too drastic, especially when considering that these errors have appeared multiple times in the past and it BUGs even if no listeners are present. This patch replaces BUG by WARN_ON and changes the notification functions to inform potential listeners of undersized allocations using a unique error code (EMSGSIZE). Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/bridge/br_netlink.c14
-rw-r--r--net/core/fib_rules.c14
-rw-r--r--net/core/neighbour.c24
-rw-r--r--net/core/rtnetlink.c23
-rw-r--r--net/decnet/dn_dev.c14
-rw-r--r--net/decnet/dn_table.c11
-rw-r--r--net/ipv4/devinet.c14
-rw-r--r--net/ipv4/fib_semantics.c14
-rw-r--r--net/ipv4/inet_diag.c17
-rw-r--r--net/ipv4/route.c5
-rw-r--r--net/ipv6/addrconf.c70
-rw-r--r--net/ipv6/route.c14
12 files changed, 149 insertions, 85 deletions
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index a9139682c49b..7d68b24b5654 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -45,7 +45,7 @@ static int br_fill_ifinfo(struct sk_buff *skb, const struct net_bridge_port *por
45 45
46 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags); 46 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags);
47 if (nlh == NULL) 47 if (nlh == NULL)
48 return -ENOBUFS; 48 return -EMSGSIZE;
49 49
50 hdr = nlmsg_data(nlh); 50 hdr = nlmsg_data(nlh);
51 hdr->ifi_family = AF_BRIDGE; 51 hdr->ifi_family = AF_BRIDGE;
@@ -72,7 +72,8 @@ static int br_fill_ifinfo(struct sk_buff *skb, const struct net_bridge_port *por
72 return nlmsg_end(skb, nlh); 72 return nlmsg_end(skb, nlh);
73 73
74nla_put_failure: 74nla_put_failure:
75 return nlmsg_cancel(skb, nlh); 75 nlmsg_cancel(skb, nlh);
76 return -EMSGSIZE;
76} 77}
77 78
78/* 79/*
@@ -89,9 +90,12 @@ void br_ifinfo_notify(int event, struct net_bridge_port *port)
89 goto errout; 90 goto errout;
90 91
91 err = br_fill_ifinfo(skb, port, 0, 0, event, 0); 92 err = br_fill_ifinfo(skb, port, 0, 0, event, 0);
92 /* failure implies BUG in br_nlmsg_size() */ 93 if (err < 0) {
93 BUG_ON(err < 0); 94 /* -EMSGSIZE implies BUG in br_nlmsg_size() */
94 95 WARN_ON(err == -EMSGSIZE);
96 kfree_skb(skb);
97 goto errout;
98 }
95 err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); 99 err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
96errout: 100errout:
97 if (err < 0) 101 if (err < 0)
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 1df6cd4568d3..215f1bff048f 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -331,7 +331,7 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
331 331
332 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*frh), flags); 332 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*frh), flags);
333 if (nlh == NULL) 333 if (nlh == NULL)
334 return -1; 334 return -EMSGSIZE;
335 335
336 frh = nlmsg_data(nlh); 336 frh = nlmsg_data(nlh);
337 frh->table = rule->table; 337 frh->table = rule->table;
@@ -359,7 +359,8 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
359 return nlmsg_end(skb, nlh); 359 return nlmsg_end(skb, nlh);
360 360
361nla_put_failure: 361nla_put_failure:
362 return nlmsg_cancel(skb, nlh); 362 nlmsg_cancel(skb, nlh);
363 return -EMSGSIZE;
363} 364}
364 365
365int fib_rules_dump(struct sk_buff *skb, struct netlink_callback *cb, int family) 366int fib_rules_dump(struct sk_buff *skb, struct netlink_callback *cb, int family)
@@ -405,9 +406,12 @@ static void notify_rule_change(int event, struct fib_rule *rule,
405 goto errout; 406 goto errout;
406 407
407 err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops); 408 err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops);
408 /* failure implies BUG in fib_rule_nlmsg_size() */ 409 if (err < 0) {
409 BUG_ON(err < 0); 410 /* -EMSGSIZE implies BUG in fib_rule_nlmsg_size() */
410 411 WARN_ON(err == -EMSGSIZE);
412 kfree_skb(skb);
413 goto errout;
414 }
411 err = rtnl_notify(skb, pid, ops->nlgroup, nlh, GFP_KERNEL); 415 err = rtnl_notify(skb, pid, ops->nlgroup, nlh, GFP_KERNEL);
412errout: 416errout:
413 if (err < 0) 417 if (err < 0)
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index e7300b6b4079..9e26f38ea6e5 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1637,7 +1637,7 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
1637 1637
1638 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndtmsg), flags); 1638 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndtmsg), flags);
1639 if (nlh == NULL) 1639 if (nlh == NULL)
1640 return -ENOBUFS; 1640 return -EMSGSIZE;
1641 1641
1642 ndtmsg = nlmsg_data(nlh); 1642 ndtmsg = nlmsg_data(nlh);
1643 1643
@@ -1706,7 +1706,8 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
1706 1706
1707nla_put_failure: 1707nla_put_failure:
1708 read_unlock_bh(&tbl->lock); 1708 read_unlock_bh(&tbl->lock);
1709 return nlmsg_cancel(skb, nlh); 1709 nlmsg_cancel(skb, nlh);
1710 return -EMSGSIZE;
1710} 1711}
1711 1712
1712static int neightbl_fill_param_info(struct sk_buff *skb, 1713static int neightbl_fill_param_info(struct sk_buff *skb,
@@ -1720,7 +1721,7 @@ static int neightbl_fill_param_info(struct sk_buff *skb,
1720 1721
1721 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndtmsg), flags); 1722 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndtmsg), flags);
1722 if (nlh == NULL) 1723 if (nlh == NULL)
1723 return -ENOBUFS; 1724 return -EMSGSIZE;
1724 1725
1725 ndtmsg = nlmsg_data(nlh); 1726 ndtmsg = nlmsg_data(nlh);
1726 1727
@@ -1737,7 +1738,8 @@ static int neightbl_fill_param_info(struct sk_buff *skb,
1737 return nlmsg_end(skb, nlh); 1738 return nlmsg_end(skb, nlh);
1738errout: 1739errout:
1739 read_unlock_bh(&tbl->lock); 1740 read_unlock_bh(&tbl->lock);
1740 return nlmsg_cancel(skb, nlh); 1741 nlmsg_cancel(skb, nlh);
1742 return -EMSGSIZE;
1741} 1743}
1742 1744
1743static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl, 1745static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
@@ -1955,7 +1957,7 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *neigh,
1955 1957
1956 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), flags); 1958 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), flags);
1957 if (nlh == NULL) 1959 if (nlh == NULL)
1958 return -ENOBUFS; 1960 return -EMSGSIZE;
1959 1961
1960 ndm = nlmsg_data(nlh); 1962 ndm = nlmsg_data(nlh);
1961 ndm->ndm_family = neigh->ops->family; 1963 ndm->ndm_family = neigh->ops->family;
@@ -1987,7 +1989,8 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *neigh,
1987 return nlmsg_end(skb, nlh); 1989 return nlmsg_end(skb, nlh);
1988 1990
1989nla_put_failure: 1991nla_put_failure:
1990 return nlmsg_cancel(skb, nlh); 1992 nlmsg_cancel(skb, nlh);
1993 return -EMSGSIZE;
1991} 1994}
1992 1995
1993 1996
@@ -2429,9 +2432,12 @@ static void __neigh_notify(struct neighbour *n, int type, int flags)
2429 goto errout; 2432 goto errout;
2430 2433
2431 err = neigh_fill_info(skb, n, 0, 0, type, flags); 2434 err = neigh_fill_info(skb, n, 0, 0, type, flags);
2432 /* failure implies BUG in neigh_nlmsg_size() */ 2435 if (err < 0) {
2433 BUG_ON(err < 0); 2436 /* -EMSGSIZE implies BUG in neigh_nlmsg_size() */
2434 2437 WARN_ON(err == -EMSGSIZE);
2438 kfree_skb(skb);
2439 goto errout;
2440 }
2435 err = rtnl_notify(skb, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); 2441 err = rtnl_notify(skb, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
2436errout: 2442errout:
2437 if (err < 0) 2443 if (err < 0)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index e76539a5eb5e..9bf9ae05f157 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -320,7 +320,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
320 320
321 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags); 321 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);
322 if (nlh == NULL) 322 if (nlh == NULL)
323 return -ENOBUFS; 323 return -EMSGSIZE;
324 324
325 ifm = nlmsg_data(nlh); 325 ifm = nlmsg_data(nlh);
326 ifm->ifi_family = AF_UNSPEC; 326 ifm->ifi_family = AF_UNSPEC;
@@ -384,7 +384,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
384 return nlmsg_end(skb, nlh); 384 return nlmsg_end(skb, nlh);
385 385
386nla_put_failure: 386nla_put_failure:
387 return nlmsg_cancel(skb, nlh); 387 nlmsg_cancel(skb, nlh);
388 return -EMSGSIZE;
388} 389}
389 390
390static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) 391static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
@@ -633,9 +634,12 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
633 634
634 err = rtnl_fill_ifinfo(nskb, dev, iw, iw_buf_len, RTM_NEWLINK, 635 err = rtnl_fill_ifinfo(nskb, dev, iw, iw_buf_len, RTM_NEWLINK,
635 NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0, 0); 636 NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0, 0);
636 /* failure impilies BUG in if_nlmsg_size or wireless_rtnetlink_get */ 637 if (err < 0) {
637 BUG_ON(err < 0); 638 /* -EMSGSIZE implies BUG in if_nlmsg_size */
638 639 WARN_ON(err == -EMSGSIZE);
640 kfree_skb(nskb);
641 goto errout;
642 }
639 err = rtnl_unicast(nskb, NETLINK_CB(skb).pid); 643 err = rtnl_unicast(nskb, NETLINK_CB(skb).pid);
640errout: 644errout:
641 kfree(iw_buf); 645 kfree(iw_buf);
@@ -678,9 +682,12 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
678 goto errout; 682 goto errout;
679 683
680 err = rtnl_fill_ifinfo(skb, dev, NULL, 0, type, 0, 0, change, 0); 684 err = rtnl_fill_ifinfo(skb, dev, NULL, 0, type, 0, 0, change, 0);
681 /* failure implies BUG in if_nlmsg_size() */ 685 if (err < 0) {
682 BUG_ON(err < 0); 686 /* -EMSGSIZE implies BUG in if_nlmsg_size() */
683 687 WARN_ON(err == -EMSGSIZE);
688 kfree_skb(skb);
689 goto errout;
690 }
684 err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_KERNEL); 691 err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
685errout: 692errout:
686 if (err < 0) 693 if (err < 0)
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index ed083ab455b7..90b3dfd72b49 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -749,7 +749,7 @@ static int dn_nl_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa,
749 749
750 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), flags); 750 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), flags);
751 if (nlh == NULL) 751 if (nlh == NULL)
752 return -ENOBUFS; 752 return -EMSGSIZE;
753 753
754 ifm = nlmsg_data(nlh); 754 ifm = nlmsg_data(nlh);
755 ifm->ifa_family = AF_DECnet; 755 ifm->ifa_family = AF_DECnet;
@@ -768,7 +768,8 @@ static int dn_nl_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa,
768 return nlmsg_end(skb, nlh); 768 return nlmsg_end(skb, nlh);
769 769
770nla_put_failure: 770nla_put_failure:
771 return nlmsg_cancel(skb, nlh); 771 nlmsg_cancel(skb, nlh);
772 return -EMSGSIZE;
772} 773}
773 774
774static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa) 775static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa)
@@ -781,9 +782,12 @@ static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa)
781 goto errout; 782 goto errout;
782 783
783 err = dn_nl_fill_ifaddr(skb, ifa, 0, 0, event, 0); 784 err = dn_nl_fill_ifaddr(skb, ifa, 0, 0, event, 0);
784 /* failure implies BUG in dn_ifaddr_nlmsg_size() */ 785 if (err < 0) {
785 BUG_ON(err < 0); 786 /* -EMSGSIZE implies BUG in dn_ifaddr_nlmsg_size() */
786 787 WARN_ON(err == -EMSGSIZE);
788 kfree_skb(skb);
789 goto errout;
790 }
787 err = rtnl_notify(skb, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL); 791 err = rtnl_notify(skb, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL);
788errout: 792errout:
789 if (err < 0) 793 if (err < 0)
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c
index 13b2421991ba..c1f0cc1b1c60 100644
--- a/net/decnet/dn_table.c
+++ b/net/decnet/dn_table.c
@@ -350,7 +350,7 @@ static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
350nlmsg_failure: 350nlmsg_failure:
351rtattr_failure: 351rtattr_failure:
352 skb_trim(skb, b - skb->data); 352 skb_trim(skb, b - skb->data);
353 return -1; 353 return -EMSGSIZE;
354} 354}
355 355
356 356
@@ -368,9 +368,12 @@ static void dn_rtmsg_fib(int event, struct dn_fib_node *f, int z, u32 tb_id,
368 err = dn_fib_dump_info(skb, pid, nlh->nlmsg_seq, event, tb_id, 368 err = dn_fib_dump_info(skb, pid, nlh->nlmsg_seq, event, tb_id,
369 f->fn_type, f->fn_scope, &f->fn_key, z, 369 f->fn_type, f->fn_scope, &f->fn_key, z,
370 DN_FIB_INFO(f), 0); 370 DN_FIB_INFO(f), 0);
371 /* failure implies BUG in dn_fib_nlmsg_size() */ 371 if (err < 0) {
372 BUG_ON(err < 0); 372 /* -EMSGSIZE implies BUG in dn_fib_nlmsg_size() */
373 373 WARN_ON(err == -EMSGSIZE);
374 kfree_skb(skb);
375 goto errout;
376 }
374 err = rtnl_notify(skb, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL); 377 err = rtnl_notify(skb, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL);
375errout: 378errout:
376 if (err < 0) 379 if (err < 0)
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 480ace9819f6..c40203640966 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1140,7 +1140,7 @@ static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
1140 1140
1141 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), flags); 1141 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), flags);
1142 if (nlh == NULL) 1142 if (nlh == NULL)
1143 return -ENOBUFS; 1143 return -EMSGSIZE;
1144 1144
1145 ifm = nlmsg_data(nlh); 1145 ifm = nlmsg_data(nlh);
1146 ifm->ifa_family = AF_INET; 1146 ifm->ifa_family = AF_INET;
@@ -1167,7 +1167,8 @@ static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
1167 return nlmsg_end(skb, nlh); 1167 return nlmsg_end(skb, nlh);
1168 1168
1169nla_put_failure: 1169nla_put_failure:
1170 return nlmsg_cancel(skb, nlh); 1170 nlmsg_cancel(skb, nlh);
1171 return -EMSGSIZE;
1171} 1172}
1172 1173
1173static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) 1174static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
@@ -1225,9 +1226,12 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa, struct nlmsghdr *nlh,
1225 goto errout; 1226 goto errout;
1226 1227
1227 err = inet_fill_ifaddr(skb, ifa, pid, seq, event, 0); 1228 err = inet_fill_ifaddr(skb, ifa, pid, seq, event, 0);
1228 /* failure implies BUG in inet_nlmsg_size() */ 1229 if (err < 0) {
1229 BUG_ON(err < 0); 1230 /* -EMSGSIZE implies BUG in inet_nlmsg_size() */
1230 1231 WARN_ON(err == -EMSGSIZE);
1232 kfree_skb(skb);
1233 goto errout;
1234 }
1231 err = rtnl_notify(skb, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL); 1235 err = rtnl_notify(skb, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
1232errout: 1236errout:
1233 if (err < 0) 1237 if (err < 0)
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index e63b8a98fb4d..be1028c9933e 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -314,9 +314,12 @@ void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
314 err = fib_dump_info(skb, info->pid, seq, event, tb_id, 314 err = fib_dump_info(skb, info->pid, seq, event, tb_id,
315 fa->fa_type, fa->fa_scope, key, dst_len, 315 fa->fa_type, fa->fa_scope, key, dst_len,
316 fa->fa_tos, fa->fa_info, 0); 316 fa->fa_tos, fa->fa_info, 0);
317 /* failure implies BUG in fib_nlmsg_size() */ 317 if (err < 0) {
318 BUG_ON(err < 0); 318 /* -EMSGSIZE implies BUG in fib_nlmsg_size() */
319 319 WARN_ON(err == -EMSGSIZE);
320 kfree_skb(skb);
321 goto errout;
322 }
320 err = rtnl_notify(skb, info->pid, RTNLGRP_IPV4_ROUTE, 323 err = rtnl_notify(skb, info->pid, RTNLGRP_IPV4_ROUTE,
321 info->nlh, GFP_KERNEL); 324 info->nlh, GFP_KERNEL);
322errout: 325errout:
@@ -960,7 +963,7 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
960 963
961 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*rtm), flags); 964 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*rtm), flags);
962 if (nlh == NULL) 965 if (nlh == NULL)
963 return -ENOBUFS; 966 return -EMSGSIZE;
964 967
965 rtm = nlmsg_data(nlh); 968 rtm = nlmsg_data(nlh);
966 rtm->rtm_family = AF_INET; 969 rtm->rtm_family = AF_INET;
@@ -1031,7 +1034,8 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
1031 return nlmsg_end(skb, nlh); 1034 return nlmsg_end(skb, nlh);
1032 1035
1033nla_put_failure: 1036nla_put_failure:
1034 return nlmsg_cancel(skb, nlh); 1037 nlmsg_cancel(skb, nlh);
1038 return -EMSGSIZE;
1035} 1039}
1036 1040
1037/* 1041/*
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 77761ac4f7bb..9cd53addb784 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -153,7 +153,7 @@ static int inet_csk_diag_fill(struct sock *sk,
153rtattr_failure: 153rtattr_failure:
154nlmsg_failure: 154nlmsg_failure:
155 skb_trim(skb, b - skb->data); 155 skb_trim(skb, b - skb->data);
156 return -1; 156 return -EMSGSIZE;
157} 157}
158 158
159static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, 159static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
@@ -209,7 +209,7 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
209 return skb->len; 209 return skb->len;
210nlmsg_failure: 210nlmsg_failure:
211 skb_trim(skb, previous_tail - skb->data); 211 skb_trim(skb, previous_tail - skb->data);
212 return -1; 212 return -EMSGSIZE;
213} 213}
214 214
215static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, 215static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
@@ -274,11 +274,14 @@ static int inet_diag_get_exact(struct sk_buff *in_skb,
274 if (!rep) 274 if (!rep)
275 goto out; 275 goto out;
276 276
277 if (sk_diag_fill(sk, rep, req->idiag_ext, 277 err = sk_diag_fill(sk, rep, req->idiag_ext,
278 NETLINK_CB(in_skb).pid, 278 NETLINK_CB(in_skb).pid,
279 nlh->nlmsg_seq, 0, nlh) <= 0) 279 nlh->nlmsg_seq, 0, nlh);
280 BUG(); 280 if (err < 0) {
281 281 WARN_ON(err == -EMSGSIZE);
282 kfree_skb(rep);
283 goto out;
284 }
282 err = netlink_unicast(idiagnl, rep, NETLINK_CB(in_skb).pid, 285 err = netlink_unicast(idiagnl, rep, NETLINK_CB(in_skb).pid,
283 MSG_DONTWAIT); 286 MSG_DONTWAIT);
284 if (err > 0) 287 if (err > 0)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 2daa0dc19d33..baee304a3cb7 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2635,7 +2635,7 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
2635 2635
2636 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags); 2636 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags);
2637 if (nlh == NULL) 2637 if (nlh == NULL)
2638 return -ENOBUFS; 2638 return -EMSGSIZE;
2639 2639
2640 r = nlmsg_data(nlh); 2640 r = nlmsg_data(nlh);
2641 r->rtm_family = AF_INET; 2641 r->rtm_family = AF_INET;
@@ -2718,7 +2718,8 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
2718 return nlmsg_end(skb, nlh); 2718 return nlmsg_end(skb, nlh);
2719 2719
2720nla_put_failure: 2720nla_put_failure:
2721 return nlmsg_cancel(skb, nlh); 2721 nlmsg_cancel(skb, nlh);
2722 return -EMSGSIZE;
2722} 2723}
2723 2724
2724int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) 2725int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index e3854696988d..fe5e1d833871 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3117,7 +3117,7 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
3117 3117
3118 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); 3118 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
3119 if (nlh == NULL) 3119 if (nlh == NULL)
3120 return -ENOBUFS; 3120 return -EMSGSIZE;
3121 3121
3122 put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope), 3122 put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope),
3123 ifa->idev->dev->ifindex); 3123 ifa->idev->dev->ifindex);
@@ -3137,8 +3137,10 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
3137 } 3137 }
3138 3138
3139 if (nla_put(skb, IFA_ADDRESS, 16, &ifa->addr) < 0 || 3139 if (nla_put(skb, IFA_ADDRESS, 16, &ifa->addr) < 0 ||
3140 put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0) 3140 put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0) {
3141 return nlmsg_cancel(skb, nlh); 3141 nlmsg_cancel(skb, nlh);
3142 return -EMSGSIZE;
3143 }
3142 3144
3143 return nlmsg_end(skb, nlh); 3145 return nlmsg_end(skb, nlh);
3144} 3146}
@@ -3155,13 +3157,15 @@ static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
3155 3157
3156 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); 3158 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
3157 if (nlh == NULL) 3159 if (nlh == NULL)
3158 return -ENOBUFS; 3160 return -EMSGSIZE;
3159 3161
3160 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex); 3162 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
3161 if (nla_put(skb, IFA_MULTICAST, 16, &ifmca->mca_addr) < 0 || 3163 if (nla_put(skb, IFA_MULTICAST, 16, &ifmca->mca_addr) < 0 ||
3162 put_cacheinfo(skb, ifmca->mca_cstamp, ifmca->mca_tstamp, 3164 put_cacheinfo(skb, ifmca->mca_cstamp, ifmca->mca_tstamp,
3163 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) 3165 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
3164 return nlmsg_cancel(skb, nlh); 3166 nlmsg_cancel(skb, nlh);
3167 return -EMSGSIZE;
3168 }
3165 3169
3166 return nlmsg_end(skb, nlh); 3170 return nlmsg_end(skb, nlh);
3167} 3171}
@@ -3178,13 +3182,15 @@ static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
3178 3182
3179 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); 3183 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
3180 if (nlh == NULL) 3184 if (nlh == NULL)
3181 return -ENOBUFS; 3185 return -EMSGSIZE;
3182 3186
3183 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex); 3187 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
3184 if (nla_put(skb, IFA_ANYCAST, 16, &ifaca->aca_addr) < 0 || 3188 if (nla_put(skb, IFA_ANYCAST, 16, &ifaca->aca_addr) < 0 ||
3185 put_cacheinfo(skb, ifaca->aca_cstamp, ifaca->aca_tstamp, 3189 put_cacheinfo(skb, ifaca->aca_cstamp, ifaca->aca_tstamp,
3186 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) 3190 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
3187 return nlmsg_cancel(skb, nlh); 3191 nlmsg_cancel(skb, nlh);
3192 return -EMSGSIZE;
3193 }
3188 3194
3189 return nlmsg_end(skb, nlh); 3195 return nlmsg_end(skb, nlh);
3190} 3196}
@@ -3334,9 +3340,12 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
3334 3340
3335 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid, 3341 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid,
3336 nlh->nlmsg_seq, RTM_NEWADDR, 0); 3342 nlh->nlmsg_seq, RTM_NEWADDR, 0);
3337 /* failure implies BUG in inet6_ifaddr_msgsize() */ 3343 if (err < 0) {
3338 BUG_ON(err < 0); 3344 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
3339 3345 WARN_ON(err == -EMSGSIZE);
3346 kfree_skb(skb);
3347 goto errout_ifa;
3348 }
3340 err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid); 3349 err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
3341errout_ifa: 3350errout_ifa:
3342 in6_ifa_put(ifa); 3351 in6_ifa_put(ifa);
@@ -3354,9 +3363,12 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
3354 goto errout; 3363 goto errout;
3355 3364
3356 err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0); 3365 err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0);
3357 /* failure implies BUG in inet6_ifaddr_msgsize() */ 3366 if (err < 0) {
3358 BUG_ON(err < 0); 3367 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
3359 3368 WARN_ON(err == -EMSGSIZE);
3369 kfree_skb(skb);
3370 goto errout;
3371 }
3360 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); 3372 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
3361errout: 3373errout:
3362 if (err < 0) 3374 if (err < 0)
@@ -3426,7 +3438,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
3426 3438
3427 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags); 3439 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags);
3428 if (nlh == NULL) 3440 if (nlh == NULL)
3429 return -ENOBUFS; 3441 return -EMSGSIZE;
3430 3442
3431 hdr = nlmsg_data(nlh); 3443 hdr = nlmsg_data(nlh);
3432 hdr->ifi_family = AF_INET6; 3444 hdr->ifi_family = AF_INET6;
@@ -3469,7 +3481,8 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
3469 return nlmsg_end(skb, nlh); 3481 return nlmsg_end(skb, nlh);
3470 3482
3471nla_put_failure: 3483nla_put_failure:
3472 return nlmsg_cancel(skb, nlh); 3484 nlmsg_cancel(skb, nlh);
3485 return -EMSGSIZE;
3473} 3486}
3474 3487
3475static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) 3488static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
@@ -3507,9 +3520,12 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
3507 goto errout; 3520 goto errout;
3508 3521
3509 err = inet6_fill_ifinfo(skb, idev, 0, 0, event, 0); 3522 err = inet6_fill_ifinfo(skb, idev, 0, 0, event, 0);
3510 /* failure implies BUG in inet6_if_nlmsg_size() */ 3523 if (err < 0) {
3511 BUG_ON(err < 0); 3524 /* -EMSGSIZE implies BUG in inet6_if_nlmsg_size() */
3512 3525 WARN_ON(err == -EMSGSIZE);
3526 kfree_skb(skb);
3527 goto errout;
3528 }
3513 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); 3529 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
3514errout: 3530errout:
3515 if (err < 0) 3531 if (err < 0)
@@ -3533,7 +3549,7 @@ static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
3533 3549
3534 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*pmsg), flags); 3550 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*pmsg), flags);
3535 if (nlh == NULL) 3551 if (nlh == NULL)
3536 return -ENOBUFS; 3552 return -EMSGSIZE;
3537 3553
3538 pmsg = nlmsg_data(nlh); 3554 pmsg = nlmsg_data(nlh);
3539 pmsg->prefix_family = AF_INET6; 3555 pmsg->prefix_family = AF_INET6;
@@ -3558,7 +3574,8 @@ static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
3558 return nlmsg_end(skb, nlh); 3574 return nlmsg_end(skb, nlh);
3559 3575
3560nla_put_failure: 3576nla_put_failure:
3561 return nlmsg_cancel(skb, nlh); 3577 nlmsg_cancel(skb, nlh);
3578 return -EMSGSIZE;
3562} 3579}
3563 3580
3564static void inet6_prefix_notify(int event, struct inet6_dev *idev, 3581static void inet6_prefix_notify(int event, struct inet6_dev *idev,
@@ -3572,9 +3589,12 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev,
3572 goto errout; 3589 goto errout;
3573 3590
3574 err = inet6_fill_prefix(skb, idev, pinfo, 0, 0, event, 0); 3591 err = inet6_fill_prefix(skb, idev, pinfo, 0, 0, event, 0);
3575 /* failure implies BUG in inet6_prefix_nlmsg_size() */ 3592 if (err < 0) {
3576 BUG_ON(err < 0); 3593 /* -EMSGSIZE implies BUG in inet6_prefix_nlmsg_size() */
3577 3594 WARN_ON(err == -EMSGSIZE);
3595 kfree_skb(skb);
3596 goto errout;
3597 }
3578 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC); 3598 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
3579errout: 3599errout:
3580 if (err < 0) 3600 if (err < 0)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 5f0043c30b70..f4fda80a41a2 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2040,7 +2040,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
2040 2040
2041 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*rtm), flags); 2041 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*rtm), flags);
2042 if (nlh == NULL) 2042 if (nlh == NULL)
2043 return -ENOBUFS; 2043 return -EMSGSIZE;
2044 2044
2045 rtm = nlmsg_data(nlh); 2045 rtm = nlmsg_data(nlh);
2046 rtm->rtm_family = AF_INET6; 2046 rtm->rtm_family = AF_INET6;
@@ -2111,7 +2111,8 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
2111 return nlmsg_end(skb, nlh); 2111 return nlmsg_end(skb, nlh);
2112 2112
2113nla_put_failure: 2113nla_put_failure:
2114 return nlmsg_cancel(skb, nlh); 2114 nlmsg_cancel(skb, nlh);
2115 return -EMSGSIZE;
2115} 2116}
2116 2117
2117int rt6_dump_route(struct rt6_info *rt, void *p_arg) 2118int rt6_dump_route(struct rt6_info *rt, void *p_arg)
@@ -2222,9 +2223,12 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
2222 goto errout; 2223 goto errout;
2223 2224
2224 err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0); 2225 err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0);
2225 /* failure implies BUG in rt6_nlmsg_size() */ 2226 if (err < 0) {
2226 BUG_ON(err < 0); 2227 /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
2227 2228 WARN_ON(err == -EMSGSIZE);
2229 kfree_skb(skb);
2230 goto errout;
2231 }
2228 err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any()); 2232 err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any());
2229errout: 2233errout:
2230 if (err < 0) 2234 if (err < 0)