.. | .. |
---|
| 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, |
---|