diff options
Diffstat (limited to 'net/netlink')
-rw-r--r-- | net/netlink/af_netlink.c | 22 | ||||
-rw-r--r-- | net/netlink/genetlink.c | 7 |
2 files changed, 23 insertions, 6 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 320d0423a240..6464a1972a69 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -545,7 +545,7 @@ static int netlink_autobind(struct socket *sock) struct hlist_head *head; struct sock *osk; struct hlist_node *node; - s32 pid = current->tgid; + s32 pid = task_tgid_vnr(current); int err; static s32 rover = -4097; @@ -683,6 +683,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr, struct netlink_sock *nlk = nlk_sk(sk); struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr; + if (alen < sizeof(addr->sa_family)) + return -EINVAL; + if (addr->sa_family == AF_UNSPEC) { sk->sk_state = NETLINK_UNCONNECTED; nlk->dst_pid = 0; @@ -1093,6 +1096,7 @@ static inline int do_one_set_err(struct sock *sk, struct netlink_set_err_data *p) { struct netlink_sock *nlk = nlk_sk(sk); + int ret = 0; if (sk == p->exclude_sk) goto out; @@ -1104,10 +1108,15 @@ static inline int do_one_set_err(struct sock *sk, !test_bit(p->group - 1, nlk->groups)) goto out; + if (p->code == ENOBUFS && nlk->flags & NETLINK_RECV_NO_ENOBUFS) { + ret = 1; + goto out; + } + sk->sk_err = p->code; sk->sk_error_report(sk); out: - return 0; + return ret; } /** @@ -1116,12 +1125,16 @@ out: * @pid: the PID of a process that we want to skip (if any) * @groups: the broadcast group that will notice the error * @code: error code, must be negative (as usual in kernelspace) + * + * This function returns the number of broadcast listeners that have set the + * NETLINK_RECV_NO_ENOBUFS socket option. */ -void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code) +int netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code) { struct netlink_set_err_data info; struct hlist_node *node; struct sock *sk; + int ret = 0; info.exclude_sk = ssk; info.pid = pid; @@ -1132,9 +1145,10 @@ void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code) read_lock(&nl_table_lock); sk_for_each_bound(sk, node, &nl_table[ssk->sk_protocol].mc_list) - do_one_set_err(sk, &info); + ret += do_one_set_err(sk, &info); read_unlock(&nl_table_lock); + return ret; } EXPORT_SYMBOL(netlink_set_err); diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index a4b6e148c5de..aa4308afcc7f 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -8,6 +8,7 @@ #include <linux/module.h> #include <linux/kernel.h> +#include <linux/slab.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> @@ -20,15 +21,17 @@ static DEFINE_MUTEX(genl_mutex); /* serialization of message processing */ -static inline void genl_lock(void) +void genl_lock(void) { mutex_lock(&genl_mutex); } +EXPORT_SYMBOL(genl_lock); -static inline void genl_unlock(void) +void genl_unlock(void) { mutex_unlock(&genl_mutex); } +EXPORT_SYMBOL(genl_unlock); #define GENL_FAM_TAB_SIZE 16 #define GENL_FAM_TAB_MASK (GENL_FAM_TAB_SIZE - 1) |