diff options
Diffstat (limited to 'net/ipx/af_ipx.c')
-rw-r--r-- | net/ipx/af_ipx.c | 61 |
1 files changed, 50 insertions, 11 deletions
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 66c7a20011f3..f9759b54a6de 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c | |||
@@ -1298,6 +1298,7 @@ static int ipx_setsockopt(struct socket *sock, int level, int optname, | |||
1298 | int opt; | 1298 | int opt; |
1299 | int rc = -EINVAL; | 1299 | int rc = -EINVAL; |
1300 | 1300 | ||
1301 | lock_kernel(); | ||
1301 | if (optlen != sizeof(int)) | 1302 | if (optlen != sizeof(int)) |
1302 | goto out; | 1303 | goto out; |
1303 | 1304 | ||
@@ -1312,6 +1313,7 @@ static int ipx_setsockopt(struct socket *sock, int level, int optname, | |||
1312 | ipx_sk(sk)->type = opt; | 1313 | ipx_sk(sk)->type = opt; |
1313 | rc = 0; | 1314 | rc = 0; |
1314 | out: | 1315 | out: |
1316 | unlock_kernel(); | ||
1315 | return rc; | 1317 | return rc; |
1316 | } | 1318 | } |
1317 | 1319 | ||
@@ -1323,6 +1325,7 @@ static int ipx_getsockopt(struct socket *sock, int level, int optname, | |||
1323 | int len; | 1325 | int len; |
1324 | int rc = -ENOPROTOOPT; | 1326 | int rc = -ENOPROTOOPT; |
1325 | 1327 | ||
1328 | lock_kernel(); | ||
1326 | if (!(level == SOL_IPX && optname == IPX_TYPE)) | 1329 | if (!(level == SOL_IPX && optname == IPX_TYPE)) |
1327 | goto out; | 1330 | goto out; |
1328 | 1331 | ||
@@ -1343,6 +1346,7 @@ static int ipx_getsockopt(struct socket *sock, int level, int optname, | |||
1343 | 1346 | ||
1344 | rc = 0; | 1347 | rc = 0; |
1345 | out: | 1348 | out: |
1349 | unlock_kernel(); | ||
1346 | return rc; | 1350 | return rc; |
1347 | } | 1351 | } |
1348 | 1352 | ||
@@ -1352,12 +1356,13 @@ static struct proto ipx_proto = { | |||
1352 | .obj_size = sizeof(struct ipx_sock), | 1356 | .obj_size = sizeof(struct ipx_sock), |
1353 | }; | 1357 | }; |
1354 | 1358 | ||
1355 | static int ipx_create(struct net *net, struct socket *sock, int protocol) | 1359 | static int ipx_create(struct net *net, struct socket *sock, int protocol, |
1360 | int kern) | ||
1356 | { | 1361 | { |
1357 | int rc = -ESOCKTNOSUPPORT; | 1362 | int rc = -ESOCKTNOSUPPORT; |
1358 | struct sock *sk; | 1363 | struct sock *sk; |
1359 | 1364 | ||
1360 | if (net != &init_net) | 1365 | if (!net_eq(net, &init_net)) |
1361 | return -EAFNOSUPPORT; | 1366 | return -EAFNOSUPPORT; |
1362 | 1367 | ||
1363 | /* | 1368 | /* |
@@ -1390,6 +1395,7 @@ static int ipx_release(struct socket *sock) | |||
1390 | if (!sk) | 1395 | if (!sk) |
1391 | goto out; | 1396 | goto out; |
1392 | 1397 | ||
1398 | lock_kernel(); | ||
1393 | if (!sock_flag(sk, SOCK_DEAD)) | 1399 | if (!sock_flag(sk, SOCK_DEAD)) |
1394 | sk->sk_state_change(sk); | 1400 | sk->sk_state_change(sk); |
1395 | 1401 | ||
@@ -1397,6 +1403,7 @@ static int ipx_release(struct socket *sock) | |||
1397 | sock->sk = NULL; | 1403 | sock->sk = NULL; |
1398 | sk_refcnt_debug_release(sk); | 1404 | sk_refcnt_debug_release(sk); |
1399 | ipx_destroy_socket(sk); | 1405 | ipx_destroy_socket(sk); |
1406 | unlock_kernel(); | ||
1400 | out: | 1407 | out: |
1401 | return 0; | 1408 | return 0; |
1402 | } | 1409 | } |
@@ -1424,7 +1431,8 @@ static __be16 ipx_first_free_socketnum(struct ipx_interface *intrfc) | |||
1424 | return htons(socketNum); | 1431 | return htons(socketNum); |
1425 | } | 1432 | } |
1426 | 1433 | ||
1427 | static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | 1434 | static int __ipx_bind(struct socket *sock, |
1435 | struct sockaddr *uaddr, int addr_len) | ||
1428 | { | 1436 | { |
1429 | struct sock *sk = sock->sk; | 1437 | struct sock *sk = sock->sk; |
1430 | struct ipx_sock *ipxs = ipx_sk(sk); | 1438 | struct ipx_sock *ipxs = ipx_sk(sk); |
@@ -1519,6 +1527,17 @@ out: | |||
1519 | return rc; | 1527 | return rc; |
1520 | } | 1528 | } |
1521 | 1529 | ||
1530 | static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | ||
1531 | { | ||
1532 | int rc; | ||
1533 | |||
1534 | lock_kernel(); | ||
1535 | rc = __ipx_bind(sock, uaddr, addr_len); | ||
1536 | unlock_kernel(); | ||
1537 | |||
1538 | return rc; | ||
1539 | } | ||
1540 | |||
1522 | static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, | 1541 | static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, |
1523 | int addr_len, int flags) | 1542 | int addr_len, int flags) |
1524 | { | 1543 | { |
@@ -1531,6 +1550,7 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, | |||
1531 | sk->sk_state = TCP_CLOSE; | 1550 | sk->sk_state = TCP_CLOSE; |
1532 | sock->state = SS_UNCONNECTED; | 1551 | sock->state = SS_UNCONNECTED; |
1533 | 1552 | ||
1553 | lock_kernel(); | ||
1534 | if (addr_len != sizeof(*addr)) | 1554 | if (addr_len != sizeof(*addr)) |
1535 | goto out; | 1555 | goto out; |
1536 | addr = (struct sockaddr_ipx *)uaddr; | 1556 | addr = (struct sockaddr_ipx *)uaddr; |
@@ -1550,7 +1570,7 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, | |||
1550 | IPX_NODE_LEN); | 1570 | IPX_NODE_LEN); |
1551 | #endif /* CONFIG_IPX_INTERN */ | 1571 | #endif /* CONFIG_IPX_INTERN */ |
1552 | 1572 | ||
1553 | rc = ipx_bind(sock, (struct sockaddr *)&uaddr, | 1573 | rc = __ipx_bind(sock, (struct sockaddr *)&uaddr, |
1554 | sizeof(struct sockaddr_ipx)); | 1574 | sizeof(struct sockaddr_ipx)); |
1555 | if (rc) | 1575 | if (rc) |
1556 | goto out; | 1576 | goto out; |
@@ -1577,6 +1597,7 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, | |||
1577 | ipxrtr_put(rt); | 1597 | ipxrtr_put(rt); |
1578 | rc = 0; | 1598 | rc = 0; |
1579 | out: | 1599 | out: |
1600 | unlock_kernel(); | ||
1580 | return rc; | 1601 | return rc; |
1581 | } | 1602 | } |
1582 | 1603 | ||
@@ -1592,6 +1613,7 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, | |||
1592 | 1613 | ||
1593 | *uaddr_len = sizeof(struct sockaddr_ipx); | 1614 | *uaddr_len = sizeof(struct sockaddr_ipx); |
1594 | 1615 | ||
1616 | lock_kernel(); | ||
1595 | if (peer) { | 1617 | if (peer) { |
1596 | rc = -ENOTCONN; | 1618 | rc = -ENOTCONN; |
1597 | if (sk->sk_state != TCP_ESTABLISHED) | 1619 | if (sk->sk_state != TCP_ESTABLISHED) |
@@ -1626,6 +1648,19 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, | |||
1626 | 1648 | ||
1627 | rc = 0; | 1649 | rc = 0; |
1628 | out: | 1650 | out: |
1651 | unlock_kernel(); | ||
1652 | return rc; | ||
1653 | } | ||
1654 | |||
1655 | static unsigned int ipx_datagram_poll(struct file *file, struct socket *sock, | ||
1656 | poll_table *wait) | ||
1657 | { | ||
1658 | int rc; | ||
1659 | |||
1660 | lock_kernel(); | ||
1661 | rc = datagram_poll(file, sock, wait); | ||
1662 | unlock_kernel(); | ||
1663 | |||
1629 | return rc; | 1664 | return rc; |
1630 | } | 1665 | } |
1631 | 1666 | ||
@@ -1700,6 +1735,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1700 | int rc = -EINVAL; | 1735 | int rc = -EINVAL; |
1701 | int flags = msg->msg_flags; | 1736 | int flags = msg->msg_flags; |
1702 | 1737 | ||
1738 | lock_kernel(); | ||
1703 | /* Socket gets bound below anyway */ | 1739 | /* Socket gets bound below anyway */ |
1704 | /* if (sk->sk_zapped) | 1740 | /* if (sk->sk_zapped) |
1705 | return -EIO; */ /* Socket not bound */ | 1741 | return -EIO; */ /* Socket not bound */ |
@@ -1723,7 +1759,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1723 | memcpy(uaddr.sipx_node, ipxs->intrfc->if_node, | 1759 | memcpy(uaddr.sipx_node, ipxs->intrfc->if_node, |
1724 | IPX_NODE_LEN); | 1760 | IPX_NODE_LEN); |
1725 | #endif | 1761 | #endif |
1726 | rc = ipx_bind(sock, (struct sockaddr *)&uaddr, | 1762 | rc = __ipx_bind(sock, (struct sockaddr *)&uaddr, |
1727 | sizeof(struct sockaddr_ipx)); | 1763 | sizeof(struct sockaddr_ipx)); |
1728 | if (rc) | 1764 | if (rc) |
1729 | goto out; | 1765 | goto out; |
@@ -1751,6 +1787,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1751 | if (rc >= 0) | 1787 | if (rc >= 0) |
1752 | rc = len; | 1788 | rc = len; |
1753 | out: | 1789 | out: |
1790 | unlock_kernel(); | ||
1754 | return rc; | 1791 | return rc; |
1755 | } | 1792 | } |
1756 | 1793 | ||
@@ -1765,6 +1802,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1765 | struct sk_buff *skb; | 1802 | struct sk_buff *skb; |
1766 | int copied, rc; | 1803 | int copied, rc; |
1767 | 1804 | ||
1805 | lock_kernel(); | ||
1768 | /* put the autobinding in */ | 1806 | /* put the autobinding in */ |
1769 | if (!ipxs->port) { | 1807 | if (!ipxs->port) { |
1770 | struct sockaddr_ipx uaddr; | 1808 | struct sockaddr_ipx uaddr; |
@@ -1779,7 +1817,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1779 | memcpy(uaddr.sipx_node, ipxs->intrfc->if_node, IPX_NODE_LEN); | 1817 | memcpy(uaddr.sipx_node, ipxs->intrfc->if_node, IPX_NODE_LEN); |
1780 | #endif /* CONFIG_IPX_INTERN */ | 1818 | #endif /* CONFIG_IPX_INTERN */ |
1781 | 1819 | ||
1782 | rc = ipx_bind(sock, (struct sockaddr *)&uaddr, | 1820 | rc = __ipx_bind(sock, (struct sockaddr *)&uaddr, |
1783 | sizeof(struct sockaddr_ipx)); | 1821 | sizeof(struct sockaddr_ipx)); |
1784 | if (rc) | 1822 | if (rc) |
1785 | goto out; | 1823 | goto out; |
@@ -1823,6 +1861,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1823 | out_free: | 1861 | out_free: |
1824 | skb_free_datagram(sk, skb); | 1862 | skb_free_datagram(sk, skb); |
1825 | out: | 1863 | out: |
1864 | unlock_kernel(); | ||
1826 | return rc; | 1865 | return rc; |
1827 | } | 1866 | } |
1828 | 1867 | ||
@@ -1834,6 +1873,7 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1834 | struct sock *sk = sock->sk; | 1873 | struct sock *sk = sock->sk; |
1835 | void __user *argp = (void __user *)arg; | 1874 | void __user *argp = (void __user *)arg; |
1836 | 1875 | ||
1876 | lock_kernel(); | ||
1837 | switch (cmd) { | 1877 | switch (cmd) { |
1838 | case TIOCOUTQ: | 1878 | case TIOCOUTQ: |
1839 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); | 1879 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
@@ -1896,6 +1936,7 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1896 | rc = -ENOIOCTLCMD; | 1936 | rc = -ENOIOCTLCMD; |
1897 | break; | 1937 | break; |
1898 | } | 1938 | } |
1939 | unlock_kernel(); | ||
1899 | 1940 | ||
1900 | return rc; | 1941 | return rc; |
1901 | } | 1942 | } |
@@ -1927,13 +1968,13 @@ static int ipx_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long | |||
1927 | * Socket family declarations | 1968 | * Socket family declarations |
1928 | */ | 1969 | */ |
1929 | 1970 | ||
1930 | static struct net_proto_family ipx_family_ops = { | 1971 | static const struct net_proto_family ipx_family_ops = { |
1931 | .family = PF_IPX, | 1972 | .family = PF_IPX, |
1932 | .create = ipx_create, | 1973 | .create = ipx_create, |
1933 | .owner = THIS_MODULE, | 1974 | .owner = THIS_MODULE, |
1934 | }; | 1975 | }; |
1935 | 1976 | ||
1936 | static const struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = { | 1977 | static const struct proto_ops ipx_dgram_ops = { |
1937 | .family = PF_IPX, | 1978 | .family = PF_IPX, |
1938 | .owner = THIS_MODULE, | 1979 | .owner = THIS_MODULE, |
1939 | .release = ipx_release, | 1980 | .release = ipx_release, |
@@ -1942,7 +1983,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = { | |||
1942 | .socketpair = sock_no_socketpair, | 1983 | .socketpair = sock_no_socketpair, |
1943 | .accept = sock_no_accept, | 1984 | .accept = sock_no_accept, |
1944 | .getname = ipx_getname, | 1985 | .getname = ipx_getname, |
1945 | .poll = datagram_poll, | 1986 | .poll = ipx_datagram_poll, |
1946 | .ioctl = ipx_ioctl, | 1987 | .ioctl = ipx_ioctl, |
1947 | #ifdef CONFIG_COMPAT | 1988 | #ifdef CONFIG_COMPAT |
1948 | .compat_ioctl = ipx_compat_ioctl, | 1989 | .compat_ioctl = ipx_compat_ioctl, |
@@ -1957,8 +1998,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = { | |||
1957 | .sendpage = sock_no_sendpage, | 1998 | .sendpage = sock_no_sendpage, |
1958 | }; | 1999 | }; |
1959 | 2000 | ||
1960 | SOCKOPS_WRAP(ipx_dgram, PF_IPX); | ||
1961 | |||
1962 | static struct packet_type ipx_8023_packet_type __read_mostly = { | 2001 | static struct packet_type ipx_8023_packet_type __read_mostly = { |
1963 | .type = cpu_to_be16(ETH_P_802_3), | 2002 | .type = cpu_to_be16(ETH_P_802_3), |
1964 | .func = ipx_rcv, | 2003 | .func = ipx_rcv, |