| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 3 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 4 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 5 | | - * (at your option) any later version. |
|---|
| 6 | 3 | * |
|---|
| 7 | 4 | * Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk) |
|---|
| 8 | 5 | * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk) |
|---|
| .. | .. |
|---|
| 90 | 87 | ax25_for_each(s, &ax25_list) { |
|---|
| 91 | 88 | if (s->ax25_dev == ax25_dev) { |
|---|
| 92 | 89 | sk = s->sk; |
|---|
| 90 | + if (!sk) { |
|---|
| 91 | + spin_unlock_bh(&ax25_list_lock); |
|---|
| 92 | + ax25_disconnect(s, ENETUNREACH); |
|---|
| 93 | + s->ax25_dev = NULL; |
|---|
| 94 | + spin_lock_bh(&ax25_list_lock); |
|---|
| 95 | + goto again; |
|---|
| 96 | + } |
|---|
| 93 | 97 | sock_hold(sk); |
|---|
| 94 | 98 | spin_unlock_bh(&ax25_list_lock); |
|---|
| 95 | 99 | lock_sock(sk); |
|---|
| 96 | | - s->ax25_dev = NULL; |
|---|
| 97 | | - release_sock(sk); |
|---|
| 98 | 100 | ax25_disconnect(s, ENETUNREACH); |
|---|
| 101 | + s->ax25_dev = NULL; |
|---|
| 102 | + if (sk->sk_socket) { |
|---|
| 103 | + dev_put(ax25_dev->dev); |
|---|
| 104 | + ax25_dev_put(ax25_dev); |
|---|
| 105 | + } |
|---|
| 106 | + release_sock(sk); |
|---|
| 99 | 107 | spin_lock_bh(&ax25_list_lock); |
|---|
| 100 | 108 | sock_put(sk); |
|---|
| 101 | 109 | /* The entry could have been deleted from the |
|---|
| .. | .. |
|---|
| 361 | 369 | if (copy_from_user(&ax25_ctl, arg, sizeof(ax25_ctl))) |
|---|
| 362 | 370 | return -EFAULT; |
|---|
| 363 | 371 | |
|---|
| 364 | | - if ((ax25_dev = ax25_addr_ax25dev(&ax25_ctl.port_addr)) == NULL) |
|---|
| 365 | | - return -ENODEV; |
|---|
| 366 | | - |
|---|
| 367 | 372 | if (ax25_ctl.digi_count > AX25_MAX_DIGIS) |
|---|
| 368 | 373 | return -EINVAL; |
|---|
| 369 | 374 | |
|---|
| 370 | 375 | if (ax25_ctl.arg > ULONG_MAX / HZ && ax25_ctl.cmd != AX25_KILL) |
|---|
| 371 | 376 | return -EINVAL; |
|---|
| 372 | 377 | |
|---|
| 378 | + ax25_dev = ax25_addr_ax25dev(&ax25_ctl.port_addr); |
|---|
| 379 | + if (!ax25_dev) |
|---|
| 380 | + return -ENODEV; |
|---|
| 381 | + |
|---|
| 373 | 382 | digi.ndigi = ax25_ctl.digi_count; |
|---|
| 374 | 383 | for (k = 0; k < digi.ndigi; k++) |
|---|
| 375 | 384 | digi.calls[k] = ax25_ctl.digi_addr[k]; |
|---|
| 376 | 385 | |
|---|
| 377 | | - if ((ax25 = ax25_find_cb(&ax25_ctl.source_addr, &ax25_ctl.dest_addr, &digi, ax25_dev->dev)) == NULL) |
|---|
| 386 | + ax25 = ax25_find_cb(&ax25_ctl.source_addr, &ax25_ctl.dest_addr, &digi, ax25_dev->dev); |
|---|
| 387 | + if (!ax25) { |
|---|
| 388 | + ax25_dev_put(ax25_dev); |
|---|
| 378 | 389 | return -ENOTCONN; |
|---|
| 390 | + } |
|---|
| 379 | 391 | |
|---|
| 380 | 392 | switch (ax25_ctl.cmd) { |
|---|
| 381 | 393 | case AX25_KILL: |
|---|
| .. | .. |
|---|
| 442 | 454 | } |
|---|
| 443 | 455 | |
|---|
| 444 | 456 | out_put: |
|---|
| 457 | + ax25_dev_put(ax25_dev); |
|---|
| 445 | 458 | ax25_cb_put(ax25); |
|---|
| 446 | 459 | return ret; |
|---|
| 447 | 460 | |
|---|
| .. | .. |
|---|
| 536 | 549 | */ |
|---|
| 537 | 550 | |
|---|
| 538 | 551 | static int ax25_setsockopt(struct socket *sock, int level, int optname, |
|---|
| 539 | | - char __user *optval, unsigned int optlen) |
|---|
| 552 | + sockptr_t optval, unsigned int optlen) |
|---|
| 540 | 553 | { |
|---|
| 541 | 554 | struct sock *sk = sock->sk; |
|---|
| 542 | 555 | ax25_cb *ax25; |
|---|
| 543 | 556 | struct net_device *dev; |
|---|
| 544 | 557 | char devname[IFNAMSIZ]; |
|---|
| 545 | | - unsigned long opt; |
|---|
| 558 | + unsigned int opt; |
|---|
| 546 | 559 | int res = 0; |
|---|
| 547 | 560 | |
|---|
| 548 | 561 | if (level != SOL_AX25) |
|---|
| .. | .. |
|---|
| 551 | 564 | if (optlen < sizeof(unsigned int)) |
|---|
| 552 | 565 | return -EINVAL; |
|---|
| 553 | 566 | |
|---|
| 554 | | - if (get_user(opt, (unsigned int __user *)optval)) |
|---|
| 567 | + if (copy_from_sockptr(&opt, optval, sizeof(unsigned int))) |
|---|
| 555 | 568 | return -EFAULT; |
|---|
| 556 | 569 | |
|---|
| 557 | 570 | lock_sock(sk); |
|---|
| .. | .. |
|---|
| 574 | 587 | break; |
|---|
| 575 | 588 | |
|---|
| 576 | 589 | case AX25_T1: |
|---|
| 577 | | - if (opt < 1 || opt > ULONG_MAX / HZ) { |
|---|
| 590 | + if (opt < 1 || opt > UINT_MAX / HZ) { |
|---|
| 578 | 591 | res = -EINVAL; |
|---|
| 579 | 592 | break; |
|---|
| 580 | 593 | } |
|---|
| .. | .. |
|---|
| 583 | 596 | break; |
|---|
| 584 | 597 | |
|---|
| 585 | 598 | case AX25_T2: |
|---|
| 586 | | - if (opt < 1 || opt > ULONG_MAX / HZ) { |
|---|
| 599 | + if (opt < 1 || opt > UINT_MAX / HZ) { |
|---|
| 587 | 600 | res = -EINVAL; |
|---|
| 588 | 601 | break; |
|---|
| 589 | 602 | } |
|---|
| .. | .. |
|---|
| 599 | 612 | break; |
|---|
| 600 | 613 | |
|---|
| 601 | 614 | case AX25_T3: |
|---|
| 602 | | - if (opt < 1 || opt > ULONG_MAX / HZ) { |
|---|
| 615 | + if (opt < 1 || opt > UINT_MAX / HZ) { |
|---|
| 603 | 616 | res = -EINVAL; |
|---|
| 604 | 617 | break; |
|---|
| 605 | 618 | } |
|---|
| .. | .. |
|---|
| 607 | 620 | break; |
|---|
| 608 | 621 | |
|---|
| 609 | 622 | case AX25_IDLE: |
|---|
| 610 | | - if (opt > ULONG_MAX / (60 * HZ)) { |
|---|
| 623 | + if (opt > UINT_MAX / (60 * HZ)) { |
|---|
| 611 | 624 | res = -EINVAL; |
|---|
| 612 | 625 | break; |
|---|
| 613 | 626 | } |
|---|
| .. | .. |
|---|
| 648 | 661 | |
|---|
| 649 | 662 | memset(devname, 0, sizeof(devname)); |
|---|
| 650 | 663 | |
|---|
| 651 | | - if (copy_from_user(devname, optval, optlen)) { |
|---|
| 664 | + if (copy_from_sockptr(devname, optval, optlen)) { |
|---|
| 652 | 665 | res = -EFAULT; |
|---|
| 653 | 666 | break; |
|---|
| 654 | 667 | } |
|---|
| .. | .. |
|---|
| 818 | 831 | struct sock *sk; |
|---|
| 819 | 832 | ax25_cb *ax25; |
|---|
| 820 | 833 | |
|---|
| 821 | | - if (protocol < 0 || protocol > SK_PROTOCOL_MAX) |
|---|
| 834 | + if (protocol < 0 || protocol > U8_MAX) |
|---|
| 822 | 835 | return -EINVAL; |
|---|
| 823 | 836 | |
|---|
| 824 | 837 | if (!net_eq(net, &init_net)) |
|---|
| .. | .. |
|---|
| 967 | 980 | { |
|---|
| 968 | 981 | struct sock *sk = sock->sk; |
|---|
| 969 | 982 | ax25_cb *ax25; |
|---|
| 983 | + ax25_dev *ax25_dev; |
|---|
| 970 | 984 | |
|---|
| 971 | 985 | if (sk == NULL) |
|---|
| 972 | 986 | return 0; |
|---|
| 973 | 987 | |
|---|
| 974 | 988 | sock_hold(sk); |
|---|
| 975 | | - sock_orphan(sk); |
|---|
| 976 | 989 | lock_sock(sk); |
|---|
| 990 | + sock_orphan(sk); |
|---|
| 977 | 991 | ax25 = sk_to_ax25(sk); |
|---|
| 992 | + ax25_dev = ax25->ax25_dev; |
|---|
| 978 | 993 | |
|---|
| 979 | 994 | if (sk->sk_type == SOCK_SEQPACKET) { |
|---|
| 980 | 995 | switch (ax25->state) { |
|---|
| .. | .. |
|---|
| 1035 | 1050 | sk->sk_shutdown |= SEND_SHUTDOWN; |
|---|
| 1036 | 1051 | sk->sk_state_change(sk); |
|---|
| 1037 | 1052 | ax25_destroy_socket(ax25); |
|---|
| 1053 | + } |
|---|
| 1054 | + if (ax25_dev) { |
|---|
| 1055 | + del_timer_sync(&ax25->timer); |
|---|
| 1056 | + del_timer_sync(&ax25->t1timer); |
|---|
| 1057 | + del_timer_sync(&ax25->t2timer); |
|---|
| 1058 | + del_timer_sync(&ax25->t3timer); |
|---|
| 1059 | + del_timer_sync(&ax25->idletimer); |
|---|
| 1060 | + dev_put(ax25_dev->dev); |
|---|
| 1061 | + ax25_dev_put(ax25_dev); |
|---|
| 1038 | 1062 | } |
|---|
| 1039 | 1063 | |
|---|
| 1040 | 1064 | sock->sk = NULL; |
|---|
| .. | .. |
|---|
| 1112 | 1136 | } |
|---|
| 1113 | 1137 | } |
|---|
| 1114 | 1138 | |
|---|
| 1115 | | - if (ax25_dev != NULL) |
|---|
| 1139 | + if (ax25_dev) { |
|---|
| 1116 | 1140 | ax25_fillin_cb(ax25, ax25_dev); |
|---|
| 1141 | + dev_hold(ax25_dev->dev); |
|---|
| 1142 | + } |
|---|
| 1117 | 1143 | |
|---|
| 1118 | 1144 | done: |
|---|
| 1119 | 1145 | ax25_cb_add(ax25); |
|---|
| .. | .. |
|---|
| 1397 | 1423 | |
|---|
| 1398 | 1424 | /* Now attach up the new socket */ |
|---|
| 1399 | 1425 | kfree_skb(skb); |
|---|
| 1400 | | - sk->sk_ack_backlog--; |
|---|
| 1426 | + sk_acceptq_removed(sk); |
|---|
| 1401 | 1427 | newsock->state = SS_CONNECTED; |
|---|
| 1402 | 1428 | |
|---|
| 1403 | 1429 | out: |
|---|
| .. | .. |
|---|
| 1627 | 1653 | int flags) |
|---|
| 1628 | 1654 | { |
|---|
| 1629 | 1655 | struct sock *sk = sock->sk; |
|---|
| 1630 | | - struct sk_buff *skb; |
|---|
| 1656 | + struct sk_buff *skb, *last; |
|---|
| 1657 | + struct sk_buff_head *sk_queue; |
|---|
| 1631 | 1658 | int copied; |
|---|
| 1632 | 1659 | int err = 0; |
|---|
| 1660 | + int off = 0; |
|---|
| 1661 | + long timeo; |
|---|
| 1633 | 1662 | |
|---|
| 1634 | 1663 | lock_sock(sk); |
|---|
| 1635 | 1664 | /* |
|---|
| .. | .. |
|---|
| 1641 | 1670 | goto out; |
|---|
| 1642 | 1671 | } |
|---|
| 1643 | 1672 | |
|---|
| 1644 | | - /* Now we can treat all alike */ |
|---|
| 1645 | | - skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, |
|---|
| 1646 | | - flags & MSG_DONTWAIT, &err); |
|---|
| 1647 | | - if (skb == NULL) |
|---|
| 1648 | | - goto out; |
|---|
| 1673 | + /* We need support for non-blocking reads. */ |
|---|
| 1674 | + sk_queue = &sk->sk_receive_queue; |
|---|
| 1675 | + skb = __skb_try_recv_datagram(sk, sk_queue, flags, &off, &err, &last); |
|---|
| 1676 | + /* If no packet is available, release_sock(sk) and try again. */ |
|---|
| 1677 | + if (!skb) { |
|---|
| 1678 | + if (err != -EAGAIN) |
|---|
| 1679 | + goto out; |
|---|
| 1680 | + release_sock(sk); |
|---|
| 1681 | + timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); |
|---|
| 1682 | + while (timeo && !__skb_wait_for_more_packets(sk, sk_queue, &err, |
|---|
| 1683 | + &timeo, last)) { |
|---|
| 1684 | + skb = __skb_try_recv_datagram(sk, sk_queue, flags, &off, |
|---|
| 1685 | + &err, &last); |
|---|
| 1686 | + if (skb) |
|---|
| 1687 | + break; |
|---|
| 1688 | + |
|---|
| 1689 | + if (err != -EAGAIN) |
|---|
| 1690 | + goto done; |
|---|
| 1691 | + } |
|---|
| 1692 | + if (!skb) |
|---|
| 1693 | + goto done; |
|---|
| 1694 | + lock_sock(sk); |
|---|
| 1695 | + } |
|---|
| 1649 | 1696 | |
|---|
| 1650 | 1697 | if (!sk_to_ax25(sk)->pidincl) |
|---|
| 1651 | 1698 | skb_pull(skb, 1); /* Remove PID */ |
|---|
| .. | .. |
|---|
| 1692 | 1739 | out: |
|---|
| 1693 | 1740 | release_sock(sk); |
|---|
| 1694 | 1741 | |
|---|
| 1742 | +done: |
|---|
| 1695 | 1743 | return err; |
|---|
| 1696 | 1744 | } |
|---|
| 1697 | 1745 | |
|---|
| .. | .. |
|---|
| 1728 | 1776 | res = put_user(amount, (int __user *) argp); |
|---|
| 1729 | 1777 | break; |
|---|
| 1730 | 1778 | } |
|---|
| 1731 | | - |
|---|
| 1732 | | - case SIOCGSTAMP: |
|---|
| 1733 | | - res = sock_get_timestamp(sk, argp); |
|---|
| 1734 | | - break; |
|---|
| 1735 | | - |
|---|
| 1736 | | - case SIOCGSTAMPNS: |
|---|
| 1737 | | - res = sock_get_timestampns(sk, argp); |
|---|
| 1738 | | - break; |
|---|
| 1739 | 1779 | |
|---|
| 1740 | 1780 | case SIOCAX25ADDUID: /* Add a uid to the uid/call map table */ |
|---|
| 1741 | 1781 | case SIOCAX25DELUID: /* Delete a uid from the uid/call map table */ |
|---|
| .. | .. |
|---|
| 1903 | 1943 | * magic dev src_addr dest_addr,digi1,digi2,.. st vs vr va t1 t1 t2 t2 t3 t3 idle idle n2 n2 rtt window paclen Snd-Q Rcv-Q inode |
|---|
| 1904 | 1944 | */ |
|---|
| 1905 | 1945 | |
|---|
| 1906 | | - seq_printf(seq, "%8.8lx %s %s%s ", |
|---|
| 1907 | | - (long) ax25, |
|---|
| 1946 | + seq_printf(seq, "%p %s %s%s ", |
|---|
| 1947 | + ax25, |
|---|
| 1908 | 1948 | ax25->ax25_dev == NULL? "???" : ax25->ax25_dev->dev->name, |
|---|
| 1909 | 1949 | ax2asc(buf, &ax25->source_addr), |
|---|
| 1910 | 1950 | ax25->iamdigi? "*":""); |
|---|
| .. | .. |
|---|
| 1965 | 2005 | .getname = ax25_getname, |
|---|
| 1966 | 2006 | .poll = datagram_poll, |
|---|
| 1967 | 2007 | .ioctl = ax25_ioctl, |
|---|
| 2008 | + .gettstamp = sock_gettstamp, |
|---|
| 1968 | 2009 | .listen = ax25_listen, |
|---|
| 1969 | 2010 | .shutdown = ax25_shutdown, |
|---|
| 1970 | 2011 | .setsockopt = ax25_setsockopt, |
|---|