diff options
-rw-r--r-- | net/x25/af_x25.c | 71 |
1 files changed, 60 insertions, 11 deletions
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 38e235f61e27..39ce03e07d18 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c | |||
@@ -415,6 +415,7 @@ static int x25_setsockopt(struct socket *sock, int level, int optname, | |||
415 | struct sock *sk = sock->sk; | 415 | struct sock *sk = sock->sk; |
416 | int rc = -ENOPROTOOPT; | 416 | int rc = -ENOPROTOOPT; |
417 | 417 | ||
418 | lock_kernel(); | ||
418 | if (level != SOL_X25 || optname != X25_QBITINCL) | 419 | if (level != SOL_X25 || optname != X25_QBITINCL) |
419 | goto out; | 420 | goto out; |
420 | 421 | ||
@@ -429,6 +430,7 @@ static int x25_setsockopt(struct socket *sock, int level, int optname, | |||
429 | x25_sk(sk)->qbitincl = !!opt; | 430 | x25_sk(sk)->qbitincl = !!opt; |
430 | rc = 0; | 431 | rc = 0; |
431 | out: | 432 | out: |
433 | unlock_kernel(); | ||
432 | return rc; | 434 | return rc; |
433 | } | 435 | } |
434 | 436 | ||
@@ -438,6 +440,7 @@ static int x25_getsockopt(struct socket *sock, int level, int optname, | |||
438 | struct sock *sk = sock->sk; | 440 | struct sock *sk = sock->sk; |
439 | int val, len, rc = -ENOPROTOOPT; | 441 | int val, len, rc = -ENOPROTOOPT; |
440 | 442 | ||
443 | lock_kernel(); | ||
441 | if (level != SOL_X25 || optname != X25_QBITINCL) | 444 | if (level != SOL_X25 || optname != X25_QBITINCL) |
442 | goto out; | 445 | goto out; |
443 | 446 | ||
@@ -458,6 +461,7 @@ static int x25_getsockopt(struct socket *sock, int level, int optname, | |||
458 | val = x25_sk(sk)->qbitincl; | 461 | val = x25_sk(sk)->qbitincl; |
459 | rc = copy_to_user(optval, &val, len) ? -EFAULT : 0; | 462 | rc = copy_to_user(optval, &val, len) ? -EFAULT : 0; |
460 | out: | 463 | out: |
464 | unlock_kernel(); | ||
461 | return rc; | 465 | return rc; |
462 | } | 466 | } |
463 | 467 | ||
@@ -466,12 +470,14 @@ static int x25_listen(struct socket *sock, int backlog) | |||
466 | struct sock *sk = sock->sk; | 470 | struct sock *sk = sock->sk; |
467 | int rc = -EOPNOTSUPP; | 471 | int rc = -EOPNOTSUPP; |
468 | 472 | ||
473 | lock_kernel(); | ||
469 | if (sk->sk_state != TCP_LISTEN) { | 474 | if (sk->sk_state != TCP_LISTEN) { |
470 | memset(&x25_sk(sk)->dest_addr, 0, X25_ADDR_LEN); | 475 | memset(&x25_sk(sk)->dest_addr, 0, X25_ADDR_LEN); |
471 | sk->sk_max_ack_backlog = backlog; | 476 | sk->sk_max_ack_backlog = backlog; |
472 | sk->sk_state = TCP_LISTEN; | 477 | sk->sk_state = TCP_LISTEN; |
473 | rc = 0; | 478 | rc = 0; |
474 | } | 479 | } |
480 | unlock_kernel(); | ||
475 | 481 | ||
476 | return rc; | 482 | return rc; |
477 | } | 483 | } |
@@ -598,6 +604,7 @@ static int x25_release(struct socket *sock) | |||
598 | struct sock *sk = sock->sk; | 604 | struct sock *sk = sock->sk; |
599 | struct x25_sock *x25; | 605 | struct x25_sock *x25; |
600 | 606 | ||
607 | lock_kernel(); | ||
601 | if (!sk) | 608 | if (!sk) |
602 | goto out; | 609 | goto out; |
603 | 610 | ||
@@ -628,6 +635,7 @@ static int x25_release(struct socket *sock) | |||
628 | 635 | ||
629 | sock_orphan(sk); | 636 | sock_orphan(sk); |
630 | out: | 637 | out: |
638 | unlock_kernel(); | ||
631 | return 0; | 639 | return 0; |
632 | } | 640 | } |
633 | 641 | ||
@@ -635,18 +643,23 @@ static int x25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
635 | { | 643 | { |
636 | struct sock *sk = sock->sk; | 644 | struct sock *sk = sock->sk; |
637 | struct sockaddr_x25 *addr = (struct sockaddr_x25 *)uaddr; | 645 | struct sockaddr_x25 *addr = (struct sockaddr_x25 *)uaddr; |
646 | int rc = 0; | ||
638 | 647 | ||
648 | lock_kernel(); | ||
639 | if (!sock_flag(sk, SOCK_ZAPPED) || | 649 | if (!sock_flag(sk, SOCK_ZAPPED) || |
640 | addr_len != sizeof(struct sockaddr_x25) || | 650 | addr_len != sizeof(struct sockaddr_x25) || |
641 | addr->sx25_family != AF_X25) | 651 | addr->sx25_family != AF_X25) { |
642 | return -EINVAL; | 652 | rc = -EINVAL; |
653 | goto out; | ||
654 | } | ||
643 | 655 | ||
644 | x25_sk(sk)->source_addr = addr->sx25_addr; | 656 | x25_sk(sk)->source_addr = addr->sx25_addr; |
645 | x25_insert_socket(sk); | 657 | x25_insert_socket(sk); |
646 | sock_reset_flag(sk, SOCK_ZAPPED); | 658 | sock_reset_flag(sk, SOCK_ZAPPED); |
647 | SOCK_DEBUG(sk, "x25_bind: socket is bound\n"); | 659 | SOCK_DEBUG(sk, "x25_bind: socket is bound\n"); |
648 | 660 | out: | |
649 | return 0; | 661 | unlock_kernel(); |
662 | return rc; | ||
650 | } | 663 | } |
651 | 664 | ||
652 | static int x25_wait_for_connection_establishment(struct sock *sk) | 665 | static int x25_wait_for_connection_establishment(struct sock *sk) |
@@ -687,6 +700,7 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, | |||
687 | struct x25_route *rt; | 700 | struct x25_route *rt; |
688 | int rc = 0; | 701 | int rc = 0; |
689 | 702 | ||
703 | lock_kernel(); | ||
690 | lock_sock(sk); | 704 | lock_sock(sk); |
691 | if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) { | 705 | if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) { |
692 | sock->state = SS_CONNECTED; | 706 | sock->state = SS_CONNECTED; |
@@ -764,6 +778,7 @@ out_put_route: | |||
764 | x25_route_put(rt); | 778 | x25_route_put(rt); |
765 | out: | 779 | out: |
766 | release_sock(sk); | 780 | release_sock(sk); |
781 | unlock_kernel(); | ||
767 | return rc; | 782 | return rc; |
768 | } | 783 | } |
769 | 784 | ||
@@ -803,6 +818,7 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags) | |||
803 | struct sk_buff *skb; | 818 | struct sk_buff *skb; |
804 | int rc = -EINVAL; | 819 | int rc = -EINVAL; |
805 | 820 | ||
821 | lock_kernel(); | ||
806 | if (!sk || sk->sk_state != TCP_LISTEN) | 822 | if (!sk || sk->sk_state != TCP_LISTEN) |
807 | goto out; | 823 | goto out; |
808 | 824 | ||
@@ -830,6 +846,7 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags) | |||
830 | out2: | 846 | out2: |
831 | release_sock(sk); | 847 | release_sock(sk); |
832 | out: | 848 | out: |
849 | unlock_kernel(); | ||
833 | return rc; | 850 | return rc; |
834 | } | 851 | } |
835 | 852 | ||
@@ -839,10 +856,14 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr, | |||
839 | struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)uaddr; | 856 | struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)uaddr; |
840 | struct sock *sk = sock->sk; | 857 | struct sock *sk = sock->sk; |
841 | struct x25_sock *x25 = x25_sk(sk); | 858 | struct x25_sock *x25 = x25_sk(sk); |
859 | int rc = 0; | ||
842 | 860 | ||
861 | lock_kernel(); | ||
843 | if (peer) { | 862 | if (peer) { |
844 | if (sk->sk_state != TCP_ESTABLISHED) | 863 | if (sk->sk_state != TCP_ESTABLISHED) { |
845 | return -ENOTCONN; | 864 | rc = -ENOTCONN; |
865 | goto out; | ||
866 | } | ||
846 | sx25->sx25_addr = x25->dest_addr; | 867 | sx25->sx25_addr = x25->dest_addr; |
847 | } else | 868 | } else |
848 | sx25->sx25_addr = x25->source_addr; | 869 | sx25->sx25_addr = x25->source_addr; |
@@ -850,7 +871,21 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr, | |||
850 | sx25->sx25_family = AF_X25; | 871 | sx25->sx25_family = AF_X25; |
851 | *uaddr_len = sizeof(*sx25); | 872 | *uaddr_len = sizeof(*sx25); |
852 | 873 | ||
853 | return 0; | 874 | out: |
875 | unlock_kernel(); | ||
876 | return rc; | ||
877 | } | ||
878 | |||
879 | static unsigned int x25_datagram_poll(struct file *file, struct socket *sock, | ||
880 | poll_table *wait) | ||
881 | { | ||
882 | int rc; | ||
883 | |||
884 | lock_kernel(); | ||
885 | rc = datagram_poll(file, sock, wait); | ||
886 | unlock_kernel(); | ||
887 | |||
888 | return rc; | ||
854 | } | 889 | } |
855 | 890 | ||
856 | int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, | 891 | int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, |
@@ -1003,6 +1038,7 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1003 | size_t size; | 1038 | size_t size; |
1004 | int qbit = 0, rc = -EINVAL; | 1039 | int qbit = 0, rc = -EINVAL; |
1005 | 1040 | ||
1041 | lock_kernel(); | ||
1006 | if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_OOB|MSG_EOR|MSG_CMSG_COMPAT)) | 1042 | if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_OOB|MSG_EOR|MSG_CMSG_COMPAT)) |
1007 | goto out; | 1043 | goto out; |
1008 | 1044 | ||
@@ -1167,6 +1203,7 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1167 | release_sock(sk); | 1203 | release_sock(sk); |
1168 | rc = len; | 1204 | rc = len; |
1169 | out: | 1205 | out: |
1206 | unlock_kernel(); | ||
1170 | return rc; | 1207 | return rc; |
1171 | out_kfree_skb: | 1208 | out_kfree_skb: |
1172 | kfree_skb(skb); | 1209 | kfree_skb(skb); |
@@ -1187,6 +1224,7 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1187 | unsigned char *asmptr; | 1224 | unsigned char *asmptr; |
1188 | int rc = -ENOTCONN; | 1225 | int rc = -ENOTCONN; |
1189 | 1226 | ||
1227 | lock_kernel(); | ||
1190 | /* | 1228 | /* |
1191 | * This works for seqpacket too. The receiver has ordered the queue for | 1229 | * This works for seqpacket too. The receiver has ordered the queue for |
1192 | * us! We do one quick check first though | 1230 | * us! We do one quick check first though |
@@ -1260,6 +1298,7 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1260 | out_free_dgram: | 1298 | out_free_dgram: |
1261 | skb_free_datagram(sk, skb); | 1299 | skb_free_datagram(sk, skb); |
1262 | out: | 1300 | out: |
1301 | unlock_kernel(); | ||
1263 | return rc; | 1302 | return rc; |
1264 | } | 1303 | } |
1265 | 1304 | ||
@@ -1271,6 +1310,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1271 | void __user *argp = (void __user *)arg; | 1310 | void __user *argp = (void __user *)arg; |
1272 | int rc; | 1311 | int rc; |
1273 | 1312 | ||
1313 | lock_kernel(); | ||
1274 | switch (cmd) { | 1314 | switch (cmd) { |
1275 | case TIOCOUTQ: { | 1315 | case TIOCOUTQ: { |
1276 | int amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); | 1316 | int amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
@@ -1473,6 +1513,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1473 | rc = -ENOIOCTLCMD; | 1513 | rc = -ENOIOCTLCMD; |
1474 | break; | 1514 | break; |
1475 | } | 1515 | } |
1516 | unlock_kernel(); | ||
1476 | 1517 | ||
1477 | return rc; | 1518 | return rc; |
1478 | } | 1519 | } |
@@ -1543,15 +1584,19 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd, | |||
1543 | break; | 1584 | break; |
1544 | case SIOCGSTAMP: | 1585 | case SIOCGSTAMP: |
1545 | rc = -EINVAL; | 1586 | rc = -EINVAL; |
1587 | lock_kernel(); | ||
1546 | if (sk) | 1588 | if (sk) |
1547 | rc = compat_sock_get_timestamp(sk, | 1589 | rc = compat_sock_get_timestamp(sk, |
1548 | (struct timeval __user*)argp); | 1590 | (struct timeval __user*)argp); |
1591 | unlock_kernel(); | ||
1549 | break; | 1592 | break; |
1550 | case SIOCGSTAMPNS: | 1593 | case SIOCGSTAMPNS: |
1551 | rc = -EINVAL; | 1594 | rc = -EINVAL; |
1595 | lock_kernel(); | ||
1552 | if (sk) | 1596 | if (sk) |
1553 | rc = compat_sock_get_timestampns(sk, | 1597 | rc = compat_sock_get_timestampns(sk, |
1554 | (struct timespec __user*)argp); | 1598 | (struct timespec __user*)argp); |
1599 | unlock_kernel(); | ||
1555 | break; | 1600 | break; |
1556 | case SIOCGIFADDR: | 1601 | case SIOCGIFADDR: |
1557 | case SIOCSIFADDR: | 1602 | case SIOCSIFADDR: |
@@ -1570,16 +1615,22 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd, | |||
1570 | rc = -EPERM; | 1615 | rc = -EPERM; |
1571 | if (!capable(CAP_NET_ADMIN)) | 1616 | if (!capable(CAP_NET_ADMIN)) |
1572 | break; | 1617 | break; |
1618 | lock_kernel(); | ||
1573 | rc = x25_route_ioctl(cmd, argp); | 1619 | rc = x25_route_ioctl(cmd, argp); |
1620 | unlock_kernel(); | ||
1574 | break; | 1621 | break; |
1575 | case SIOCX25GSUBSCRIP: | 1622 | case SIOCX25GSUBSCRIP: |
1623 | lock_kernel(); | ||
1576 | rc = compat_x25_subscr_ioctl(cmd, argp); | 1624 | rc = compat_x25_subscr_ioctl(cmd, argp); |
1625 | unlock_kernel(); | ||
1577 | break; | 1626 | break; |
1578 | case SIOCX25SSUBSCRIP: | 1627 | case SIOCX25SSUBSCRIP: |
1579 | rc = -EPERM; | 1628 | rc = -EPERM; |
1580 | if (!capable(CAP_NET_ADMIN)) | 1629 | if (!capable(CAP_NET_ADMIN)) |
1581 | break; | 1630 | break; |
1631 | lock_kernel(); | ||
1582 | rc = compat_x25_subscr_ioctl(cmd, argp); | 1632 | rc = compat_x25_subscr_ioctl(cmd, argp); |
1633 | unlock_kernel(); | ||
1583 | break; | 1634 | break; |
1584 | case SIOCX25GFACILITIES: | 1635 | case SIOCX25GFACILITIES: |
1585 | case SIOCX25SFACILITIES: | 1636 | case SIOCX25SFACILITIES: |
@@ -1601,7 +1652,7 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd, | |||
1601 | } | 1652 | } |
1602 | #endif | 1653 | #endif |
1603 | 1654 | ||
1604 | static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = { | 1655 | static const struct proto_ops x25_proto_ops = { |
1605 | .family = AF_X25, | 1656 | .family = AF_X25, |
1606 | .owner = THIS_MODULE, | 1657 | .owner = THIS_MODULE, |
1607 | .release = x25_release, | 1658 | .release = x25_release, |
@@ -1610,7 +1661,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = { | |||
1610 | .socketpair = sock_no_socketpair, | 1661 | .socketpair = sock_no_socketpair, |
1611 | .accept = x25_accept, | 1662 | .accept = x25_accept, |
1612 | .getname = x25_getname, | 1663 | .getname = x25_getname, |
1613 | .poll = datagram_poll, | 1664 | .poll = x25_datagram_poll, |
1614 | .ioctl = x25_ioctl, | 1665 | .ioctl = x25_ioctl, |
1615 | #ifdef CONFIG_COMPAT | 1666 | #ifdef CONFIG_COMPAT |
1616 | .compat_ioctl = compat_x25_ioctl, | 1667 | .compat_ioctl = compat_x25_ioctl, |
@@ -1625,8 +1676,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = { | |||
1625 | .sendpage = sock_no_sendpage, | 1676 | .sendpage = sock_no_sendpage, |
1626 | }; | 1677 | }; |
1627 | 1678 | ||
1628 | SOCKOPS_WRAP(x25_proto, AF_X25); | ||
1629 | |||
1630 | static struct packet_type x25_packet_type __read_mostly = { | 1679 | static struct packet_type x25_packet_type __read_mostly = { |
1631 | .type = cpu_to_be16(ETH_P_X25), | 1680 | .type = cpu_to_be16(ETH_P_X25), |
1632 | .func = x25_lapb_receive_frame, | 1681 | .func = x25_lapb_receive_frame, |