| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * X.25 Packet Layer release 002 |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 6 | 7 | * screw up. It might even work. |
|---|
| 7 | 8 | * |
|---|
| 8 | 9 | * This code REQUIRES 2.1.15 or higher |
|---|
| 9 | | - * |
|---|
| 10 | | - * This module: |
|---|
| 11 | | - * This module is free software; you can redistribute it and/or |
|---|
| 12 | | - * modify it under the terms of the GNU General Public License |
|---|
| 13 | | - * as published by the Free Software Foundation; either version |
|---|
| 14 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 15 | 10 | * |
|---|
| 16 | 11 | * History |
|---|
| 17 | 12 | * X.25 001 Jonathan Naylor Started coding. |
|---|
| .. | .. |
|---|
| 436 | 431 | */ |
|---|
| 437 | 432 | |
|---|
| 438 | 433 | static int x25_setsockopt(struct socket *sock, int level, int optname, |
|---|
| 439 | | - char __user *optval, unsigned int optlen) |
|---|
| 434 | + sockptr_t optval, unsigned int optlen) |
|---|
| 440 | 435 | { |
|---|
| 441 | 436 | int opt; |
|---|
| 442 | 437 | struct sock *sk = sock->sk; |
|---|
| .. | .. |
|---|
| 450 | 445 | goto out; |
|---|
| 451 | 446 | |
|---|
| 452 | 447 | rc = -EFAULT; |
|---|
| 453 | | - if (get_user(opt, (int __user *)optval)) |
|---|
| 448 | + if (copy_from_sockptr(&opt, optval, sizeof(int))) |
|---|
| 454 | 449 | goto out; |
|---|
| 455 | 450 | |
|---|
| 456 | 451 | if (opt) |
|---|
| .. | .. |
|---|
| 664 | 659 | sock_set_flag(sk, SOCK_DEAD); |
|---|
| 665 | 660 | sock_set_flag(sk, SOCK_DESTROY); |
|---|
| 666 | 661 | break; |
|---|
| 662 | + |
|---|
| 663 | + case X25_STATE_5: |
|---|
| 664 | + x25_write_internal(sk, X25_CLEAR_REQUEST); |
|---|
| 665 | + x25_disconnect(sk, 0, 0, 0); |
|---|
| 666 | + __x25_destroy_socket(sk); |
|---|
| 667 | + goto out; |
|---|
| 667 | 668 | } |
|---|
| 668 | 669 | |
|---|
| 669 | 670 | sock_orphan(sk); |
|---|
| .. | .. |
|---|
| 902 | 903 | /* Now attach up the new socket */ |
|---|
| 903 | 904 | skb->sk = NULL; |
|---|
| 904 | 905 | kfree_skb(skb); |
|---|
| 905 | | - sk->sk_ack_backlog--; |
|---|
| 906 | + sk_acceptq_removed(sk); |
|---|
| 906 | 907 | newsock->state = SS_CONNECTED; |
|---|
| 907 | 908 | rc = 0; |
|---|
| 908 | 909 | out2: |
|---|
| .. | .. |
|---|
| 1066 | 1067 | if (test_bit(X25_ACCPT_APPRV_FLAG, &makex25->flags)) { |
|---|
| 1067 | 1068 | x25_write_internal(make, X25_CALL_ACCEPTED); |
|---|
| 1068 | 1069 | makex25->state = X25_STATE_3; |
|---|
| 1070 | + } else { |
|---|
| 1071 | + makex25->state = X25_STATE_5; |
|---|
| 1069 | 1072 | } |
|---|
| 1070 | 1073 | |
|---|
| 1071 | 1074 | /* |
|---|
| .. | .. |
|---|
| 1074 | 1077 | skb_copy_from_linear_data(skb, makex25->calluserdata.cuddata, skb->len); |
|---|
| 1075 | 1078 | makex25->calluserdata.cudlength = skb->len; |
|---|
| 1076 | 1079 | |
|---|
| 1077 | | - sk->sk_ack_backlog++; |
|---|
| 1080 | + sk_acceptq_added(sk); |
|---|
| 1078 | 1081 | |
|---|
| 1079 | 1082 | x25_insert_socket(make); |
|---|
| 1080 | 1083 | |
|---|
| .. | .. |
|---|
| 1405 | 1408 | break; |
|---|
| 1406 | 1409 | } |
|---|
| 1407 | 1410 | |
|---|
| 1408 | | - case SIOCGSTAMP: |
|---|
| 1409 | | - rc = -EINVAL; |
|---|
| 1410 | | - if (sk) |
|---|
| 1411 | | - rc = sock_get_timestamp(sk, |
|---|
| 1412 | | - (struct timeval __user *)argp); |
|---|
| 1413 | | - break; |
|---|
| 1414 | | - case SIOCGSTAMPNS: |
|---|
| 1415 | | - rc = -EINVAL; |
|---|
| 1416 | | - if (sk) |
|---|
| 1417 | | - rc = sock_get_timestampns(sk, |
|---|
| 1418 | | - (struct timespec __user *)argp); |
|---|
| 1419 | | - break; |
|---|
| 1420 | 1411 | case SIOCGIFADDR: |
|---|
| 1421 | 1412 | case SIOCSIFADDR: |
|---|
| 1422 | 1413 | case SIOCGIFDSTADDR: |
|---|
| .. | .. |
|---|
| 1688 | 1679 | unsigned long arg) |
|---|
| 1689 | 1680 | { |
|---|
| 1690 | 1681 | void __user *argp = compat_ptr(arg); |
|---|
| 1691 | | - struct sock *sk = sock->sk; |
|---|
| 1692 | | - |
|---|
| 1693 | 1682 | int rc = -ENOIOCTLCMD; |
|---|
| 1694 | 1683 | |
|---|
| 1695 | 1684 | switch(cmd) { |
|---|
| 1696 | 1685 | case TIOCOUTQ: |
|---|
| 1697 | 1686 | case TIOCINQ: |
|---|
| 1698 | 1687 | rc = x25_ioctl(sock, cmd, (unsigned long)argp); |
|---|
| 1699 | | - break; |
|---|
| 1700 | | - case SIOCGSTAMP: |
|---|
| 1701 | | - rc = -EINVAL; |
|---|
| 1702 | | - if (sk) |
|---|
| 1703 | | - rc = compat_sock_get_timestamp(sk, |
|---|
| 1704 | | - (struct timeval __user*)argp); |
|---|
| 1705 | | - break; |
|---|
| 1706 | | - case SIOCGSTAMPNS: |
|---|
| 1707 | | - rc = -EINVAL; |
|---|
| 1708 | | - if (sk) |
|---|
| 1709 | | - rc = compat_sock_get_timestampns(sk, |
|---|
| 1710 | | - (struct timespec __user*)argp); |
|---|
| 1711 | 1688 | break; |
|---|
| 1712 | 1689 | case SIOCGIFADDR: |
|---|
| 1713 | 1690 | case SIOCSIFADDR: |
|---|
| .. | .. |
|---|
| 1772 | 1749 | #ifdef CONFIG_COMPAT |
|---|
| 1773 | 1750 | .compat_ioctl = compat_x25_ioctl, |
|---|
| 1774 | 1751 | #endif |
|---|
| 1752 | + .gettstamp = sock_gettstamp, |
|---|
| 1775 | 1753 | .listen = x25_listen, |
|---|
| 1776 | 1754 | .shutdown = sock_no_shutdown, |
|---|
| 1777 | 1755 | .setsockopt = x25_setsockopt, |
|---|
| .. | .. |
|---|
| 1797 | 1775 | |
|---|
| 1798 | 1776 | write_lock_bh(&x25_list_lock); |
|---|
| 1799 | 1777 | |
|---|
| 1800 | | - sk_for_each(s, &x25_list) |
|---|
| 1801 | | - if (x25_sk(s)->neighbour == nb) |
|---|
| 1778 | + sk_for_each(s, &x25_list) { |
|---|
| 1779 | + if (x25_sk(s)->neighbour == nb) { |
|---|
| 1780 | + write_unlock_bh(&x25_list_lock); |
|---|
| 1781 | + lock_sock(s); |
|---|
| 1802 | 1782 | x25_disconnect(s, ENETUNREACH, 0, 0); |
|---|
| 1803 | | - |
|---|
| 1783 | + release_sock(s); |
|---|
| 1784 | + write_lock_bh(&x25_list_lock); |
|---|
| 1785 | + } |
|---|
| 1786 | + } |
|---|
| 1804 | 1787 | write_unlock_bh(&x25_list_lock); |
|---|
| 1805 | 1788 | |
|---|
| 1806 | 1789 | /* Remove any related forwards */ |
|---|