return sk;
}
-extern struct proto_ops netlink_ops;
+static struct proto_ops netlink_ops;
static int netlink_insert(struct sock *sk, u32 pid)
{
struct sockaddr_nl *nladdr=(struct sockaddr_nl*)addr;
if (addr->sa_family == AF_UNSPEC) {
+ sk->sk_state = NETLINK_UNCONNECTED;
nlk->dst_pid = 0;
nlk->dst_groups = 0;
return 0;
err = netlink_autobind(sock);
if (err == 0) {
+ sk->sk_state = NETLINK_CONNECTED;
nlk->dst_pid = nladdr->nl_pid;
nlk->dst_groups = nladdr->nl_groups;
}
- return 0;
+ return err;
}
static int netlink_getname(struct socket *sock, struct sockaddr *addr, int *addr_len, int peer)
/* Don't bother queuing skb if kernel socket has no input function */
nlk = nlk_sk(sock);
- if (nlk->pid == 0 && !nlk->data_ready) {
+ if ((nlk->pid == 0 && !nlk->data_ready) ||
+ (sock->sk_state == NETLINK_CONNECTED &&
+ nlk->dst_pid != nlk_sk(ssk)->pid)) {
sock_put(sock);
return ERR_PTR(-ECONNREFUSED);
}
to corresponding kernel module. --ANK (980802)
*/
- err = security_netlink_send(skb);
- if (err) {
+ err = -EFAULT;
+ if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) {
kfree_skb(skb);
goto out;
}
- err = -EFAULT;
- if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) {
+ err = security_netlink_send(sk, skb);
+ if (err) {
kfree_skb(skb);
goto out;
}