aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/netlink/af_netlink.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index c41a88100fea..3c56b96b4a4b 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -67,7 +67,7 @@ struct netlink_sock {
67 u32 pid; 67 u32 pid;
68 unsigned int groups; 68 unsigned int groups;
69 u32 dst_pid; 69 u32 dst_pid;
70 unsigned int dst_groups; 70 u32 dst_group;
71 unsigned long state; 71 unsigned long state;
72 wait_queue_head_t wait; 72 wait_queue_head_t wait;
73 struct netlink_callback *cb; 73 struct netlink_callback *cb;
@@ -116,6 +116,11 @@ static atomic_t nl_table_users = ATOMIC_INIT(0);
116 116
117static struct notifier_block *netlink_chain; 117static struct notifier_block *netlink_chain;
118 118
119static u32 netlink_group_mask(u32 group)
120{
121 return group ? 1 << (group - 1) : 0;
122}
123
119static struct hlist_head *nl_pid_hashfn(struct nl_pid_hash *hash, u32 pid) 124static struct hlist_head *nl_pid_hashfn(struct nl_pid_hash *hash, u32 pid)
120{ 125{
121 return &hash->table[jhash_1word(pid, hash->rnd) & hash->mask]; 126 return &hash->table[jhash_1word(pid, hash->rnd) & hash->mask];
@@ -533,7 +538,7 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
533 if (addr->sa_family == AF_UNSPEC) { 538 if (addr->sa_family == AF_UNSPEC) {
534 sk->sk_state = NETLINK_UNCONNECTED; 539 sk->sk_state = NETLINK_UNCONNECTED;
535 nlk->dst_pid = 0; 540 nlk->dst_pid = 0;
536 nlk->dst_groups = 0; 541 nlk->dst_group = 0;
537 return 0; 542 return 0;
538 } 543 }
539 if (addr->sa_family != AF_NETLINK) 544 if (addr->sa_family != AF_NETLINK)
@@ -549,7 +554,7 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
549 if (err == 0) { 554 if (err == 0) {
550 sk->sk_state = NETLINK_CONNECTED; 555 sk->sk_state = NETLINK_CONNECTED;
551 nlk->dst_pid = nladdr->nl_pid; 556 nlk->dst_pid = nladdr->nl_pid;
552 nlk->dst_groups = nladdr->nl_groups; 557 nlk->dst_group = ffs(nladdr->nl_groups);
553 } 558 }
554 559
555 return err; 560 return err;
@@ -567,10 +572,10 @@ static int netlink_getname(struct socket *sock, struct sockaddr *addr, int *addr
567 572
568 if (peer) { 573 if (peer) {
569 nladdr->nl_pid = nlk->dst_pid; 574 nladdr->nl_pid = nlk->dst_pid;
570 nladdr->nl_groups = nlk->dst_groups; 575 nladdr->nl_groups = netlink_group_mask(nlk->dst_group);
571 } else { 576 } else {
572 nladdr->nl_pid = nlk->pid; 577 nladdr->nl_pid = nlk->pid;
573 nladdr->nl_groups = nlk->groups; 578 nladdr->nl_groups = nlk->groups;
574 } 579 }
575 return 0; 580 return 0;
576} 581}
@@ -771,7 +776,7 @@ static inline int do_one_broadcast(struct sock *sk,
771 if (p->exclude_sk == sk) 776 if (p->exclude_sk == sk)
772 goto out; 777 goto out;
773 778
774 if (nlk->pid == p->pid || !(nlk->groups & p->group)) 779 if (nlk->pid == p->pid || !(nlk->groups & netlink_group_mask(p->group)))
775 goto out; 780 goto out;
776 781
777 if (p->failure) { 782 if (p->failure) {
@@ -867,7 +872,7 @@ static inline int do_one_set_err(struct sock *sk,
867 if (sk == p->exclude_sk) 872 if (sk == p->exclude_sk)
868 goto out; 873 goto out;
869 874
870 if (nlk->pid == p->pid || !(nlk->groups & p->group)) 875 if (nlk->pid == p->pid || !(nlk->groups & netlink_group_mask(p->group)))
871 goto out; 876 goto out;
872 877
873 sk->sk_err = p->code; 878 sk->sk_err = p->code;
@@ -913,7 +918,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
913 struct netlink_sock *nlk = nlk_sk(sk); 918 struct netlink_sock *nlk = nlk_sk(sk);
914 struct sockaddr_nl *addr=msg->msg_name; 919 struct sockaddr_nl *addr=msg->msg_name;
915 u32 dst_pid; 920 u32 dst_pid;
916 u32 dst_groups; 921 u32 dst_group;
917 struct sk_buff *skb; 922 struct sk_buff *skb;
918 int err; 923 int err;
919 struct scm_cookie scm; 924 struct scm_cookie scm;
@@ -931,12 +936,12 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
931 if (addr->nl_family != AF_NETLINK) 936 if (addr->nl_family != AF_NETLINK)
932 return -EINVAL; 937 return -EINVAL;
933 dst_pid = addr->nl_pid; 938 dst_pid = addr->nl_pid;
934 dst_groups = addr->nl_groups; 939 dst_group = ffs(addr->nl_groups);
935 if (dst_groups && !netlink_capable(sock, NL_NONROOT_SEND)) 940 if (dst_group && !netlink_capable(sock, NL_NONROOT_SEND))
936 return -EPERM; 941 return -EPERM;
937 } else { 942 } else {
938 dst_pid = nlk->dst_pid; 943 dst_pid = nlk->dst_pid;
939 dst_groups = nlk->dst_groups; 944 dst_group = nlk->dst_group;
940 } 945 }
941 946
942 if (!nlk->pid) { 947 if (!nlk->pid) {
@@ -955,7 +960,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
955 960
956 NETLINK_CB(skb).pid = nlk->pid; 961 NETLINK_CB(skb).pid = nlk->pid;
957 NETLINK_CB(skb).dst_pid = dst_pid; 962 NETLINK_CB(skb).dst_pid = dst_pid;
958 NETLINK_CB(skb).dst_groups = dst_groups; 963 NETLINK_CB(skb).dst_group = dst_group;
959 NETLINK_CB(skb).loginuid = audit_get_loginuid(current->audit_context); 964 NETLINK_CB(skb).loginuid = audit_get_loginuid(current->audit_context);
960 memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); 965 memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
961 966
@@ -977,9 +982,9 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
977 goto out; 982 goto out;
978 } 983 }
979 984
980 if (dst_groups) { 985 if (dst_group) {
981 atomic_inc(&skb->users); 986 atomic_inc(&skb->users);
982 netlink_broadcast(sk, skb, dst_pid, dst_groups, GFP_KERNEL); 987 netlink_broadcast(sk, skb, dst_pid, dst_group, GFP_KERNEL);
983 } 988 }
984 err = netlink_unicast(sk, skb, dst_pid, msg->msg_flags&MSG_DONTWAIT); 989 err = netlink_unicast(sk, skb, dst_pid, msg->msg_flags&MSG_DONTWAIT);
985 990
@@ -1025,7 +1030,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
1025 addr->nl_family = AF_NETLINK; 1030 addr->nl_family = AF_NETLINK;
1026 addr->nl_pad = 0; 1031 addr->nl_pad = 0;
1027 addr->nl_pid = NETLINK_CB(skb).pid; 1032 addr->nl_pid = NETLINK_CB(skb).pid;
1028 addr->nl_groups = NETLINK_CB(skb).dst_groups; 1033 addr->nl_groups = netlink_group_mask(NETLINK_CB(skb).dst_group);
1029 msg->msg_namelen = sizeof(*addr); 1034 msg->msg_namelen = sizeof(*addr);
1030 } 1035 }
1031 1036