diff options
Diffstat (limited to 'net/netlink')
-rw-r--r-- | net/netlink/af_netlink.c | 35 |
1 files changed, 15 insertions, 20 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 478181d53c55..5fe4f3b04ed3 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -1362,17 +1362,8 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1362 | 1362 | ||
1363 | NETLINK_CB(skb).pid = nlk->pid; | 1363 | NETLINK_CB(skb).pid = nlk->pid; |
1364 | NETLINK_CB(skb).dst_group = dst_group; | 1364 | NETLINK_CB(skb).dst_group = dst_group; |
1365 | NETLINK_CB(skb).loginuid = audit_get_loginuid(current); | ||
1366 | NETLINK_CB(skb).sessionid = audit_get_sessionid(current); | ||
1367 | security_task_getsecid(current, &(NETLINK_CB(skb).sid)); | ||
1368 | memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); | 1365 | memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); |
1369 | 1366 | ||
1370 | /* What can I do? Netlink is asynchronous, so that | ||
1371 | we will have to save current capabilities to | ||
1372 | check them, when this message will be delivered | ||
1373 | to corresponding kernel module. --ANK (980802) | ||
1374 | */ | ||
1375 | |||
1376 | err = -EFAULT; | 1367 | err = -EFAULT; |
1377 | if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { | 1368 | if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { |
1378 | kfree_skb(skb); | 1369 | kfree_skb(skb); |
@@ -1407,7 +1398,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, | |||
1407 | int noblock = flags&MSG_DONTWAIT; | 1398 | int noblock = flags&MSG_DONTWAIT; |
1408 | size_t copied; | 1399 | size_t copied; |
1409 | struct sk_buff *skb, *data_skb; | 1400 | struct sk_buff *skb, *data_skb; |
1410 | int err; | 1401 | int err, ret; |
1411 | 1402 | ||
1412 | if (flags&MSG_OOB) | 1403 | if (flags&MSG_OOB) |
1413 | return -EOPNOTSUPP; | 1404 | return -EOPNOTSUPP; |
@@ -1470,8 +1461,13 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, | |||
1470 | 1461 | ||
1471 | skb_free_datagram(sk, skb); | 1462 | skb_free_datagram(sk, skb); |
1472 | 1463 | ||
1473 | if (nlk->cb && atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) | 1464 | if (nlk->cb && atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) { |
1474 | netlink_dump(sk); | 1465 | ret = netlink_dump(sk); |
1466 | if (ret) { | ||
1467 | sk->sk_err = ret; | ||
1468 | sk->sk_error_report(sk); | ||
1469 | } | ||
1470 | } | ||
1475 | 1471 | ||
1476 | scm_recv(sock, msg, siocb->scm, flags); | 1472 | scm_recv(sock, msg, siocb->scm, flags); |
1477 | out: | 1473 | out: |
@@ -1570,12 +1566,6 @@ netlink_kernel_release(struct sock *sk) | |||
1570 | } | 1566 | } |
1571 | EXPORT_SYMBOL(netlink_kernel_release); | 1567 | EXPORT_SYMBOL(netlink_kernel_release); |
1572 | 1568 | ||
1573 | |||
1574 | static void listeners_free_rcu(struct rcu_head *head) | ||
1575 | { | ||
1576 | kfree(container_of(head, struct listeners, rcu)); | ||
1577 | } | ||
1578 | |||
1579 | int __netlink_change_ngroups(struct sock *sk, unsigned int groups) | 1569 | int __netlink_change_ngroups(struct sock *sk, unsigned int groups) |
1580 | { | 1570 | { |
1581 | struct listeners *new, *old; | 1571 | struct listeners *new, *old; |
@@ -1592,7 +1582,7 @@ int __netlink_change_ngroups(struct sock *sk, unsigned int groups) | |||
1592 | memcpy(new->masks, old->masks, NLGRPSZ(tbl->groups)); | 1582 | memcpy(new->masks, old->masks, NLGRPSZ(tbl->groups)); |
1593 | rcu_assign_pointer(tbl->listeners, new); | 1583 | rcu_assign_pointer(tbl->listeners, new); |
1594 | 1584 | ||
1595 | call_rcu(&old->rcu, listeners_free_rcu); | 1585 | kfree_rcu(old, rcu); |
1596 | } | 1586 | } |
1597 | tbl->groups = groups; | 1587 | tbl->groups = groups; |
1598 | 1588 | ||
@@ -1736,6 +1726,7 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, | |||
1736 | struct netlink_callback *cb; | 1726 | struct netlink_callback *cb; |
1737 | struct sock *sk; | 1727 | struct sock *sk; |
1738 | struct netlink_sock *nlk; | 1728 | struct netlink_sock *nlk; |
1729 | int ret; | ||
1739 | 1730 | ||
1740 | cb = kzalloc(sizeof(*cb), GFP_KERNEL); | 1731 | cb = kzalloc(sizeof(*cb), GFP_KERNEL); |
1741 | if (cb == NULL) | 1732 | if (cb == NULL) |
@@ -1764,9 +1755,13 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, | |||
1764 | nlk->cb = cb; | 1755 | nlk->cb = cb; |
1765 | mutex_unlock(nlk->cb_mutex); | 1756 | mutex_unlock(nlk->cb_mutex); |
1766 | 1757 | ||
1767 | netlink_dump(sk); | 1758 | ret = netlink_dump(sk); |
1759 | |||
1768 | sock_put(sk); | 1760 | sock_put(sk); |
1769 | 1761 | ||
1762 | if (ret) | ||
1763 | return ret; | ||
1764 | |||
1770 | /* We successfully started a dump, by returning -EINTR we | 1765 | /* We successfully started a dump, by returning -EINTR we |
1771 | * signal not to send ACK even if it was requested. | 1766 | * signal not to send ACK even if it was requested. |
1772 | */ | 1767 | */ |