summaryrefslogtreecommitdiffstats
path: root/net/netlink
diff options
context:
space:
mode:
Diffstat (limited to 'net/netlink')
-rw-r--r--net/netlink/af_netlink.c75
-rw-r--r--net/netlink/genetlink.c35
2 files changed, 62 insertions, 48 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index faa48f70b7c9..b3025a603d56 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -104,27 +104,27 @@ static inline int netlink_is_kernel(struct sock *sk)
}
struct nl_pid_hash {
- struct hlist_head *table;
- unsigned long rehash_time;
+ struct hlist_head *table;
+ unsigned long rehash_time;
- unsigned int mask;
- unsigned int shift;
+ unsigned int mask;
+ unsigned int shift;
- unsigned int entries;
- unsigned int max_shift;
+ unsigned int entries;
+ unsigned int max_shift;
- u32 rnd;
+ u32 rnd;
};
struct netlink_table {
- struct nl_pid_hash hash;
- struct hlist_head mc_list;
- struct listeners __rcu *listeners;
- unsigned int nl_nonroot;
- unsigned int groups;
- struct mutex *cb_mutex;
- struct module *module;
- int registered;
+ struct nl_pid_hash hash;
+ struct hlist_head mc_list;
+ struct listeners __rcu *listeners;
+ unsigned int nl_nonroot;
+ unsigned int groups;
+ struct mutex *cb_mutex;
+ struct module *module;
+ int registered;
};
static struct netlink_table *nl_table;
@@ -132,7 +132,6 @@ static struct netlink_table *nl_table;
static DECLARE_WAIT_QUEUE_HEAD(nl_table_wait);
static int netlink_dump(struct sock *sk);
-static void netlink_destroy_callback(struct netlink_callback *cb);
static DEFINE_RWLOCK(nl_table_lock);
static atomic_t nl_table_users = ATOMIC_INIT(0);
@@ -149,6 +148,18 @@ static inline struct hlist_head *nl_pid_hashfn(struct nl_pid_hash *hash, u32 pid
return &hash->table[jhash_1word(pid, hash->rnd) & hash->mask];
}
+static void netlink_destroy_callback(struct netlink_callback *cb)
+{
+ kfree_skb(cb->skb);
+ kfree(cb);
+}
+
+static void netlink_consume_callback(struct netlink_callback *cb)
+{
+ consume_skb(cb->skb);
+ kfree(cb);
+}
+
static void netlink_sock_destruct(struct sock *sk)
{
struct netlink_sock *nlk = nlk_sk(sk);
@@ -414,9 +425,9 @@ static int __netlink_create(struct net *net, struct socket *sock,
sock_init_data(sock, sk);
nlk = nlk_sk(sk);
- if (cb_mutex)
+ if (cb_mutex) {
nlk->cb_mutex = cb_mutex;
- else {
+ } else {
nlk->cb_mutex = &nlk->cb_def_mutex;
mutex_init(nlk->cb_mutex);
}
@@ -522,8 +533,9 @@ static int netlink_release(struct socket *sock)
nl_table[sk->sk_protocol].module = NULL;
nl_table[sk->sk_protocol].registered = 0;
}
- } else if (nlk->subscriptions)
+ } else if (nlk->subscriptions) {
netlink_update_listeners(sk);
+ }
netlink_table_ungrab();
kfree(nlk->groups);
@@ -866,7 +878,7 @@ static struct sk_buff *netlink_trim(struct sk_buff *skb, gfp_t allocation)
struct sk_buff *nskb = skb_clone(skb, allocation);
if (!nskb)
return skb;
- kfree_skb(skb);
+ consume_skb(skb);
skb = nskb;
}
@@ -896,8 +908,10 @@ static int netlink_unicast_kernel(struct sock *sk, struct sk_buff *skb)
ret = skb->len;
skb_set_owner_r(skb, sk);
nlk->netlink_rcv(skb);
+ consume_skb(skb);
+ } else {
+ kfree_skb(skb);
}
- kfree_skb(skb);
sock_put(sk);
return ret;
}
@@ -1086,8 +1100,8 @@ int netlink_broadcast_filtered(struct sock *ssk, struct sk_buff *skb, u32 pid,
if (info.delivery_failure) {
kfree_skb(info.skb2);
return -ENOBUFS;
- } else
- consume_skb(info.skb2);
+ }
+ consume_skb(info.skb2);
if (info.delivered) {
if (info.congested && (allocation & __GFP_WAIT))
@@ -1240,8 +1254,9 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
nlk->flags |= NETLINK_RECV_NO_ENOBUFS;
clear_bit(0, &nlk->state);
wake_up_interruptible(&nlk->wait);
- } else
+ } else {
nlk->flags &= ~NETLINK_RECV_NO_ENOBUFS;
+ }
err = 0;
break;
default:
@@ -1645,12 +1660,6 @@ void netlink_set_nonroot(int protocol, unsigned int flags)
}
EXPORT_SYMBOL(netlink_set_nonroot);
-static void netlink_destroy_callback(struct netlink_callback *cb)
-{
- kfree_skb(cb->skb);
- kfree(cb);
-}
-
struct nlmsghdr *
__nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags)
{
@@ -1727,7 +1736,7 @@ static int netlink_dump(struct sock *sk)
nlk->cb = NULL;
mutex_unlock(nlk->cb_mutex);
- netlink_destroy_callback(cb);
+ netlink_consume_callback(cb);
return 0;
errout_skb:
@@ -1996,11 +2005,11 @@ static void netlink_seq_stop(struct seq_file *seq, void *v)
static int netlink_seq_show(struct seq_file *seq, void *v)
{
- if (v == SEQ_START_TOKEN)
+ if (v == SEQ_START_TOKEN) {
seq_puts(seq,
"sk Eth Pid Groups "
"Rmem Wmem Dump Locks Drops Inode\n");
- else {
+ } else {
struct sock *s = v;
struct netlink_sock *nlk = nlk_sk(s);
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 9f40441d7a7d..8340ace837f2 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -635,11 +635,12 @@ static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq,
if (hdr == NULL)
return -1;
- NLA_PUT_STRING(skb, CTRL_ATTR_FAMILY_NAME, family->name);
- NLA_PUT_U16(skb, CTRL_ATTR_FAMILY_ID, family->id);
- NLA_PUT_U32(skb, CTRL_ATTR_VERSION, family->version);
- NLA_PUT_U32(skb, CTRL_ATTR_HDRSIZE, family->hdrsize);
- NLA_PUT_U32(skb, CTRL_ATTR_MAXATTR, family->maxattr);
+ if (nla_put_string(skb, CTRL_ATTR_FAMILY_NAME, family->name) ||
+ nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, family->id) ||
+ nla_put_u32(skb, CTRL_ATTR_VERSION, family->version) ||
+ nla_put_u32(skb, CTRL_ATTR_HDRSIZE, family->hdrsize) ||
+ nla_put_u32(skb, CTRL_ATTR_MAXATTR, family->maxattr))
+ goto nla_put_failure;
if (!list_empty(&family->ops_list)) {
struct nlattr *nla_ops;
@@ -657,8 +658,9 @@ static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq,
if (nest == NULL)
goto nla_put_failure;
- NLA_PUT_U32(skb, CTRL_ATTR_OP_ID, ops->cmd);
- NLA_PUT_U32(skb, CTRL_ATTR_OP_FLAGS, ops->flags);
+ if (nla_put_u32(skb, CTRL_ATTR_OP_ID, ops->cmd) ||
+ nla_put_u32(skb, CTRL_ATTR_OP_FLAGS, ops->flags))
+ goto nla_put_failure;
nla_nest_end(skb, nest);
}
@@ -682,9 +684,10 @@ static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq,
if (nest == NULL)
goto nla_put_failure;
- NLA_PUT_U32(skb, CTRL_ATTR_MCAST_GRP_ID, grp->id);
- NLA_PUT_STRING(skb, CTRL_ATTR_MCAST_GRP_NAME,
- grp->name);
+ if (nla_put_u32(skb, CTRL_ATTR_MCAST_GRP_ID, grp->id) ||
+ nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME,
+ grp->name))
+ goto nla_put_failure;
nla_nest_end(skb, nest);
}
@@ -710,8 +713,9 @@ static int ctrl_fill_mcgrp_info(struct genl_multicast_group *grp, u32 pid,
if (hdr == NULL)
return -1;
- NLA_PUT_STRING(skb, CTRL_ATTR_FAMILY_NAME, grp->family->name);
- NLA_PUT_U16(skb, CTRL_ATTR_FAMILY_ID, grp->family->id);
+ if (nla_put_string(skb, CTRL_ATTR_FAMILY_NAME, grp->family->name) ||
+ nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, grp->family->id))
+ goto nla_put_failure;
nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS);
if (nla_grps == NULL)
@@ -721,9 +725,10 @@ static int ctrl_fill_mcgrp_info(struct genl_multicast_group *grp, u32 pid,
if (nest == NULL)
goto nla_put_failure;
- NLA_PUT_U32(skb, CTRL_ATTR_MCAST_GRP_ID, grp->id);
- NLA_PUT_STRING(skb, CTRL_ATTR_MCAST_GRP_NAME,
- grp->name);
+ if (nla_put_u32(skb, CTRL_ATTR_MCAST_GRP_ID, grp->id) ||
+ nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME,
+ grp->name))
+ goto nla_put_failure;
nla_nest_end(skb, nest);
nla_nest_end(skb, nla_grps);