diff options
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/fib_rules.c | 14 | ||||
-rw-r--r-- | net/core/neighbour.c | 24 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 23 |
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, nlh = nlmsg_put(skb, pid, seq, type, sizeof(*frh), flags); if (nlh == NULL) - return -1; + return -EMSGSIZE; frh = nlmsg_data(nlh); frh->table = rule->table; @@ -359,7 +359,8 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule, return nlmsg_end(skb, nlh); nla_put_failure: - return nlmsg_cancel(skb, nlh); + nlmsg_cancel(skb, nlh); + return -EMSGSIZE; } int 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, goto errout; err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops); - /* failure implies BUG in fib_rule_nlmsg_size() */ - BUG_ON(err < 0); - + if (err < 0) { + /* -EMSGSIZE implies BUG in fib_rule_nlmsg_size() */ + WARN_ON(err == -EMSGSIZE); + kfree_skb(skb); + goto errout; + } err = rtnl_notify(skb, pid, ops->nlgroup, nlh, GFP_KERNEL); errout: 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, nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndtmsg), flags); if (nlh == NULL) - return -ENOBUFS; + return -EMSGSIZE; ndtmsg = nlmsg_data(nlh); @@ -1706,7 +1706,8 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl, nla_put_failure: read_unlock_bh(&tbl->lock); - return nlmsg_cancel(skb, nlh); + nlmsg_cancel(skb, nlh); + return -EMSGSIZE; } static int neightbl_fill_param_info(struct sk_buff *skb, @@ -1720,7 +1721,7 @@ static int neightbl_fill_param_info(struct sk_buff *skb, nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndtmsg), flags); if (nlh == NULL) - return -ENOBUFS; + return -EMSGSIZE; ndtmsg = nlmsg_data(nlh); @@ -1737,7 +1738,8 @@ static int neightbl_fill_param_info(struct sk_buff *skb, return nlmsg_end(skb, nlh); errout: read_unlock_bh(&tbl->lock); - return nlmsg_cancel(skb, nlh); + nlmsg_cancel(skb, nlh); + return -EMSGSIZE; } 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, nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), flags); if (nlh == NULL) - return -ENOBUFS; + return -EMSGSIZE; ndm = nlmsg_data(nlh); ndm->ndm_family = neigh->ops->family; @@ -1987,7 +1989,8 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *neigh, return nlmsg_end(skb, nlh); nla_put_failure: - return nlmsg_cancel(skb, nlh); + nlmsg_cancel(skb, nlh); + return -EMSGSIZE; } @@ -2429,9 +2432,12 @@ static void __neigh_notify(struct neighbour *n, int type, int flags) goto errout; err = neigh_fill_info(skb, n, 0, 0, type, flags); - /* failure implies BUG in neigh_nlmsg_size() */ - BUG_ON(err < 0); - + if (err < 0) { + /* -EMSGSIZE implies BUG in neigh_nlmsg_size() */ + WARN_ON(err == -EMSGSIZE); + kfree_skb(skb); + goto errout; + } err = rtnl_notify(skb, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); errout: 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, nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags); if (nlh == NULL) - return -ENOBUFS; + return -EMSGSIZE; ifm = nlmsg_data(nlh); ifm->ifi_family = AF_UNSPEC; @@ -384,7 +384,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, return nlmsg_end(skb, nlh); nla_put_failure: - return nlmsg_cancel(skb, nlh); + nlmsg_cancel(skb, nlh); + return -EMSGSIZE; } static 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) err = rtnl_fill_ifinfo(nskb, dev, iw, iw_buf_len, RTM_NEWLINK, NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0, 0); - /* failure impilies BUG in if_nlmsg_size or wireless_rtnetlink_get */ - BUG_ON(err < 0); - + if (err < 0) { + /* -EMSGSIZE implies BUG in if_nlmsg_size */ + WARN_ON(err == -EMSGSIZE); + kfree_skb(nskb); + goto errout; + } err = rtnl_unicast(nskb, NETLINK_CB(skb).pid); errout: kfree(iw_buf); @@ -678,9 +682,12 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change) goto errout; err = rtnl_fill_ifinfo(skb, dev, NULL, 0, type, 0, 0, change, 0); - /* failure implies BUG in if_nlmsg_size() */ - BUG_ON(err < 0); - + if (err < 0) { + /* -EMSGSIZE implies BUG in if_nlmsg_size() */ + WARN_ON(err == -EMSGSIZE); + kfree_skb(skb); + goto errout; + } err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_KERNEL); errout: if (err < 0) |