aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
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/core
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/core')
-rw-r--r--net/core/fib_rules.c14
-rw-r--r--net/core/neighbour.c24
-rw-r--r--net/core/rtnetlink.c23
3 files changed, 39 insertions, 22 deletions
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)