diff options
author | Samuel Ortiz <samuel@sortiz.org> | 2010-10-10 18:46:51 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2010-10-10 20:11:23 -0400 |
commit | 5b40964eadea40509d353318d2c82e8b7bf5e8a5 (patch) | |
tree | d3f17ae32707aa413572a27f056ad30cf89b3fca | |
parent | 7b738b55b2ec0e95a5030037c45b3c312e385789 (diff) |
irda: Remove BKL instances from af_irda.c
Most of the times, lock_kernel() was pointless or could simply be replaced
by lock_sock().
Signed-off-by: Samuel Ortiz <samuel@sortiz.org>
-rw-r--r-- | net/irda/af_irda.c | 370 |
1 files changed, 196 insertions, 174 deletions
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index bf3635129b17..7f097989cde2 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
@@ -715,14 +715,11 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr, | |||
715 | struct sockaddr_irda saddr; | 715 | struct sockaddr_irda saddr; |
716 | struct sock *sk = sock->sk; | 716 | struct sock *sk = sock->sk; |
717 | struct irda_sock *self = irda_sk(sk); | 717 | struct irda_sock *self = irda_sk(sk); |
718 | int err; | ||
719 | 718 | ||
720 | lock_kernel(); | ||
721 | memset(&saddr, 0, sizeof(saddr)); | 719 | memset(&saddr, 0, sizeof(saddr)); |
722 | if (peer) { | 720 | if (peer) { |
723 | err = -ENOTCONN; | ||
724 | if (sk->sk_state != TCP_ESTABLISHED) | 721 | if (sk->sk_state != TCP_ESTABLISHED) |
725 | goto out; | 722 | return -ENOTCONN; |
726 | 723 | ||
727 | saddr.sir_family = AF_IRDA; | 724 | saddr.sir_family = AF_IRDA; |
728 | saddr.sir_lsap_sel = self->dtsap_sel; | 725 | saddr.sir_lsap_sel = self->dtsap_sel; |
@@ -739,10 +736,8 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr, | |||
739 | /* uaddr_len come to us uninitialised */ | 736 | /* uaddr_len come to us uninitialised */ |
740 | *uaddr_len = sizeof (struct sockaddr_irda); | 737 | *uaddr_len = sizeof (struct sockaddr_irda); |
741 | memcpy(uaddr, &saddr, *uaddr_len); | 738 | memcpy(uaddr, &saddr, *uaddr_len); |
742 | err = 0; | 739 | |
743 | out: | 740 | return 0; |
744 | unlock_kernel(); | ||
745 | return err; | ||
746 | } | 741 | } |
747 | 742 | ||
748 | /* | 743 | /* |
@@ -758,7 +753,8 @@ static int irda_listen(struct socket *sock, int backlog) | |||
758 | 753 | ||
759 | IRDA_DEBUG(2, "%s()\n", __func__); | 754 | IRDA_DEBUG(2, "%s()\n", __func__); |
760 | 755 | ||
761 | lock_kernel(); | 756 | lock_sock(sk); |
757 | |||
762 | if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) && | 758 | if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) && |
763 | (sk->sk_type != SOCK_DGRAM)) | 759 | (sk->sk_type != SOCK_DGRAM)) |
764 | goto out; | 760 | goto out; |
@@ -770,7 +766,7 @@ static int irda_listen(struct socket *sock, int backlog) | |||
770 | err = 0; | 766 | err = 0; |
771 | } | 767 | } |
772 | out: | 768 | out: |
773 | unlock_kernel(); | 769 | release_sock(sk); |
774 | 770 | ||
775 | return err; | 771 | return err; |
776 | } | 772 | } |
@@ -793,7 +789,7 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
793 | if (addr_len != sizeof(struct sockaddr_irda)) | 789 | if (addr_len != sizeof(struct sockaddr_irda)) |
794 | return -EINVAL; | 790 | return -EINVAL; |
795 | 791 | ||
796 | lock_kernel(); | 792 | lock_sock(sk); |
797 | #ifdef CONFIG_IRDA_ULTRA | 793 | #ifdef CONFIG_IRDA_ULTRA |
798 | /* Special care for Ultra sockets */ | 794 | /* Special care for Ultra sockets */ |
799 | if ((sk->sk_type == SOCK_DGRAM) && | 795 | if ((sk->sk_type == SOCK_DGRAM) && |
@@ -836,7 +832,7 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
836 | 832 | ||
837 | err = 0; | 833 | err = 0; |
838 | out: | 834 | out: |
839 | unlock_kernel(); | 835 | release_sock(sk); |
840 | return err; | 836 | return err; |
841 | } | 837 | } |
842 | 838 | ||
@@ -856,12 +852,13 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) | |||
856 | 852 | ||
857 | IRDA_DEBUG(2, "%s()\n", __func__); | 853 | IRDA_DEBUG(2, "%s()\n", __func__); |
858 | 854 | ||
859 | lock_kernel(); | ||
860 | err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0); | 855 | err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0); |
861 | if (err) | 856 | if (err) |
862 | goto out; | 857 | return err; |
863 | 858 | ||
864 | err = -EINVAL; | 859 | err = -EINVAL; |
860 | |||
861 | lock_sock(sk); | ||
865 | if (sock->state != SS_UNCONNECTED) | 862 | if (sock->state != SS_UNCONNECTED) |
866 | goto out; | 863 | goto out; |
867 | 864 | ||
@@ -947,7 +944,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) | |||
947 | irda_connect_response(new); | 944 | irda_connect_response(new); |
948 | err = 0; | 945 | err = 0; |
949 | out: | 946 | out: |
950 | unlock_kernel(); | 947 | release_sock(sk); |
951 | return err; | 948 | return err; |
952 | } | 949 | } |
953 | 950 | ||
@@ -981,7 +978,7 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, | |||
981 | 978 | ||
982 | IRDA_DEBUG(2, "%s(%p)\n", __func__, self); | 979 | IRDA_DEBUG(2, "%s(%p)\n", __func__, self); |
983 | 980 | ||
984 | lock_kernel(); | 981 | lock_sock(sk); |
985 | /* Don't allow connect for Ultra sockets */ | 982 | /* Don't allow connect for Ultra sockets */ |
986 | err = -ESOCKTNOSUPPORT; | 983 | err = -ESOCKTNOSUPPORT; |
987 | if ((sk->sk_type == SOCK_DGRAM) && (sk->sk_protocol == IRDAPROTO_ULTRA)) | 984 | if ((sk->sk_type == SOCK_DGRAM) && (sk->sk_protocol == IRDAPROTO_ULTRA)) |
@@ -1072,6 +1069,8 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, | |||
1072 | 1069 | ||
1073 | if (sk->sk_state != TCP_ESTABLISHED) { | 1070 | if (sk->sk_state != TCP_ESTABLISHED) { |
1074 | sock->state = SS_UNCONNECTED; | 1071 | sock->state = SS_UNCONNECTED; |
1072 | if (sk->sk_prot->disconnect(sk, flags)) | ||
1073 | sock->state = SS_DISCONNECTING; | ||
1075 | err = sock_error(sk); | 1074 | err = sock_error(sk); |
1076 | if (!err) | 1075 | if (!err) |
1077 | err = -ECONNRESET; | 1076 | err = -ECONNRESET; |
@@ -1084,7 +1083,7 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, | |||
1084 | self->saddr = irttp_get_saddr(self->tsap); | 1083 | self->saddr = irttp_get_saddr(self->tsap); |
1085 | err = 0; | 1084 | err = 0; |
1086 | out: | 1085 | out: |
1087 | unlock_kernel(); | 1086 | release_sock(sk); |
1088 | return err; | 1087 | return err; |
1089 | } | 1088 | } |
1090 | 1089 | ||
@@ -1231,7 +1230,6 @@ static int irda_release(struct socket *sock) | |||
1231 | if (sk == NULL) | 1230 | if (sk == NULL) |
1232 | return 0; | 1231 | return 0; |
1233 | 1232 | ||
1234 | lock_kernel(); | ||
1235 | lock_sock(sk); | 1233 | lock_sock(sk); |
1236 | sk->sk_state = TCP_CLOSE; | 1234 | sk->sk_state = TCP_CLOSE; |
1237 | sk->sk_shutdown |= SEND_SHUTDOWN; | 1235 | sk->sk_shutdown |= SEND_SHUTDOWN; |
@@ -1250,7 +1248,6 @@ static int irda_release(struct socket *sock) | |||
1250 | /* Destroy networking socket if we are the last reference on it, | 1248 | /* Destroy networking socket if we are the last reference on it, |
1251 | * i.e. if(sk->sk_refcnt == 0) -> sk_free(sk) */ | 1249 | * i.e. if(sk->sk_refcnt == 0) -> sk_free(sk) */ |
1252 | sock_put(sk); | 1250 | sock_put(sk); |
1253 | unlock_kernel(); | ||
1254 | 1251 | ||
1255 | /* Notes on socket locking and deallocation... - Jean II | 1252 | /* Notes on socket locking and deallocation... - Jean II |
1256 | * In theory we should put pairs of sock_hold() / sock_put() to | 1253 | * In theory we should put pairs of sock_hold() / sock_put() to |
@@ -1298,7 +1295,6 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1298 | 1295 | ||
1299 | IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); | 1296 | IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); |
1300 | 1297 | ||
1301 | lock_kernel(); | ||
1302 | /* Note : socket.c set MSG_EOR on SEQPACKET sockets */ | 1298 | /* Note : socket.c set MSG_EOR on SEQPACKET sockets */ |
1303 | if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_EOR | MSG_CMSG_COMPAT | | 1299 | if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_EOR | MSG_CMSG_COMPAT | |
1304 | MSG_NOSIGNAL)) { | 1300 | MSG_NOSIGNAL)) { |
@@ -1306,6 +1302,8 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1306 | goto out; | 1302 | goto out; |
1307 | } | 1303 | } |
1308 | 1304 | ||
1305 | lock_sock(sk); | ||
1306 | |||
1309 | if (sk->sk_shutdown & SEND_SHUTDOWN) | 1307 | if (sk->sk_shutdown & SEND_SHUTDOWN) |
1310 | goto out_err; | 1308 | goto out_err; |
1311 | 1309 | ||
@@ -1361,14 +1359,14 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1361 | goto out_err; | 1359 | goto out_err; |
1362 | } | 1360 | } |
1363 | 1361 | ||
1364 | unlock_kernel(); | 1362 | release_sock(sk); |
1365 | /* Tell client how much data we actually sent */ | 1363 | /* Tell client how much data we actually sent */ |
1366 | return len; | 1364 | return len; |
1367 | 1365 | ||
1368 | out_err: | 1366 | out_err: |
1369 | err = sk_stream_error(sk, msg->msg_flags, err); | 1367 | err = sk_stream_error(sk, msg->msg_flags, err); |
1370 | out: | 1368 | out: |
1371 | unlock_kernel(); | 1369 | release_sock(sk); |
1372 | return err; | 1370 | return err; |
1373 | 1371 | ||
1374 | } | 1372 | } |
@@ -1390,14 +1388,10 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock, | |||
1390 | 1388 | ||
1391 | IRDA_DEBUG(4, "%s()\n", __func__); | 1389 | IRDA_DEBUG(4, "%s()\n", __func__); |
1392 | 1390 | ||
1393 | lock_kernel(); | ||
1394 | if ((err = sock_error(sk)) < 0) | ||
1395 | goto out; | ||
1396 | |||
1397 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, | 1391 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, |
1398 | flags & MSG_DONTWAIT, &err); | 1392 | flags & MSG_DONTWAIT, &err); |
1399 | if (!skb) | 1393 | if (!skb) |
1400 | goto out; | 1394 | return err; |
1401 | 1395 | ||
1402 | skb_reset_transport_header(skb); | 1396 | skb_reset_transport_header(skb); |
1403 | copied = skb->len; | 1397 | copied = skb->len; |
@@ -1425,12 +1419,8 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock, | |||
1425 | irttp_flow_request(self->tsap, FLOW_START); | 1419 | irttp_flow_request(self->tsap, FLOW_START); |
1426 | } | 1420 | } |
1427 | } | 1421 | } |
1428 | unlock_kernel(); | ||
1429 | return copied; | ||
1430 | 1422 | ||
1431 | out: | 1423 | return copied; |
1432 | unlock_kernel(); | ||
1433 | return err; | ||
1434 | } | 1424 | } |
1435 | 1425 | ||
1436 | /* | 1426 | /* |
@@ -1448,17 +1438,15 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, | |||
1448 | 1438 | ||
1449 | IRDA_DEBUG(3, "%s()\n", __func__); | 1439 | IRDA_DEBUG(3, "%s()\n", __func__); |
1450 | 1440 | ||
1451 | lock_kernel(); | ||
1452 | if ((err = sock_error(sk)) < 0) | 1441 | if ((err = sock_error(sk)) < 0) |
1453 | goto out; | 1442 | return err; |
1454 | 1443 | ||
1455 | err = -EINVAL; | ||
1456 | if (sock->flags & __SO_ACCEPTCON) | 1444 | if (sock->flags & __SO_ACCEPTCON) |
1457 | goto out; | 1445 | return -EINVAL; |
1458 | 1446 | ||
1459 | err =-EOPNOTSUPP; | 1447 | err =-EOPNOTSUPP; |
1460 | if (flags & MSG_OOB) | 1448 | if (flags & MSG_OOB) |
1461 | goto out; | 1449 | return -EOPNOTSUPP; |
1462 | 1450 | ||
1463 | err = 0; | 1451 | err = 0; |
1464 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, size); | 1452 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, size); |
@@ -1500,7 +1488,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, | |||
1500 | finish_wait(sk_sleep(sk), &wait); | 1488 | finish_wait(sk_sleep(sk), &wait); |
1501 | 1489 | ||
1502 | if (err) | 1490 | if (err) |
1503 | goto out; | 1491 | return err; |
1504 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 1492 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
1505 | break; | 1493 | break; |
1506 | 1494 | ||
@@ -1553,9 +1541,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, | |||
1553 | } | 1541 | } |
1554 | } | 1542 | } |
1555 | 1543 | ||
1556 | out: | 1544 | return copied; |
1557 | unlock_kernel(); | ||
1558 | return err ? : copied; | ||
1559 | } | 1545 | } |
1560 | 1546 | ||
1561 | /* | 1547 | /* |
@@ -1573,13 +1559,12 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock, | |||
1573 | struct sk_buff *skb; | 1559 | struct sk_buff *skb; |
1574 | int err; | 1560 | int err; |
1575 | 1561 | ||
1576 | lock_kernel(); | ||
1577 | |||
1578 | IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); | 1562 | IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); |
1579 | 1563 | ||
1580 | err = -EINVAL; | ||
1581 | if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) | 1564 | if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) |
1582 | goto out; | 1565 | return -EINVAL; |
1566 | |||
1567 | lock_sock(sk); | ||
1583 | 1568 | ||
1584 | if (sk->sk_shutdown & SEND_SHUTDOWN) { | 1569 | if (sk->sk_shutdown & SEND_SHUTDOWN) { |
1585 | send_sig(SIGPIPE, current, 0); | 1570 | send_sig(SIGPIPE, current, 0); |
@@ -1630,10 +1615,12 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock, | |||
1630 | IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err); | 1615 | IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err); |
1631 | goto out; | 1616 | goto out; |
1632 | } | 1617 | } |
1633 | unlock_kernel(); | 1618 | |
1619 | release_sock(sk); | ||
1634 | return len; | 1620 | return len; |
1621 | |||
1635 | out: | 1622 | out: |
1636 | unlock_kernel(); | 1623 | release_sock(sk); |
1637 | return err; | 1624 | return err; |
1638 | } | 1625 | } |
1639 | 1626 | ||
@@ -1656,10 +1643,11 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, | |||
1656 | 1643 | ||
1657 | IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); | 1644 | IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); |
1658 | 1645 | ||
1659 | lock_kernel(); | ||
1660 | err = -EINVAL; | 1646 | err = -EINVAL; |
1661 | if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) | 1647 | if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) |
1662 | goto out; | 1648 | return -EINVAL; |
1649 | |||
1650 | lock_sock(sk); | ||
1663 | 1651 | ||
1664 | err = -EPIPE; | 1652 | err = -EPIPE; |
1665 | if (sk->sk_shutdown & SEND_SHUTDOWN) { | 1653 | if (sk->sk_shutdown & SEND_SHUTDOWN) { |
@@ -1732,7 +1720,7 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, | |||
1732 | if (err) | 1720 | if (err) |
1733 | IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err); | 1721 | IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err); |
1734 | out: | 1722 | out: |
1735 | unlock_kernel(); | 1723 | release_sock(sk); |
1736 | return err ? : len; | 1724 | return err ? : len; |
1737 | } | 1725 | } |
1738 | #endif /* CONFIG_IRDA_ULTRA */ | 1726 | #endif /* CONFIG_IRDA_ULTRA */ |
@@ -1747,7 +1735,7 @@ static int irda_shutdown(struct socket *sock, int how) | |||
1747 | 1735 | ||
1748 | IRDA_DEBUG(1, "%s(%p)\n", __func__, self); | 1736 | IRDA_DEBUG(1, "%s(%p)\n", __func__, self); |
1749 | 1737 | ||
1750 | lock_kernel(); | 1738 | lock_sock(sk); |
1751 | 1739 | ||
1752 | sk->sk_state = TCP_CLOSE; | 1740 | sk->sk_state = TCP_CLOSE; |
1753 | sk->sk_shutdown |= SEND_SHUTDOWN; | 1741 | sk->sk_shutdown |= SEND_SHUTDOWN; |
@@ -1769,7 +1757,7 @@ static int irda_shutdown(struct socket *sock, int how) | |||
1769 | self->daddr = DEV_ADDR_ANY; /* Until we get re-connected */ | 1757 | self->daddr = DEV_ADDR_ANY; /* Until we get re-connected */ |
1770 | self->saddr = 0x0; /* so IrLMP assign us any link */ | 1758 | self->saddr = 0x0; /* so IrLMP assign us any link */ |
1771 | 1759 | ||
1772 | unlock_kernel(); | 1760 | release_sock(sk); |
1773 | 1761 | ||
1774 | return 0; | 1762 | return 0; |
1775 | } | 1763 | } |
@@ -1786,7 +1774,6 @@ static unsigned int irda_poll(struct file * file, struct socket *sock, | |||
1786 | 1774 | ||
1787 | IRDA_DEBUG(4, "%s()\n", __func__); | 1775 | IRDA_DEBUG(4, "%s()\n", __func__); |
1788 | 1776 | ||
1789 | lock_kernel(); | ||
1790 | poll_wait(file, sk_sleep(sk), wait); | 1777 | poll_wait(file, sk_sleep(sk), wait); |
1791 | mask = 0; | 1778 | mask = 0; |
1792 | 1779 | ||
@@ -1834,20 +1821,8 @@ static unsigned int irda_poll(struct file * file, struct socket *sock, | |||
1834 | default: | 1821 | default: |
1835 | break; | 1822 | break; |
1836 | } | 1823 | } |
1837 | unlock_kernel(); | ||
1838 | return mask; | ||
1839 | } | ||
1840 | 1824 | ||
1841 | static unsigned int irda_datagram_poll(struct file *file, struct socket *sock, | 1825 | return mask; |
1842 | poll_table *wait) | ||
1843 | { | ||
1844 | int err; | ||
1845 | |||
1846 | lock_kernel(); | ||
1847 | err = datagram_poll(file, sock, wait); | ||
1848 | unlock_kernel(); | ||
1849 | |||
1850 | return err; | ||
1851 | } | 1826 | } |
1852 | 1827 | ||
1853 | /* | 1828 | /* |
@@ -1860,7 +1835,6 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1860 | 1835 | ||
1861 | IRDA_DEBUG(4, "%s(), cmd=%#x\n", __func__, cmd); | 1836 | IRDA_DEBUG(4, "%s(), cmd=%#x\n", __func__, cmd); |
1862 | 1837 | ||
1863 | lock_kernel(); | ||
1864 | err = -EINVAL; | 1838 | err = -EINVAL; |
1865 | switch (cmd) { | 1839 | switch (cmd) { |
1866 | case TIOCOUTQ: { | 1840 | case TIOCOUTQ: { |
@@ -1903,7 +1877,6 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1903 | IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __func__); | 1877 | IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __func__); |
1904 | err = -ENOIOCTLCMD; | 1878 | err = -ENOIOCTLCMD; |
1905 | } | 1879 | } |
1906 | unlock_kernel(); | ||
1907 | 1880 | ||
1908 | return err; | 1881 | return err; |
1909 | } | 1882 | } |
@@ -1927,7 +1900,7 @@ static int irda_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned lon | |||
1927 | * Set some options for the socket | 1900 | * Set some options for the socket |
1928 | * | 1901 | * |
1929 | */ | 1902 | */ |
1930 | static int __irda_setsockopt(struct socket *sock, int level, int optname, | 1903 | static int irda_setsockopt(struct socket *sock, int level, int optname, |
1931 | char __user *optval, unsigned int optlen) | 1904 | char __user *optval, unsigned int optlen) |
1932 | { | 1905 | { |
1933 | struct sock *sk = sock->sk; | 1906 | struct sock *sk = sock->sk; |
@@ -1935,13 +1908,15 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, | |||
1935 | struct irda_ias_set *ias_opt; | 1908 | struct irda_ias_set *ias_opt; |
1936 | struct ias_object *ias_obj; | 1909 | struct ias_object *ias_obj; |
1937 | struct ias_attrib * ias_attr; /* Attribute in IAS object */ | 1910 | struct ias_attrib * ias_attr; /* Attribute in IAS object */ |
1938 | int opt, free_ias = 0; | 1911 | int opt, free_ias = 0, err = 0; |
1939 | 1912 | ||
1940 | IRDA_DEBUG(2, "%s(%p)\n", __func__, self); | 1913 | IRDA_DEBUG(2, "%s(%p)\n", __func__, self); |
1941 | 1914 | ||
1942 | if (level != SOL_IRLMP) | 1915 | if (level != SOL_IRLMP) |
1943 | return -ENOPROTOOPT; | 1916 | return -ENOPROTOOPT; |
1944 | 1917 | ||
1918 | lock_sock(sk); | ||
1919 | |||
1945 | switch (optname) { | 1920 | switch (optname) { |
1946 | case IRLMP_IAS_SET: | 1921 | case IRLMP_IAS_SET: |
1947 | /* The user want to add an attribute to an existing IAS object | 1922 | /* The user want to add an attribute to an existing IAS object |
@@ -1951,17 +1926,22 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, | |||
1951 | * create the right attribute... | 1926 | * create the right attribute... |
1952 | */ | 1927 | */ |
1953 | 1928 | ||
1954 | if (optlen != sizeof(struct irda_ias_set)) | 1929 | if (optlen != sizeof(struct irda_ias_set)) { |
1955 | return -EINVAL; | 1930 | err = -EINVAL; |
1931 | goto out; | ||
1932 | } | ||
1956 | 1933 | ||
1957 | ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); | 1934 | ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); |
1958 | if (ias_opt == NULL) | 1935 | if (ias_opt == NULL) { |
1959 | return -ENOMEM; | 1936 | err = -ENOMEM; |
1937 | goto out; | ||
1938 | } | ||
1960 | 1939 | ||
1961 | /* Copy query to the driver. */ | 1940 | /* Copy query to the driver. */ |
1962 | if (copy_from_user(ias_opt, optval, optlen)) { | 1941 | if (copy_from_user(ias_opt, optval, optlen)) { |
1963 | kfree(ias_opt); | 1942 | kfree(ias_opt); |
1964 | return -EFAULT; | 1943 | err = -EFAULT; |
1944 | goto out; | ||
1965 | } | 1945 | } |
1966 | 1946 | ||
1967 | /* Find the object we target. | 1947 | /* Find the object we target. |
@@ -1971,7 +1951,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, | |||
1971 | if(ias_opt->irda_class_name[0] == '\0') { | 1951 | if(ias_opt->irda_class_name[0] == '\0') { |
1972 | if(self->ias_obj == NULL) { | 1952 | if(self->ias_obj == NULL) { |
1973 | kfree(ias_opt); | 1953 | kfree(ias_opt); |
1974 | return -EINVAL; | 1954 | err = -EINVAL; |
1955 | goto out; | ||
1975 | } | 1956 | } |
1976 | ias_obj = self->ias_obj; | 1957 | ias_obj = self->ias_obj; |
1977 | } else | 1958 | } else |
@@ -1983,7 +1964,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, | |||
1983 | if((!capable(CAP_NET_ADMIN)) && | 1964 | if((!capable(CAP_NET_ADMIN)) && |
1984 | ((ias_obj == NULL) || (ias_obj != self->ias_obj))) { | 1965 | ((ias_obj == NULL) || (ias_obj != self->ias_obj))) { |
1985 | kfree(ias_opt); | 1966 | kfree(ias_opt); |
1986 | return -EPERM; | 1967 | err = -EPERM; |
1968 | goto out; | ||
1987 | } | 1969 | } |
1988 | 1970 | ||
1989 | /* If the object doesn't exist, create it */ | 1971 | /* If the object doesn't exist, create it */ |
@@ -1993,7 +1975,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, | |||
1993 | jiffies); | 1975 | jiffies); |
1994 | if (ias_obj == NULL) { | 1976 | if (ias_obj == NULL) { |
1995 | kfree(ias_opt); | 1977 | kfree(ias_opt); |
1996 | return -ENOMEM; | 1978 | err = -ENOMEM; |
1979 | goto out; | ||
1997 | } | 1980 | } |
1998 | free_ias = 1; | 1981 | free_ias = 1; |
1999 | } | 1982 | } |
@@ -2005,7 +1988,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, | |||
2005 | kfree(ias_obj->name); | 1988 | kfree(ias_obj->name); |
2006 | kfree(ias_obj); | 1989 | kfree(ias_obj); |
2007 | } | 1990 | } |
2008 | return -EINVAL; | 1991 | err = -EINVAL; |
1992 | goto out; | ||
2009 | } | 1993 | } |
2010 | 1994 | ||
2011 | /* Look at the type */ | 1995 | /* Look at the type */ |
@@ -2028,7 +2012,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, | |||
2028 | kfree(ias_obj); | 2012 | kfree(ias_obj); |
2029 | } | 2013 | } |
2030 | 2014 | ||
2031 | return -EINVAL; | 2015 | err = -EINVAL; |
2016 | goto out; | ||
2032 | } | 2017 | } |
2033 | /* Add an octet sequence attribute */ | 2018 | /* Add an octet sequence attribute */ |
2034 | irias_add_octseq_attrib( | 2019 | irias_add_octseq_attrib( |
@@ -2060,7 +2045,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, | |||
2060 | kfree(ias_obj->name); | 2045 | kfree(ias_obj->name); |
2061 | kfree(ias_obj); | 2046 | kfree(ias_obj); |
2062 | } | 2047 | } |
2063 | return -EINVAL; | 2048 | err = -EINVAL; |
2049 | goto out; | ||
2064 | } | 2050 | } |
2065 | irias_insert_object(ias_obj); | 2051 | irias_insert_object(ias_obj); |
2066 | kfree(ias_opt); | 2052 | kfree(ias_opt); |
@@ -2071,17 +2057,22 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, | |||
2071 | * object is not owned by the kernel and delete it. | 2057 | * object is not owned by the kernel and delete it. |
2072 | */ | 2058 | */ |
2073 | 2059 | ||
2074 | if (optlen != sizeof(struct irda_ias_set)) | 2060 | if (optlen != sizeof(struct irda_ias_set)) { |
2075 | return -EINVAL; | 2061 | err = -EINVAL; |
2062 | goto out; | ||
2063 | } | ||
2076 | 2064 | ||
2077 | ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); | 2065 | ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); |
2078 | if (ias_opt == NULL) | 2066 | if (ias_opt == NULL) { |
2079 | return -ENOMEM; | 2067 | err = -ENOMEM; |
2068 | goto out; | ||
2069 | } | ||
2080 | 2070 | ||
2081 | /* Copy query to the driver. */ | 2071 | /* Copy query to the driver. */ |
2082 | if (copy_from_user(ias_opt, optval, optlen)) { | 2072 | if (copy_from_user(ias_opt, optval, optlen)) { |
2083 | kfree(ias_opt); | 2073 | kfree(ias_opt); |
2084 | return -EFAULT; | 2074 | err = -EFAULT; |
2075 | goto out; | ||
2085 | } | 2076 | } |
2086 | 2077 | ||
2087 | /* Find the object we target. | 2078 | /* Find the object we target. |
@@ -2094,7 +2085,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, | |||
2094 | ias_obj = irias_find_object(ias_opt->irda_class_name); | 2085 | ias_obj = irias_find_object(ias_opt->irda_class_name); |
2095 | if(ias_obj == (struct ias_object *) NULL) { | 2086 | if(ias_obj == (struct ias_object *) NULL) { |
2096 | kfree(ias_opt); | 2087 | kfree(ias_opt); |
2097 | return -EINVAL; | 2088 | err = -EINVAL; |
2089 | goto out; | ||
2098 | } | 2090 | } |
2099 | 2091 | ||
2100 | /* Only ROOT can mess with the global IAS database. | 2092 | /* Only ROOT can mess with the global IAS database. |
@@ -2103,7 +2095,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, | |||
2103 | if((!capable(CAP_NET_ADMIN)) && | 2095 | if((!capable(CAP_NET_ADMIN)) && |
2104 | ((ias_obj == NULL) || (ias_obj != self->ias_obj))) { | 2096 | ((ias_obj == NULL) || (ias_obj != self->ias_obj))) { |
2105 | kfree(ias_opt); | 2097 | kfree(ias_opt); |
2106 | return -EPERM; | 2098 | err = -EPERM; |
2099 | goto out; | ||
2107 | } | 2100 | } |
2108 | 2101 | ||
2109 | /* Find the attribute (in the object) we target */ | 2102 | /* Find the attribute (in the object) we target */ |
@@ -2111,14 +2104,16 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, | |||
2111 | ias_opt->irda_attrib_name); | 2104 | ias_opt->irda_attrib_name); |
2112 | if(ias_attr == (struct ias_attrib *) NULL) { | 2105 | if(ias_attr == (struct ias_attrib *) NULL) { |
2113 | kfree(ias_opt); | 2106 | kfree(ias_opt); |
2114 | return -EINVAL; | 2107 | err = -EINVAL; |
2108 | goto out; | ||
2115 | } | 2109 | } |
2116 | 2110 | ||
2117 | /* Check is the user space own the object */ | 2111 | /* Check is the user space own the object */ |
2118 | if(ias_attr->value->owner != IAS_USER_ATTR) { | 2112 | if(ias_attr->value->owner != IAS_USER_ATTR) { |
2119 | IRDA_DEBUG(1, "%s(), attempting to delete a kernel attribute\n", __func__); | 2113 | IRDA_DEBUG(1, "%s(), attempting to delete a kernel attribute\n", __func__); |
2120 | kfree(ias_opt); | 2114 | kfree(ias_opt); |
2121 | return -EPERM; | 2115 | err = -EPERM; |
2116 | goto out; | ||
2122 | } | 2117 | } |
2123 | 2118 | ||
2124 | /* Remove the attribute (and maybe the object) */ | 2119 | /* Remove the attribute (and maybe the object) */ |
@@ -2126,11 +2121,15 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, | |||
2126 | kfree(ias_opt); | 2121 | kfree(ias_opt); |
2127 | break; | 2122 | break; |
2128 | case IRLMP_MAX_SDU_SIZE: | 2123 | case IRLMP_MAX_SDU_SIZE: |
2129 | if (optlen < sizeof(int)) | 2124 | if (optlen < sizeof(int)) { |
2130 | return -EINVAL; | 2125 | err = -EINVAL; |
2126 | goto out; | ||
2127 | } | ||
2131 | 2128 | ||
2132 | if (get_user(opt, (int __user *)optval)) | 2129 | if (get_user(opt, (int __user *)optval)) { |
2133 | return -EFAULT; | 2130 | err = -EFAULT; |
2131 | goto out; | ||
2132 | } | ||
2134 | 2133 | ||
2135 | /* Only possible for a seqpacket service (TTP with SAR) */ | 2134 | /* Only possible for a seqpacket service (TTP with SAR) */ |
2136 | if (sk->sk_type != SOCK_SEQPACKET) { | 2135 | if (sk->sk_type != SOCK_SEQPACKET) { |
@@ -2140,16 +2139,21 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, | |||
2140 | } else { | 2139 | } else { |
2141 | IRDA_WARNING("%s: not allowed to set MAXSDUSIZE for this socket type!\n", | 2140 | IRDA_WARNING("%s: not allowed to set MAXSDUSIZE for this socket type!\n", |
2142 | __func__); | 2141 | __func__); |
2143 | return -ENOPROTOOPT; | 2142 | err = -ENOPROTOOPT; |
2143 | goto out; | ||
2144 | } | 2144 | } |
2145 | break; | 2145 | break; |
2146 | case IRLMP_HINTS_SET: | 2146 | case IRLMP_HINTS_SET: |
2147 | if (optlen < sizeof(int)) | 2147 | if (optlen < sizeof(int)) { |
2148 | return -EINVAL; | 2148 | err = -EINVAL; |
2149 | goto out; | ||
2150 | } | ||
2149 | 2151 | ||
2150 | /* The input is really a (__u8 hints[2]), easier as an int */ | 2152 | /* The input is really a (__u8 hints[2]), easier as an int */ |
2151 | if (get_user(opt, (int __user *)optval)) | 2153 | if (get_user(opt, (int __user *)optval)) { |
2152 | return -EFAULT; | 2154 | err = -EFAULT; |
2155 | goto out; | ||
2156 | } | ||
2153 | 2157 | ||
2154 | /* Unregister any old registration */ | 2158 | /* Unregister any old registration */ |
2155 | if (self->skey) | 2159 | if (self->skey) |
@@ -2163,12 +2167,16 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, | |||
2163 | * making a discovery (nodes which don't match any hint | 2167 | * making a discovery (nodes which don't match any hint |
2164 | * bit in the mask are not reported). | 2168 | * bit in the mask are not reported). |
2165 | */ | 2169 | */ |
2166 | if (optlen < sizeof(int)) | 2170 | if (optlen < sizeof(int)) { |
2167 | return -EINVAL; | 2171 | err = -EINVAL; |
2172 | goto out; | ||
2173 | } | ||
2168 | 2174 | ||
2169 | /* The input is really a (__u8 hints[2]), easier as an int */ | 2175 | /* The input is really a (__u8 hints[2]), easier as an int */ |
2170 | if (get_user(opt, (int __user *)optval)) | 2176 | if (get_user(opt, (int __user *)optval)) { |
2171 | return -EFAULT; | 2177 | err = -EFAULT; |
2178 | goto out; | ||
2179 | } | ||
2172 | 2180 | ||
2173 | /* Set the new hint mask */ | 2181 | /* Set the new hint mask */ |
2174 | self->mask.word = (__u16) opt; | 2182 | self->mask.word = (__u16) opt; |
@@ -2180,19 +2188,12 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, | |||
2180 | 2188 | ||
2181 | break; | 2189 | break; |
2182 | default: | 2190 | default: |
2183 | return -ENOPROTOOPT; | 2191 | err = -ENOPROTOOPT; |
2192 | break; | ||
2184 | } | 2193 | } |
2185 | return 0; | ||
2186 | } | ||
2187 | 2194 | ||
2188 | static int irda_setsockopt(struct socket *sock, int level, int optname, | 2195 | out: |
2189 | char __user *optval, unsigned int optlen) | 2196 | release_sock(sk); |
2190 | { | ||
2191 | int err; | ||
2192 | |||
2193 | lock_kernel(); | ||
2194 | err = __irda_setsockopt(sock, level, optname, optval, optlen); | ||
2195 | unlock_kernel(); | ||
2196 | 2197 | ||
2197 | return err; | 2198 | return err; |
2198 | } | 2199 | } |
@@ -2249,7 +2250,7 @@ static int irda_extract_ias_value(struct irda_ias_set *ias_opt, | |||
2249 | /* | 2250 | /* |
2250 | * Function irda_getsockopt (sock, level, optname, optval, optlen) | 2251 | * Function irda_getsockopt (sock, level, optname, optval, optlen) |
2251 | */ | 2252 | */ |
2252 | static int __irda_getsockopt(struct socket *sock, int level, int optname, | 2253 | static int irda_getsockopt(struct socket *sock, int level, int optname, |
2253 | char __user *optval, int __user *optlen) | 2254 | char __user *optval, int __user *optlen) |
2254 | { | 2255 | { |
2255 | struct sock *sk = sock->sk; | 2256 | struct sock *sk = sock->sk; |
@@ -2262,7 +2263,7 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, | |||
2262 | int daddr = DEV_ADDR_ANY; /* Dest address for IAS queries */ | 2263 | int daddr = DEV_ADDR_ANY; /* Dest address for IAS queries */ |
2263 | int val = 0; | 2264 | int val = 0; |
2264 | int len = 0; | 2265 | int len = 0; |
2265 | int err; | 2266 | int err = 0; |
2266 | int offset, total; | 2267 | int offset, total; |
2267 | 2268 | ||
2268 | IRDA_DEBUG(2, "%s(%p)\n", __func__, self); | 2269 | IRDA_DEBUG(2, "%s(%p)\n", __func__, self); |
@@ -2276,15 +2277,18 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, | |||
2276 | if(len < 0) | 2277 | if(len < 0) |
2277 | return -EINVAL; | 2278 | return -EINVAL; |
2278 | 2279 | ||
2280 | lock_sock(sk); | ||
2281 | |||
2279 | switch (optname) { | 2282 | switch (optname) { |
2280 | case IRLMP_ENUMDEVICES: | 2283 | case IRLMP_ENUMDEVICES: |
2281 | /* Ask lmp for the current discovery log */ | 2284 | /* Ask lmp for the current discovery log */ |
2282 | discoveries = irlmp_get_discoveries(&list.len, self->mask.word, | 2285 | discoveries = irlmp_get_discoveries(&list.len, self->mask.word, |
2283 | self->nslots); | 2286 | self->nslots); |
2284 | /* Check if the we got some results */ | 2287 | /* Check if the we got some results */ |
2285 | if (discoveries == NULL) | 2288 | if (discoveries == NULL) { |
2286 | return -EAGAIN; /* Didn't find any devices */ | 2289 | err = -EAGAIN; |
2287 | err = 0; | 2290 | goto out; /* Didn't find any devices */ |
2291 | } | ||
2288 | 2292 | ||
2289 | /* Write total list length back to client */ | 2293 | /* Write total list length back to client */ |
2290 | if (copy_to_user(optval, &list, | 2294 | if (copy_to_user(optval, &list, |
@@ -2297,8 +2301,7 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, | |||
2297 | sizeof(struct irda_device_info); | 2301 | sizeof(struct irda_device_info); |
2298 | 2302 | ||
2299 | /* Copy the list itself - watch for overflow */ | 2303 | /* Copy the list itself - watch for overflow */ |
2300 | if(list.len > 2048) | 2304 | if (list.len > 2048) { |
2301 | { | ||
2302 | err = -EINVAL; | 2305 | err = -EINVAL; |
2303 | goto bed; | 2306 | goto bed; |
2304 | } | 2307 | } |
@@ -2314,17 +2317,20 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, | |||
2314 | bed: | 2317 | bed: |
2315 | /* Free up our buffer */ | 2318 | /* Free up our buffer */ |
2316 | kfree(discoveries); | 2319 | kfree(discoveries); |
2317 | if (err) | ||
2318 | return err; | ||
2319 | break; | 2320 | break; |
2320 | case IRLMP_MAX_SDU_SIZE: | 2321 | case IRLMP_MAX_SDU_SIZE: |
2321 | val = self->max_data_size; | 2322 | val = self->max_data_size; |
2322 | len = sizeof(int); | 2323 | len = sizeof(int); |
2323 | if (put_user(len, optlen)) | 2324 | if (put_user(len, optlen)) { |
2324 | return -EFAULT; | 2325 | err = -EFAULT; |
2326 | goto out; | ||
2327 | } | ||
2328 | |||
2329 | if (copy_to_user(optval, &val, len)) { | ||
2330 | err = -EFAULT; | ||
2331 | goto out; | ||
2332 | } | ||
2325 | 2333 | ||
2326 | if (copy_to_user(optval, &val, len)) | ||
2327 | return -EFAULT; | ||
2328 | break; | 2334 | break; |
2329 | case IRLMP_IAS_GET: | 2335 | case IRLMP_IAS_GET: |
2330 | /* The user want an object from our local IAS database. | 2336 | /* The user want an object from our local IAS database. |
@@ -2332,17 +2338,22 @@ bed: | |||
2332 | * that we found */ | 2338 | * that we found */ |
2333 | 2339 | ||
2334 | /* Check that the user has allocated the right space for us */ | 2340 | /* Check that the user has allocated the right space for us */ |
2335 | if (len != sizeof(struct irda_ias_set)) | 2341 | if (len != sizeof(struct irda_ias_set)) { |
2336 | return -EINVAL; | 2342 | err = -EINVAL; |
2343 | goto out; | ||
2344 | } | ||
2337 | 2345 | ||
2338 | ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); | 2346 | ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); |
2339 | if (ias_opt == NULL) | 2347 | if (ias_opt == NULL) { |
2340 | return -ENOMEM; | 2348 | err = -ENOMEM; |
2349 | goto out; | ||
2350 | } | ||
2341 | 2351 | ||
2342 | /* Copy query to the driver. */ | 2352 | /* Copy query to the driver. */ |
2343 | if (copy_from_user(ias_opt, optval, len)) { | 2353 | if (copy_from_user(ias_opt, optval, len)) { |
2344 | kfree(ias_opt); | 2354 | kfree(ias_opt); |
2345 | return -EFAULT; | 2355 | err = -EFAULT; |
2356 | goto out; | ||
2346 | } | 2357 | } |
2347 | 2358 | ||
2348 | /* Find the object we target. | 2359 | /* Find the object we target. |
@@ -2355,7 +2366,8 @@ bed: | |||
2355 | ias_obj = irias_find_object(ias_opt->irda_class_name); | 2366 | ias_obj = irias_find_object(ias_opt->irda_class_name); |
2356 | if(ias_obj == (struct ias_object *) NULL) { | 2367 | if(ias_obj == (struct ias_object *) NULL) { |
2357 | kfree(ias_opt); | 2368 | kfree(ias_opt); |
2358 | return -EINVAL; | 2369 | err = -EINVAL; |
2370 | goto out; | ||
2359 | } | 2371 | } |
2360 | 2372 | ||
2361 | /* Find the attribute (in the object) we target */ | 2373 | /* Find the attribute (in the object) we target */ |
@@ -2363,21 +2375,23 @@ bed: | |||
2363 | ias_opt->irda_attrib_name); | 2375 | ias_opt->irda_attrib_name); |
2364 | if(ias_attr == (struct ias_attrib *) NULL) { | 2376 | if(ias_attr == (struct ias_attrib *) NULL) { |
2365 | kfree(ias_opt); | 2377 | kfree(ias_opt); |
2366 | return -EINVAL; | 2378 | err = -EINVAL; |
2379 | goto out; | ||
2367 | } | 2380 | } |
2368 | 2381 | ||
2369 | /* Translate from internal to user structure */ | 2382 | /* Translate from internal to user structure */ |
2370 | err = irda_extract_ias_value(ias_opt, ias_attr->value); | 2383 | err = irda_extract_ias_value(ias_opt, ias_attr->value); |
2371 | if(err) { | 2384 | if(err) { |
2372 | kfree(ias_opt); | 2385 | kfree(ias_opt); |
2373 | return err; | 2386 | goto out; |
2374 | } | 2387 | } |
2375 | 2388 | ||
2376 | /* Copy reply to the user */ | 2389 | /* Copy reply to the user */ |
2377 | if (copy_to_user(optval, ias_opt, | 2390 | if (copy_to_user(optval, ias_opt, |
2378 | sizeof(struct irda_ias_set))) { | 2391 | sizeof(struct irda_ias_set))) { |
2379 | kfree(ias_opt); | 2392 | kfree(ias_opt); |
2380 | return -EFAULT; | 2393 | err = -EFAULT; |
2394 | goto out; | ||
2381 | } | 2395 | } |
2382 | /* Note : don't need to put optlen, we checked it */ | 2396 | /* Note : don't need to put optlen, we checked it */ |
2383 | kfree(ias_opt); | 2397 | kfree(ias_opt); |
@@ -2388,17 +2402,22 @@ bed: | |||
2388 | * then wait for the answer to come back. */ | 2402 | * then wait for the answer to come back. */ |
2389 | 2403 | ||
2390 | /* Check that the user has allocated the right space for us */ | 2404 | /* Check that the user has allocated the right space for us */ |
2391 | if (len != sizeof(struct irda_ias_set)) | 2405 | if (len != sizeof(struct irda_ias_set)) { |
2392 | return -EINVAL; | 2406 | err = -EINVAL; |
2407 | goto out; | ||
2408 | } | ||
2393 | 2409 | ||
2394 | ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); | 2410 | ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); |
2395 | if (ias_opt == NULL) | 2411 | if (ias_opt == NULL) { |
2396 | return -ENOMEM; | 2412 | err = -ENOMEM; |
2413 | goto out; | ||
2414 | } | ||
2397 | 2415 | ||
2398 | /* Copy query to the driver. */ | 2416 | /* Copy query to the driver. */ |
2399 | if (copy_from_user(ias_opt, optval, len)) { | 2417 | if (copy_from_user(ias_opt, optval, len)) { |
2400 | kfree(ias_opt); | 2418 | kfree(ias_opt); |
2401 | return -EFAULT; | 2419 | err = -EFAULT; |
2420 | goto out; | ||
2402 | } | 2421 | } |
2403 | 2422 | ||
2404 | /* At this point, there are two cases... | 2423 | /* At this point, there are two cases... |
@@ -2419,7 +2438,8 @@ bed: | |||
2419 | daddr = ias_opt->daddr; | 2438 | daddr = ias_opt->daddr; |
2420 | if((!daddr) || (daddr == DEV_ADDR_ANY)) { | 2439 | if((!daddr) || (daddr == DEV_ADDR_ANY)) { |
2421 | kfree(ias_opt); | 2440 | kfree(ias_opt); |
2422 | return -EINVAL; | 2441 | err = -EINVAL; |
2442 | goto out; | ||
2423 | } | 2443 | } |
2424 | } | 2444 | } |
2425 | 2445 | ||
@@ -2428,7 +2448,8 @@ bed: | |||
2428 | IRDA_WARNING("%s: busy with a previous query\n", | 2448 | IRDA_WARNING("%s: busy with a previous query\n", |
2429 | __func__); | 2449 | __func__); |
2430 | kfree(ias_opt); | 2450 | kfree(ias_opt); |
2431 | return -EBUSY; | 2451 | err = -EBUSY; |
2452 | goto out; | ||
2432 | } | 2453 | } |
2433 | 2454 | ||
2434 | self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self, | 2455 | self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self, |
@@ -2436,7 +2457,8 @@ bed: | |||
2436 | 2457 | ||
2437 | if (self->iriap == NULL) { | 2458 | if (self->iriap == NULL) { |
2438 | kfree(ias_opt); | 2459 | kfree(ias_opt); |
2439 | return -ENOMEM; | 2460 | err = -ENOMEM; |
2461 | goto out; | ||
2440 | } | 2462 | } |
2441 | 2463 | ||
2442 | /* Treat unexpected wakeup as disconnect */ | 2464 | /* Treat unexpected wakeup as disconnect */ |
@@ -2455,7 +2477,8 @@ bed: | |||
2455 | * we can free it regardless! */ | 2477 | * we can free it regardless! */ |
2456 | kfree(ias_opt); | 2478 | kfree(ias_opt); |
2457 | /* Treat signals as disconnect */ | 2479 | /* Treat signals as disconnect */ |
2458 | return -EHOSTUNREACH; | 2480 | err = -EHOSTUNREACH; |
2481 | goto out; | ||
2459 | } | 2482 | } |
2460 | 2483 | ||
2461 | /* Check what happened */ | 2484 | /* Check what happened */ |
@@ -2465,9 +2488,11 @@ bed: | |||
2465 | /* Requested object/attribute doesn't exist */ | 2488 | /* Requested object/attribute doesn't exist */ |
2466 | if((self->errno == IAS_CLASS_UNKNOWN) || | 2489 | if((self->errno == IAS_CLASS_UNKNOWN) || |
2467 | (self->errno == IAS_ATTRIB_UNKNOWN)) | 2490 | (self->errno == IAS_ATTRIB_UNKNOWN)) |
2468 | return -EADDRNOTAVAIL; | 2491 | err = -EADDRNOTAVAIL; |
2469 | else | 2492 | else |
2470 | return -EHOSTUNREACH; | 2493 | err = -EHOSTUNREACH; |
2494 | |||
2495 | goto out; | ||
2471 | } | 2496 | } |
2472 | 2497 | ||
2473 | /* Translate from internal to user structure */ | 2498 | /* Translate from internal to user structure */ |
@@ -2476,14 +2501,15 @@ bed: | |||
2476 | irias_delete_value(self->ias_result); | 2501 | irias_delete_value(self->ias_result); |
2477 | if (err) { | 2502 | if (err) { |
2478 | kfree(ias_opt); | 2503 | kfree(ias_opt); |
2479 | return err; | 2504 | goto out; |
2480 | } | 2505 | } |
2481 | 2506 | ||
2482 | /* Copy reply to the user */ | 2507 | /* Copy reply to the user */ |
2483 | if (copy_to_user(optval, ias_opt, | 2508 | if (copy_to_user(optval, ias_opt, |
2484 | sizeof(struct irda_ias_set))) { | 2509 | sizeof(struct irda_ias_set))) { |
2485 | kfree(ias_opt); | 2510 | kfree(ias_opt); |
2486 | return -EFAULT; | 2511 | err = -EFAULT; |
2512 | goto out; | ||
2487 | } | 2513 | } |
2488 | /* Note : don't need to put optlen, we checked it */ | 2514 | /* Note : don't need to put optlen, we checked it */ |
2489 | kfree(ias_opt); | 2515 | kfree(ias_opt); |
@@ -2504,11 +2530,15 @@ bed: | |||
2504 | */ | 2530 | */ |
2505 | 2531 | ||
2506 | /* Check that the user is passing us an int */ | 2532 | /* Check that the user is passing us an int */ |
2507 | if (len != sizeof(int)) | 2533 | if (len != sizeof(int)) { |
2508 | return -EINVAL; | 2534 | err = -EINVAL; |
2535 | goto out; | ||
2536 | } | ||
2509 | /* Get timeout in ms (max time we block the caller) */ | 2537 | /* Get timeout in ms (max time we block the caller) */ |
2510 | if (get_user(val, (int __user *)optval)) | 2538 | if (get_user(val, (int __user *)optval)) { |
2511 | return -EFAULT; | 2539 | err = -EFAULT; |
2540 | goto out; | ||
2541 | } | ||
2512 | 2542 | ||
2513 | /* Tell IrLMP we want to be notified */ | 2543 | /* Tell IrLMP we want to be notified */ |
2514 | irlmp_update_client(self->ckey, self->mask.word, | 2544 | irlmp_update_client(self->ckey, self->mask.word, |
@@ -2520,8 +2550,6 @@ bed: | |||
2520 | 2550 | ||
2521 | /* Wait until a node is discovered */ | 2551 | /* Wait until a node is discovered */ |
2522 | if (!self->cachedaddr) { | 2552 | if (!self->cachedaddr) { |
2523 | int ret = 0; | ||
2524 | |||
2525 | IRDA_DEBUG(1, "%s(), nothing discovered yet, going to sleep...\n", __func__); | 2553 | IRDA_DEBUG(1, "%s(), nothing discovered yet, going to sleep...\n", __func__); |
2526 | 2554 | ||
2527 | /* Set watchdog timer to expire in <val> ms. */ | 2555 | /* Set watchdog timer to expire in <val> ms. */ |
@@ -2534,7 +2562,7 @@ bed: | |||
2534 | /* Wait for IR-LMP to call us back */ | 2562 | /* Wait for IR-LMP to call us back */ |
2535 | __wait_event_interruptible(self->query_wait, | 2563 | __wait_event_interruptible(self->query_wait, |
2536 | (self->cachedaddr != 0 || self->errno == -ETIME), | 2564 | (self->cachedaddr != 0 || self->errno == -ETIME), |
2537 | ret); | 2565 | err); |
2538 | 2566 | ||
2539 | /* If watchdog is still activated, kill it! */ | 2567 | /* If watchdog is still activated, kill it! */ |
2540 | if(timer_pending(&(self->watchdog))) | 2568 | if(timer_pending(&(self->watchdog))) |
@@ -2542,8 +2570,8 @@ bed: | |||
2542 | 2570 | ||
2543 | IRDA_DEBUG(1, "%s(), ...waking up !\n", __func__); | 2571 | IRDA_DEBUG(1, "%s(), ...waking up !\n", __func__); |
2544 | 2572 | ||
2545 | if (ret != 0) | 2573 | if (err != 0) |
2546 | return ret; | 2574 | goto out; |
2547 | } | 2575 | } |
2548 | else | 2576 | else |
2549 | IRDA_DEBUG(1, "%s(), found immediately !\n", | 2577 | IRDA_DEBUG(1, "%s(), found immediately !\n", |
@@ -2566,25 +2594,19 @@ bed: | |||
2566 | * If the user want more details, he should query | 2594 | * If the user want more details, he should query |
2567 | * the whole discovery log and pick one device... | 2595 | * the whole discovery log and pick one device... |
2568 | */ | 2596 | */ |
2569 | if (put_user(daddr, (int __user *)optval)) | 2597 | if (put_user(daddr, (int __user *)optval)) { |
2570 | return -EFAULT; | 2598 | err = -EFAULT; |
2599 | goto out; | ||
2600 | } | ||
2571 | 2601 | ||
2572 | break; | 2602 | break; |
2573 | default: | 2603 | default: |
2574 | return -ENOPROTOOPT; | 2604 | err = -ENOPROTOOPT; |
2575 | } | 2605 | } |
2576 | 2606 | ||
2577 | return 0; | 2607 | out: |
2578 | } | ||
2579 | |||
2580 | static int irda_getsockopt(struct socket *sock, int level, int optname, | ||
2581 | char __user *optval, int __user *optlen) | ||
2582 | { | ||
2583 | int err; | ||
2584 | 2608 | ||
2585 | lock_kernel(); | 2609 | release_sock(sk); |
2586 | err = __irda_getsockopt(sock, level, optname, optval, optlen); | ||
2587 | unlock_kernel(); | ||
2588 | 2610 | ||
2589 | return err; | 2611 | return err; |
2590 | } | 2612 | } |
@@ -2628,7 +2650,7 @@ static const struct proto_ops irda_seqpacket_ops = { | |||
2628 | .socketpair = sock_no_socketpair, | 2650 | .socketpair = sock_no_socketpair, |
2629 | .accept = irda_accept, | 2651 | .accept = irda_accept, |
2630 | .getname = irda_getname, | 2652 | .getname = irda_getname, |
2631 | .poll = irda_datagram_poll, | 2653 | .poll = datagram_poll, |
2632 | .ioctl = irda_ioctl, | 2654 | .ioctl = irda_ioctl, |
2633 | #ifdef CONFIG_COMPAT | 2655 | #ifdef CONFIG_COMPAT |
2634 | .compat_ioctl = irda_compat_ioctl, | 2656 | .compat_ioctl = irda_compat_ioctl, |
@@ -2652,7 +2674,7 @@ static const struct proto_ops irda_dgram_ops = { | |||
2652 | .socketpair = sock_no_socketpair, | 2674 | .socketpair = sock_no_socketpair, |
2653 | .accept = irda_accept, | 2675 | .accept = irda_accept, |
2654 | .getname = irda_getname, | 2676 | .getname = irda_getname, |
2655 | .poll = irda_datagram_poll, | 2677 | .poll = datagram_poll, |
2656 | .ioctl = irda_ioctl, | 2678 | .ioctl = irda_ioctl, |
2657 | #ifdef CONFIG_COMPAT | 2679 | #ifdef CONFIG_COMPAT |
2658 | .compat_ioctl = irda_compat_ioctl, | 2680 | .compat_ioctl = irda_compat_ioctl, |
@@ -2677,7 +2699,7 @@ static const struct proto_ops irda_ultra_ops = { | |||
2677 | .socketpair = sock_no_socketpair, | 2699 | .socketpair = sock_no_socketpair, |
2678 | .accept = sock_no_accept, | 2700 | .accept = sock_no_accept, |
2679 | .getname = irda_getname, | 2701 | .getname = irda_getname, |
2680 | .poll = irda_datagram_poll, | 2702 | .poll = datagram_poll, |
2681 | .ioctl = irda_ioctl, | 2703 | .ioctl = irda_ioctl, |
2682 | #ifdef CONFIG_COMPAT | 2704 | #ifdef CONFIG_COMPAT |
2683 | .compat_ioctl = irda_compat_ioctl, | 2705 | .compat_ioctl = irda_compat_ioctl, |