diff options
author | Patrick McHardy <kaber@trash.net> | 2007-02-01 02:16:40 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-02-08 15:38:41 -0500 |
commit | 26932566a42d46aee7e5d526cb34fba9380cad10 (patch) | |
tree | 3991d9209ddf2454ba4c71daccdc33951811dcf1 /net/core/neighbour.c | |
parent | 2cf6c36cb46d69057db2ebae0d8ec352e065f48b (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/neighbour.c')
-rw-r--r-- | net/core/neighbour.c | 24 |
1 files changed, 15 insertions, 9 deletions
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 | ||
1707 | nla_put_failure: | 1707 | nla_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 | ||
1712 | static int neightbl_fill_param_info(struct sk_buff *skb, | 1713 | static 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); |
1738 | errout: | 1739 | errout: |
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 | ||
1743 | static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl, | 1745 | static 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 | ||
1989 | nla_put_failure: | 1991 | nla_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); |
2436 | errout: | 2442 | errout: |
2437 | if (err < 0) | 2443 | if (err < 0) |