diff options
author | Patrick McHardy <kaber@trash.net> | 2007-01-31 23:16:40 -0800 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-02-08 12:38:41 -0800 |
commit | 26932566a42d46aee7e5d526cb34fba9380cad10 (patch) | |
tree | 3991d9209ddf2454ba4c71daccdc33951811dcf1 /net/decnet | |
parent | 2cf6c36cb46d69057db2ebae0d8ec352e065f48b (diff) | |
download | lwn-26932566a42d46aee7e5d526cb34fba9380cad10.tar.gz lwn-26932566a42d46aee7e5d526cb34fba9380cad10.zip |
[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/decnet')
-rw-r--r-- | net/decnet/dn_dev.c | 14 | ||||
-rw-r--r-- | net/decnet/dn_table.c | 11 |
2 files changed, 16 insertions, 9 deletions
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, nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), flags); if (nlh == NULL) - return -ENOBUFS; + return -EMSGSIZE; ifm = nlmsg_data(nlh); ifm->ifa_family = AF_DECnet; @@ -768,7 +768,8 @@ static int dn_nl_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa, return nlmsg_end(skb, nlh); nla_put_failure: - return nlmsg_cancel(skb, nlh); + nlmsg_cancel(skb, nlh); + return -EMSGSIZE; } static 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) goto errout; err = dn_nl_fill_ifaddr(skb, ifa, 0, 0, event, 0); - /* failure implies BUG in dn_ifaddr_nlmsg_size() */ - BUG_ON(err < 0); - + if (err < 0) { + /* -EMSGSIZE implies BUG in dn_ifaddr_nlmsg_size() */ + WARN_ON(err == -EMSGSIZE); + kfree_skb(skb); + goto errout; + } err = rtnl_notify(skb, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL); errout: 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, nlmsg_failure: rtattr_failure: skb_trim(skb, b - skb->data); - return -1; + return -EMSGSIZE; } @@ -368,9 +368,12 @@ static void dn_rtmsg_fib(int event, struct dn_fib_node *f, int z, u32 tb_id, err = dn_fib_dump_info(skb, pid, nlh->nlmsg_seq, event, tb_id, f->fn_type, f->fn_scope, &f->fn_key, z, DN_FIB_INFO(f), 0); - /* failure implies BUG in dn_fib_nlmsg_size() */ - BUG_ON(err < 0); - + if (err < 0) { + /* -EMSGSIZE implies BUG in dn_fib_nlmsg_size() */ + WARN_ON(err == -EMSGSIZE); + kfree_skb(skb); + goto errout; + } err = rtnl_notify(skb, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL); errout: if (err < 0) |