.. | .. |
---|
| 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) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk) |
---|
8 | 5 | * Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk) |
---|
.. | .. |
---|
194 | 191 | rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0); |
---|
195 | 192 | if (rose->neighbour) |
---|
196 | 193 | rose->neighbour->use--; |
---|
| 194 | + dev_put(rose->device); |
---|
197 | 195 | rose->device = NULL; |
---|
198 | 196 | } |
---|
199 | 197 | } |
---|
.. | .. |
---|
368 | 366 | */ |
---|
369 | 367 | |
---|
370 | 368 | static int rose_setsockopt(struct socket *sock, int level, int optname, |
---|
371 | | - char __user *optval, unsigned int optlen) |
---|
| 369 | + sockptr_t optval, unsigned int optlen) |
---|
372 | 370 | { |
---|
373 | 371 | struct sock *sk = sock->sk; |
---|
374 | 372 | struct rose_sock *rose = rose_sk(sk); |
---|
.. | .. |
---|
380 | 378 | if (optlen < sizeof(int)) |
---|
381 | 379 | return -EINVAL; |
---|
382 | 380 | |
---|
383 | | - if (get_user(opt, (int __user *)optval)) |
---|
| 381 | + if (copy_from_sockptr(&opt, optval, sizeof(int))) |
---|
384 | 382 | return -EFAULT; |
---|
385 | 383 | |
---|
386 | 384 | switch (optname) { |
---|
.. | .. |
---|
489 | 487 | { |
---|
490 | 488 | struct sock *sk = sock->sk; |
---|
491 | 489 | |
---|
| 490 | + lock_sock(sk); |
---|
| 491 | + if (sock->state != SS_UNCONNECTED) { |
---|
| 492 | + release_sock(sk); |
---|
| 493 | + return -EINVAL; |
---|
| 494 | + } |
---|
| 495 | + |
---|
492 | 496 | if (sk->sk_state != TCP_LISTEN) { |
---|
493 | 497 | struct rose_sock *rose = rose_sk(sk); |
---|
494 | 498 | |
---|
.. | .. |
---|
498 | 502 | memset(rose->dest_digis, 0, AX25_ADDR_LEN * ROSE_MAX_DIGIS); |
---|
499 | 503 | sk->sk_max_ack_backlog = backlog; |
---|
500 | 504 | sk->sk_state = TCP_LISTEN; |
---|
| 505 | + release_sock(sk); |
---|
501 | 506 | return 0; |
---|
502 | 507 | } |
---|
| 508 | + release_sock(sk); |
---|
503 | 509 | |
---|
504 | 510 | return -EOPNOTSUPP; |
---|
505 | 511 | } |
---|
.. | .. |
---|
594 | 600 | rose->idle = orose->idle; |
---|
595 | 601 | rose->defer = orose->defer; |
---|
596 | 602 | rose->device = orose->device; |
---|
| 603 | + if (rose->device) |
---|
| 604 | + dev_hold(rose->device); |
---|
597 | 605 | rose->qbitincl = orose->qbitincl; |
---|
598 | 606 | |
---|
599 | 607 | return sk; |
---|
.. | .. |
---|
647 | 655 | break; |
---|
648 | 656 | } |
---|
649 | 657 | |
---|
| 658 | + dev_put(rose->device); |
---|
650 | 659 | sock->sk = NULL; |
---|
651 | 660 | release_sock(sk); |
---|
652 | 661 | sock_put(sk); |
---|
.. | .. |
---|
689 | 698 | rose->source_call = user->call; |
---|
690 | 699 | ax25_uid_put(user); |
---|
691 | 700 | } else { |
---|
692 | | - if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) |
---|
| 701 | + if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) { |
---|
| 702 | + dev_put(dev); |
---|
693 | 703 | return -EACCES; |
---|
| 704 | + } |
---|
694 | 705 | rose->source_call = *source; |
---|
695 | 706 | } |
---|
696 | 707 | |
---|
.. | .. |
---|
721 | 732 | struct rose_sock *rose = rose_sk(sk); |
---|
722 | 733 | struct sockaddr_rose *addr = (struct sockaddr_rose *)uaddr; |
---|
723 | 734 | unsigned char cause, diagnostic; |
---|
724 | | - struct net_device *dev; |
---|
725 | 735 | ax25_uid_assoc *user; |
---|
726 | 736 | int n, err = 0; |
---|
727 | 737 | |
---|
.. | .. |
---|
778 | 788 | } |
---|
779 | 789 | |
---|
780 | 790 | if (sock_flag(sk, SOCK_ZAPPED)) { /* Must bind first - autobinding in this may or may not work */ |
---|
| 791 | + struct net_device *dev; |
---|
| 792 | + |
---|
781 | 793 | sock_reset_flag(sk, SOCK_ZAPPED); |
---|
782 | 794 | |
---|
783 | | - if ((dev = rose_dev_first()) == NULL) { |
---|
| 795 | + dev = rose_dev_first(); |
---|
| 796 | + if (!dev) { |
---|
784 | 797 | err = -ENETUNREACH; |
---|
785 | 798 | goto out_release; |
---|
786 | 799 | } |
---|
.. | .. |
---|
788 | 801 | user = ax25_findbyuid(current_euid()); |
---|
789 | 802 | if (!user) { |
---|
790 | 803 | err = -EINVAL; |
---|
| 804 | + dev_put(dev); |
---|
791 | 805 | goto out_release; |
---|
792 | 806 | } |
---|
793 | 807 | |
---|
.. | .. |
---|
929 | 943 | /* Now attach up the new socket */ |
---|
930 | 944 | skb->sk = NULL; |
---|
931 | 945 | kfree_skb(skb); |
---|
932 | | - sk->sk_ack_backlog--; |
---|
| 946 | + sk_acceptq_removed(sk); |
---|
933 | 947 | |
---|
934 | 948 | out_release: |
---|
935 | 949 | release_sock(sk); |
---|
.. | .. |
---|
1034 | 1048 | make_rose->va = 0; |
---|
1035 | 1049 | make_rose->vr = 0; |
---|
1036 | 1050 | make_rose->vl = 0; |
---|
1037 | | - sk->sk_ack_backlog++; |
---|
| 1051 | + sk_acceptq_added(sk); |
---|
1038 | 1052 | |
---|
1039 | 1053 | rose_insert_socket(make); |
---|
1040 | 1054 | |
---|
.. | .. |
---|
1299 | 1313 | return put_user(amount, (unsigned int __user *) argp); |
---|
1300 | 1314 | } |
---|
1301 | 1315 | |
---|
1302 | | - case SIOCGSTAMP: |
---|
1303 | | - return sock_get_timestamp(sk, (struct timeval __user *) argp); |
---|
1304 | | - |
---|
1305 | | - case SIOCGSTAMPNS: |
---|
1306 | | - return sock_get_timestampns(sk, (struct timespec __user *) argp); |
---|
1307 | | - |
---|
1308 | 1316 | case SIOCGIFADDR: |
---|
1309 | 1317 | case SIOCSIFADDR: |
---|
1310 | 1318 | case SIOCGIFDSTADDR: |
---|
.. | .. |
---|
1472 | 1480 | .getname = rose_getname, |
---|
1473 | 1481 | .poll = datagram_poll, |
---|
1474 | 1482 | .ioctl = rose_ioctl, |
---|
| 1483 | + .gettstamp = sock_gettstamp, |
---|
1475 | 1484 | .listen = rose_listen, |
---|
1476 | 1485 | .shutdown = sock_no_shutdown, |
---|
1477 | 1486 | .setsockopt = rose_setsockopt, |
---|
.. | .. |
---|
1503 | 1512 | int rc; |
---|
1504 | 1513 | |
---|
1505 | 1514 | if (rose_ndevs > 0x7FFFFFFF/sizeof(struct net_device *)) { |
---|
1506 | | - printk(KERN_ERR "ROSE: rose_proto_init - rose_ndevs parameter to large\n"); |
---|
| 1515 | + printk(KERN_ERR "ROSE: rose_proto_init - rose_ndevs parameter too large\n"); |
---|
1507 | 1516 | rc = -EINVAL; |
---|
1508 | 1517 | goto out; |
---|
1509 | 1518 | } |
---|