| .. | .. |
|---|
| 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) |
|---|
| .. | .. |
|---|
| 497 | 492 | int rc = -EOPNOTSUPP; |
|---|
| 498 | 493 | |
|---|
| 499 | 494 | lock_sock(sk); |
|---|
| 495 | + if (sock->state != SS_UNCONNECTED) { |
|---|
| 496 | + rc = -EINVAL; |
|---|
| 497 | + release_sock(sk); |
|---|
| 498 | + return rc; |
|---|
| 499 | + } |
|---|
| 500 | + |
|---|
| 500 | 501 | if (sk->sk_state != TCP_LISTEN) { |
|---|
| 501 | 502 | memset(&x25_sk(sk)->dest_addr, 0, X25_ADDR_LEN); |
|---|
| 502 | 503 | sk->sk_max_ack_backlog = backlog; |
|---|
| .. | .. |
|---|
| 664 | 665 | sock_set_flag(sk, SOCK_DEAD); |
|---|
| 665 | 666 | sock_set_flag(sk, SOCK_DESTROY); |
|---|
| 666 | 667 | break; |
|---|
| 668 | + |
|---|
| 669 | + case X25_STATE_5: |
|---|
| 670 | + x25_write_internal(sk, X25_CLEAR_REQUEST); |
|---|
| 671 | + x25_disconnect(sk, 0, 0, 0); |
|---|
| 672 | + __x25_destroy_socket(sk); |
|---|
| 673 | + goto out; |
|---|
| 667 | 674 | } |
|---|
| 668 | 675 | |
|---|
| 669 | 676 | sock_orphan(sk); |
|---|
| .. | .. |
|---|
| 902 | 909 | /* Now attach up the new socket */ |
|---|
| 903 | 910 | skb->sk = NULL; |
|---|
| 904 | 911 | kfree_skb(skb); |
|---|
| 905 | | - sk->sk_ack_backlog--; |
|---|
| 912 | + sk_acceptq_removed(sk); |
|---|
| 906 | 913 | newsock->state = SS_CONNECTED; |
|---|
| 907 | 914 | rc = 0; |
|---|
| 908 | 915 | out2: |
|---|
| .. | .. |
|---|
| 1066 | 1073 | if (test_bit(X25_ACCPT_APPRV_FLAG, &makex25->flags)) { |
|---|
| 1067 | 1074 | x25_write_internal(make, X25_CALL_ACCEPTED); |
|---|
| 1068 | 1075 | makex25->state = X25_STATE_3; |
|---|
| 1076 | + } else { |
|---|
| 1077 | + makex25->state = X25_STATE_5; |
|---|
| 1069 | 1078 | } |
|---|
| 1070 | 1079 | |
|---|
| 1071 | 1080 | /* |
|---|
| .. | .. |
|---|
| 1074 | 1083 | skb_copy_from_linear_data(skb, makex25->calluserdata.cuddata, skb->len); |
|---|
| 1075 | 1084 | makex25->calluserdata.cudlength = skb->len; |
|---|
| 1076 | 1085 | |
|---|
| 1077 | | - sk->sk_ack_backlog++; |
|---|
| 1086 | + sk_acceptq_added(sk); |
|---|
| 1078 | 1087 | |
|---|
| 1079 | 1088 | x25_insert_socket(make); |
|---|
| 1080 | 1089 | |
|---|
| .. | .. |
|---|
| 1405 | 1414 | break; |
|---|
| 1406 | 1415 | } |
|---|
| 1407 | 1416 | |
|---|
| 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 | 1417 | case SIOCGIFADDR: |
|---|
| 1421 | 1418 | case SIOCSIFADDR: |
|---|
| 1422 | 1419 | case SIOCGIFDSTADDR: |
|---|
| .. | .. |
|---|
| 1688 | 1685 | unsigned long arg) |
|---|
| 1689 | 1686 | { |
|---|
| 1690 | 1687 | void __user *argp = compat_ptr(arg); |
|---|
| 1691 | | - struct sock *sk = sock->sk; |
|---|
| 1692 | | - |
|---|
| 1693 | 1688 | int rc = -ENOIOCTLCMD; |
|---|
| 1694 | 1689 | |
|---|
| 1695 | 1690 | switch(cmd) { |
|---|
| 1696 | 1691 | case TIOCOUTQ: |
|---|
| 1697 | 1692 | case TIOCINQ: |
|---|
| 1698 | 1693 | 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 | 1694 | break; |
|---|
| 1712 | 1695 | case SIOCGIFADDR: |
|---|
| 1713 | 1696 | case SIOCSIFADDR: |
|---|
| .. | .. |
|---|
| 1772 | 1755 | #ifdef CONFIG_COMPAT |
|---|
| 1773 | 1756 | .compat_ioctl = compat_x25_ioctl, |
|---|
| 1774 | 1757 | #endif |
|---|
| 1758 | + .gettstamp = sock_gettstamp, |
|---|
| 1775 | 1759 | .listen = x25_listen, |
|---|
| 1776 | 1760 | .shutdown = sock_no_shutdown, |
|---|
| 1777 | 1761 | .setsockopt = x25_setsockopt, |
|---|
| .. | .. |
|---|
| 1797 | 1781 | |
|---|
| 1798 | 1782 | write_lock_bh(&x25_list_lock); |
|---|
| 1799 | 1783 | |
|---|
| 1800 | | - sk_for_each(s, &x25_list) |
|---|
| 1801 | | - if (x25_sk(s)->neighbour == nb) |
|---|
| 1784 | + sk_for_each(s, &x25_list) { |
|---|
| 1785 | + if (x25_sk(s)->neighbour == nb) { |
|---|
| 1786 | + write_unlock_bh(&x25_list_lock); |
|---|
| 1787 | + lock_sock(s); |
|---|
| 1802 | 1788 | x25_disconnect(s, ENETUNREACH, 0, 0); |
|---|
| 1803 | | - |
|---|
| 1789 | + release_sock(s); |
|---|
| 1790 | + write_lock_bh(&x25_list_lock); |
|---|
| 1791 | + } |
|---|
| 1792 | + } |
|---|
| 1804 | 1793 | write_unlock_bh(&x25_list_lock); |
|---|
| 1805 | 1794 | |
|---|
| 1806 | 1795 | /* Remove any related forwards */ |
|---|