aboutsummaryrefslogtreecommitdiffstats
path: root/net/x25/af_x25.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/x25/af_x25.c')
-rw-r--r--net/x25/af_x25.c115
1 files changed, 93 insertions, 22 deletions
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 7fa9c7ad3d3b..e3219e4cd044 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;
431out: 432out:
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;
460out: 463out:
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}
@@ -501,13 +507,14 @@ out:
501 return sk; 507 return sk;
502} 508}
503 509
504static int x25_create(struct net *net, struct socket *sock, int protocol) 510static int x25_create(struct net *net, struct socket *sock, int protocol,
511 int kern)
505{ 512{
506 struct sock *sk; 513 struct sock *sk;
507 struct x25_sock *x25; 514 struct x25_sock *x25;
508 int rc = -ESOCKTNOSUPPORT; 515 int rc = -ESOCKTNOSUPPORT;
509 516
510 if (net != &init_net) 517 if (!net_eq(net, &init_net))
511 return -EAFNOSUPPORT; 518 return -EAFNOSUPPORT;
512 519
513 if (sock->type != SOCK_SEQPACKET || protocol) 520 if (sock->type != SOCK_SEQPACKET || protocol)
@@ -597,6 +604,7 @@ static int x25_release(struct socket *sock)
597 struct sock *sk = sock->sk; 604 struct sock *sk = sock->sk;
598 struct x25_sock *x25; 605 struct x25_sock *x25;
599 606
607 lock_kernel();
600 if (!sk) 608 if (!sk)
601 goto out; 609 goto out;
602 610
@@ -627,6 +635,7 @@ static int x25_release(struct socket *sock)
627 635
628 sock_orphan(sk); 636 sock_orphan(sk);
629out: 637out:
638 unlock_kernel();
630 return 0; 639 return 0;
631} 640}
632 641
@@ -634,18 +643,23 @@ static int x25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
634{ 643{
635 struct sock *sk = sock->sk; 644 struct sock *sk = sock->sk;
636 struct sockaddr_x25 *addr = (struct sockaddr_x25 *)uaddr; 645 struct sockaddr_x25 *addr = (struct sockaddr_x25 *)uaddr;
646 int rc = 0;
637 647
648 lock_kernel();
638 if (!sock_flag(sk, SOCK_ZAPPED) || 649 if (!sock_flag(sk, SOCK_ZAPPED) ||
639 addr_len != sizeof(struct sockaddr_x25) || 650 addr_len != sizeof(struct sockaddr_x25) ||
640 addr->sx25_family != AF_X25) 651 addr->sx25_family != AF_X25) {
641 return -EINVAL; 652 rc = -EINVAL;
653 goto out;
654 }
642 655
643 x25_sk(sk)->source_addr = addr->sx25_addr; 656 x25_sk(sk)->source_addr = addr->sx25_addr;
644 x25_insert_socket(sk); 657 x25_insert_socket(sk);
645 sock_reset_flag(sk, SOCK_ZAPPED); 658 sock_reset_flag(sk, SOCK_ZAPPED);
646 SOCK_DEBUG(sk, "x25_bind: socket is bound\n"); 659 SOCK_DEBUG(sk, "x25_bind: socket is bound\n");
647 660out:
648 return 0; 661 unlock_kernel();
662 return rc;
649} 663}
650 664
651static int x25_wait_for_connection_establishment(struct sock *sk) 665static int x25_wait_for_connection_establishment(struct sock *sk)
@@ -686,6 +700,7 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr,
686 struct x25_route *rt; 700 struct x25_route *rt;
687 int rc = 0; 701 int rc = 0;
688 702
703 lock_kernel();
689 lock_sock(sk); 704 lock_sock(sk);
690 if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) { 705 if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
691 sock->state = SS_CONNECTED; 706 sock->state = SS_CONNECTED;
@@ -763,6 +778,7 @@ out_put_route:
763 x25_route_put(rt); 778 x25_route_put(rt);
764out: 779out:
765 release_sock(sk); 780 release_sock(sk);
781 unlock_kernel();
766 return rc; 782 return rc;
767} 783}
768 784
@@ -802,6 +818,7 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
802 struct sk_buff *skb; 818 struct sk_buff *skb;
803 int rc = -EINVAL; 819 int rc = -EINVAL;
804 820
821 lock_kernel();
805 if (!sk || sk->sk_state != TCP_LISTEN) 822 if (!sk || sk->sk_state != TCP_LISTEN)
806 goto out; 823 goto out;
807 824
@@ -829,6 +846,7 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags)
829out2: 846out2:
830 release_sock(sk); 847 release_sock(sk);
831out: 848out:
849 unlock_kernel();
832 return rc; 850 return rc;
833} 851}
834 852
@@ -838,10 +856,14 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr,
838 struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)uaddr; 856 struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)uaddr;
839 struct sock *sk = sock->sk; 857 struct sock *sk = sock->sk;
840 struct x25_sock *x25 = x25_sk(sk); 858 struct x25_sock *x25 = x25_sk(sk);
859 int rc = 0;
841 860
861 lock_kernel();
842 if (peer) { 862 if (peer) {
843 if (sk->sk_state != TCP_ESTABLISHED) 863 if (sk->sk_state != TCP_ESTABLISHED) {
844 return -ENOTCONN; 864 rc = -ENOTCONN;
865 goto out;
866 }
845 sx25->sx25_addr = x25->dest_addr; 867 sx25->sx25_addr = x25->dest_addr;
846 } else 868 } else
847 sx25->sx25_addr = x25->source_addr; 869 sx25->sx25_addr = x25->source_addr;
@@ -849,7 +871,21 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr,
849 sx25->sx25_family = AF_X25; 871 sx25->sx25_family = AF_X25;
850 *uaddr_len = sizeof(*sx25); 872 *uaddr_len = sizeof(*sx25);
851 873
852 return 0; 874out:
875 unlock_kernel();
876 return rc;
877}
878
879static 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;
853} 889}
854 890
855int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, 891int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
@@ -1002,6 +1038,7 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock,
1002 size_t size; 1038 size_t size;
1003 int qbit = 0, rc = -EINVAL; 1039 int qbit = 0, rc = -EINVAL;
1004 1040
1041 lock_kernel();
1005 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))
1006 goto out; 1043 goto out;
1007 1044
@@ -1166,6 +1203,7 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock,
1166 release_sock(sk); 1203 release_sock(sk);
1167 rc = len; 1204 rc = len;
1168out: 1205out:
1206 unlock_kernel();
1169 return rc; 1207 return rc;
1170out_kfree_skb: 1208out_kfree_skb:
1171 kfree_skb(skb); 1209 kfree_skb(skb);
@@ -1186,6 +1224,7 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
1186 unsigned char *asmptr; 1224 unsigned char *asmptr;
1187 int rc = -ENOTCONN; 1225 int rc = -ENOTCONN;
1188 1226
1227 lock_kernel();
1189 /* 1228 /*
1190 * 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
1191 * us! We do one quick check first though 1230 * us! We do one quick check first though
@@ -1259,6 +1298,7 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
1259out_free_dgram: 1298out_free_dgram:
1260 skb_free_datagram(sk, skb); 1299 skb_free_datagram(sk, skb);
1261out: 1300out:
1301 unlock_kernel();
1262 return rc; 1302 return rc;
1263} 1303}
1264 1304
@@ -1270,6 +1310,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1270 void __user *argp = (void __user *)arg; 1310 void __user *argp = (void __user *)arg;
1271 int rc; 1311 int rc;
1272 1312
1313 lock_kernel();
1273 switch (cmd) { 1314 switch (cmd) {
1274 case TIOCOUTQ: { 1315 case TIOCOUTQ: {
1275 int amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); 1316 int amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
@@ -1363,7 +1404,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1363 facilities.throughput > 0xDD) 1404 facilities.throughput > 0xDD)
1364 break; 1405 break;
1365 if (facilities.reverse && 1406 if (facilities.reverse &&
1366 (facilities.reverse | 0x81)!= 0x81) 1407 (facilities.reverse & 0x81) != 0x81)
1367 break; 1408 break;
1368 x25->facilities = facilities; 1409 x25->facilities = facilities;
1369 rc = 0; 1410 rc = 0;
@@ -1430,6 +1471,17 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1430 break; 1471 break;
1431 } 1472 }
1432 1473
1474 case SIOCX25SCAUSEDIAG: {
1475 struct x25_causediag causediag;
1476 rc = -EFAULT;
1477 if (copy_from_user(&causediag, argp, sizeof(causediag)))
1478 break;
1479 x25->causediag = causediag;
1480 rc = 0;
1481 break;
1482
1483 }
1484
1433 case SIOCX25SCUDMATCHLEN: { 1485 case SIOCX25SCUDMATCHLEN: {
1434 struct x25_subaddr sub_addr; 1486 struct x25_subaddr sub_addr;
1435 rc = -EINVAL; 1487 rc = -EINVAL;
@@ -1472,11 +1524,12 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1472 rc = -ENOIOCTLCMD; 1524 rc = -ENOIOCTLCMD;
1473 break; 1525 break;
1474 } 1526 }
1527 unlock_kernel();
1475 1528
1476 return rc; 1529 return rc;
1477} 1530}
1478 1531
1479static struct net_proto_family x25_family_ops = { 1532static const struct net_proto_family x25_family_ops = {
1480 .family = AF_X25, 1533 .family = AF_X25,
1481 .create = x25_create, 1534 .create = x25_create,
1482 .owner = THIS_MODULE, 1535 .owner = THIS_MODULE,
@@ -1542,15 +1595,19 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd,
1542 break; 1595 break;
1543 case SIOCGSTAMP: 1596 case SIOCGSTAMP:
1544 rc = -EINVAL; 1597 rc = -EINVAL;
1598 lock_kernel();
1545 if (sk) 1599 if (sk)
1546 rc = compat_sock_get_timestamp(sk, 1600 rc = compat_sock_get_timestamp(sk,
1547 (struct timeval __user*)argp); 1601 (struct timeval __user*)argp);
1602 unlock_kernel();
1548 break; 1603 break;
1549 case SIOCGSTAMPNS: 1604 case SIOCGSTAMPNS:
1550 rc = -EINVAL; 1605 rc = -EINVAL;
1606 lock_kernel();
1551 if (sk) 1607 if (sk)
1552 rc = compat_sock_get_timestampns(sk, 1608 rc = compat_sock_get_timestampns(sk,
1553 (struct timespec __user*)argp); 1609 (struct timespec __user*)argp);
1610 unlock_kernel();
1554 break; 1611 break;
1555 case SIOCGIFADDR: 1612 case SIOCGIFADDR:
1556 case SIOCSIFADDR: 1613 case SIOCSIFADDR:
@@ -1569,16 +1626,22 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd,
1569 rc = -EPERM; 1626 rc = -EPERM;
1570 if (!capable(CAP_NET_ADMIN)) 1627 if (!capable(CAP_NET_ADMIN))
1571 break; 1628 break;
1629 lock_kernel();
1572 rc = x25_route_ioctl(cmd, argp); 1630 rc = x25_route_ioctl(cmd, argp);
1631 unlock_kernel();
1573 break; 1632 break;
1574 case SIOCX25GSUBSCRIP: 1633 case SIOCX25GSUBSCRIP:
1634 lock_kernel();
1575 rc = compat_x25_subscr_ioctl(cmd, argp); 1635 rc = compat_x25_subscr_ioctl(cmd, argp);
1636 unlock_kernel();
1576 break; 1637 break;
1577 case SIOCX25SSUBSCRIP: 1638 case SIOCX25SSUBSCRIP:
1578 rc = -EPERM; 1639 rc = -EPERM;
1579 if (!capable(CAP_NET_ADMIN)) 1640 if (!capable(CAP_NET_ADMIN))
1580 break; 1641 break;
1642 lock_kernel();
1581 rc = compat_x25_subscr_ioctl(cmd, argp); 1643 rc = compat_x25_subscr_ioctl(cmd, argp);
1644 unlock_kernel();
1582 break; 1645 break;
1583 case SIOCX25GFACILITIES: 1646 case SIOCX25GFACILITIES:
1584 case SIOCX25SFACILITIES: 1647 case SIOCX25SFACILITIES:
@@ -1587,6 +1650,7 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd,
1587 case SIOCX25GCALLUSERDATA: 1650 case SIOCX25GCALLUSERDATA:
1588 case SIOCX25SCALLUSERDATA: 1651 case SIOCX25SCALLUSERDATA:
1589 case SIOCX25GCAUSEDIAG: 1652 case SIOCX25GCAUSEDIAG:
1653 case SIOCX25SCAUSEDIAG:
1590 case SIOCX25SCUDMATCHLEN: 1654 case SIOCX25SCUDMATCHLEN:
1591 case SIOCX25CALLACCPTAPPRV: 1655 case SIOCX25CALLACCPTAPPRV:
1592 case SIOCX25SENDCALLACCPT: 1656 case SIOCX25SENDCALLACCPT:
@@ -1600,7 +1664,7 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd,
1600} 1664}
1601#endif 1665#endif
1602 1666
1603static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = { 1667static const struct proto_ops x25_proto_ops = {
1604 .family = AF_X25, 1668 .family = AF_X25,
1605 .owner = THIS_MODULE, 1669 .owner = THIS_MODULE,
1606 .release = x25_release, 1670 .release = x25_release,
@@ -1609,7 +1673,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
1609 .socketpair = sock_no_socketpair, 1673 .socketpair = sock_no_socketpair,
1610 .accept = x25_accept, 1674 .accept = x25_accept,
1611 .getname = x25_getname, 1675 .getname = x25_getname,
1612 .poll = datagram_poll, 1676 .poll = x25_datagram_poll,
1613 .ioctl = x25_ioctl, 1677 .ioctl = x25_ioctl,
1614#ifdef CONFIG_COMPAT 1678#ifdef CONFIG_COMPAT
1615 .compat_ioctl = compat_x25_ioctl, 1679 .compat_ioctl = compat_x25_ioctl,
@@ -1624,8 +1688,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
1624 .sendpage = sock_no_sendpage, 1688 .sendpage = sock_no_sendpage,
1625}; 1689};
1626 1690
1627SOCKOPS_WRAP(x25_proto, AF_X25);
1628
1629static struct packet_type x25_packet_type __read_mostly = { 1691static struct packet_type x25_packet_type __read_mostly = {
1630 .type = cpu_to_be16(ETH_P_X25), 1692 .type = cpu_to_be16(ETH_P_X25),
1631 .func = x25_lapb_receive_frame, 1693 .func = x25_lapb_receive_frame,
@@ -1659,20 +1721,31 @@ static int __init x25_init(void)
1659 if (rc != 0) 1721 if (rc != 0)
1660 goto out; 1722 goto out;
1661 1723
1662 sock_register(&x25_family_ops); 1724 rc = sock_register(&x25_family_ops);
1725 if (rc != 0)
1726 goto out_proto;
1663 1727
1664 dev_add_pack(&x25_packet_type); 1728 dev_add_pack(&x25_packet_type);
1665 1729
1666 register_netdevice_notifier(&x25_dev_notifier); 1730 rc = register_netdevice_notifier(&x25_dev_notifier);
1731 if (rc != 0)
1732 goto out_sock;
1667 1733
1668 printk(KERN_INFO "X.25 for Linux Version 0.2\n"); 1734 printk(KERN_INFO "X.25 for Linux Version 0.2\n");
1669 1735
1670#ifdef CONFIG_SYSCTL
1671 x25_register_sysctl(); 1736 x25_register_sysctl();
1672#endif 1737 rc = x25_proc_init();
1673 x25_proc_init(); 1738 if (rc != 0)
1739 goto out_dev;
1674out: 1740out:
1675 return rc; 1741 return rc;
1742out_dev:
1743 unregister_netdevice_notifier(&x25_dev_notifier);
1744out_sock:
1745 sock_unregister(AF_X25);
1746out_proto:
1747 proto_unregister(&x25_proto);
1748 goto out;
1676} 1749}
1677module_init(x25_init); 1750module_init(x25_init);
1678 1751
@@ -1682,9 +1755,7 @@ static void __exit x25_exit(void)
1682 x25_link_free(); 1755 x25_link_free();
1683 x25_route_free(); 1756 x25_route_free();
1684 1757
1685#ifdef CONFIG_SYSCTL
1686 x25_unregister_sysctl(); 1758 x25_unregister_sysctl();
1687#endif
1688 1759
1689 unregister_netdevice_notifier(&x25_dev_notifier); 1760 unregister_netdevice_notifier(&x25_dev_notifier);
1690 1761