| .. | .. |
|---|
| 1 | | -/* |
|---|
| 2 | | - * raw.c - Raw sockets for protocol family CAN |
|---|
| 1 | +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) |
|---|
| 2 | +/* raw.c - Raw sockets for protocol family CAN |
|---|
| 3 | 3 | * |
|---|
| 4 | 4 | * Copyright (c) 2002-2007 Volkswagen Group Electronic Research |
|---|
| 5 | 5 | * All rights reserved. |
|---|
| .. | .. |
|---|
| 55 | 55 | #include <net/sock.h> |
|---|
| 56 | 56 | #include <net/net_namespace.h> |
|---|
| 57 | 57 | |
|---|
| 58 | | -#define CAN_RAW_VERSION CAN_VERSION |
|---|
| 59 | | - |
|---|
| 60 | 58 | MODULE_DESCRIPTION("PF_CAN raw protocol"); |
|---|
| 61 | 59 | MODULE_LICENSE("Dual BSD/GPL"); |
|---|
| 62 | 60 | MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>"); |
|---|
| 63 | 61 | MODULE_ALIAS("can-proto-1"); |
|---|
| 64 | 62 | |
|---|
| 63 | +#define RAW_MIN_NAMELEN CAN_REQUIRED_SIZE(struct sockaddr_can, can_ifindex) |
|---|
| 64 | + |
|---|
| 65 | 65 | #define MASK_ALL 0 |
|---|
| 66 | 66 | |
|---|
| 67 | | -/* |
|---|
| 68 | | - * A raw socket has a list of can_filters attached to it, each receiving |
|---|
| 67 | +/* A raw socket has a list of can_filters attached to it, each receiving |
|---|
| 69 | 68 | * the CAN frames matching that filter. If the filter list is empty, |
|---|
| 70 | 69 | * no CAN frames will be received by the socket. The default after |
|---|
| 71 | 70 | * opening the socket, is to have one filter which receives all frames. |
|---|
| .. | .. |
|---|
| 100 | 99 | static DEFINE_SPINLOCK(raw_notifier_lock); |
|---|
| 101 | 100 | static struct raw_sock *raw_busy_notifier; |
|---|
| 102 | 101 | |
|---|
| 103 | | -/* |
|---|
| 104 | | - * Return pointer to store the extra msg flags for raw_recvmsg(). |
|---|
| 102 | +/* Return pointer to store the extra msg flags for raw_recvmsg(). |
|---|
| 105 | 103 | * We use the space of one unsigned int beyond the 'struct sockaddr_can' |
|---|
| 106 | 104 | * in skb->cb. |
|---|
| 107 | 105 | */ |
|---|
| .. | .. |
|---|
| 160 | 158 | if (!skb) |
|---|
| 161 | 159 | return; |
|---|
| 162 | 160 | |
|---|
| 163 | | - /* |
|---|
| 164 | | - * Put the datagram to the queue so that raw_recvmsg() can |
|---|
| 165 | | - * get it from there. We need to pass the interface index to |
|---|
| 166 | | - * raw_recvmsg(). We pass a whole struct sockaddr_can in skb->cb |
|---|
| 167 | | - * containing the interface index. |
|---|
| 161 | + /* Put the datagram to the queue so that raw_recvmsg() can get |
|---|
| 162 | + * it from there. We need to pass the interface index to |
|---|
| 163 | + * raw_recvmsg(). We pass a whole struct sockaddr_can in |
|---|
| 164 | + * skb->cb containing the interface index. |
|---|
| 168 | 165 | */ |
|---|
| 169 | 166 | |
|---|
| 170 | 167 | sock_skb_cb_check_size(sizeof(struct sockaddr_can)); |
|---|
| 171 | 168 | addr = (struct sockaddr_can *)skb->cb; |
|---|
| 172 | 169 | memset(addr, 0, sizeof(*addr)); |
|---|
| 173 | | - addr->can_family = AF_CAN; |
|---|
| 170 | + addr->can_family = AF_CAN; |
|---|
| 174 | 171 | addr->can_ifindex = skb->dev->ifindex; |
|---|
| 175 | 172 | |
|---|
| 176 | 173 | /* add CAN specific message flags for raw_recvmsg() */ |
|---|
| .. | .. |
|---|
| 282 | 279 | return; |
|---|
| 283 | 280 | |
|---|
| 284 | 281 | switch (msg) { |
|---|
| 285 | | - |
|---|
| 286 | 282 | case NETDEV_UNREGISTER: |
|---|
| 287 | 283 | lock_sock(sk); |
|---|
| 288 | 284 | /* remove current filters & unregister */ |
|---|
| .. | .. |
|---|
| 293 | 289 | kfree(ro->filter); |
|---|
| 294 | 290 | |
|---|
| 295 | 291 | ro->ifindex = 0; |
|---|
| 296 | | - ro->bound = 0; |
|---|
| 297 | | - ro->count = 0; |
|---|
| 292 | + ro->bound = 0; |
|---|
| 293 | + ro->count = 0; |
|---|
| 298 | 294 | release_sock(sk); |
|---|
| 299 | 295 | |
|---|
| 300 | 296 | sk->sk_err = ENODEV; |
|---|
| .. | .. |
|---|
| 396 | 392 | raw_disable_allfilters(dev_net(dev), dev, sk); |
|---|
| 397 | 393 | dev_put(dev); |
|---|
| 398 | 394 | } |
|---|
| 399 | | - } else |
|---|
| 395 | + } else { |
|---|
| 400 | 396 | raw_disable_allfilters(sock_net(sk), NULL, sk); |
|---|
| 397 | + } |
|---|
| 401 | 398 | } |
|---|
| 402 | 399 | |
|---|
| 403 | 400 | if (ro->count > 1) |
|---|
| 404 | 401 | kfree(ro->filter); |
|---|
| 405 | 402 | |
|---|
| 406 | 403 | ro->ifindex = 0; |
|---|
| 407 | | - ro->bound = 0; |
|---|
| 408 | | - ro->count = 0; |
|---|
| 404 | + ro->bound = 0; |
|---|
| 405 | + ro->count = 0; |
|---|
| 409 | 406 | free_percpu(ro->uniq); |
|---|
| 410 | 407 | |
|---|
| 411 | 408 | sock_orphan(sk); |
|---|
| .. | .. |
|---|
| 426 | 423 | int err = 0; |
|---|
| 427 | 424 | int notify_enetdown = 0; |
|---|
| 428 | 425 | |
|---|
| 429 | | - if (len < sizeof(*addr)) |
|---|
| 426 | + if (len < RAW_MIN_NAMELEN) |
|---|
| 430 | 427 | return -EINVAL; |
|---|
| 431 | 428 | if (addr->can_family != AF_CAN) |
|---|
| 432 | 429 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 477 | 474 | dev, sk); |
|---|
| 478 | 475 | dev_put(dev); |
|---|
| 479 | 476 | } |
|---|
| 480 | | - } else |
|---|
| 477 | + } else { |
|---|
| 481 | 478 | raw_disable_allfilters(sock_net(sk), NULL, sk); |
|---|
| 479 | + } |
|---|
| 482 | 480 | } |
|---|
| 483 | 481 | ro->ifindex = ifindex; |
|---|
| 484 | 482 | ro->bound = 1; |
|---|
| .. | .. |
|---|
| 506 | 504 | if (peer) |
|---|
| 507 | 505 | return -EOPNOTSUPP; |
|---|
| 508 | 506 | |
|---|
| 509 | | - memset(addr, 0, sizeof(*addr)); |
|---|
| 507 | + memset(addr, 0, RAW_MIN_NAMELEN); |
|---|
| 510 | 508 | addr->can_family = AF_CAN; |
|---|
| 511 | 509 | addr->can_ifindex = ro->ifindex; |
|---|
| 512 | 510 | |
|---|
| 513 | | - return sizeof(*addr); |
|---|
| 511 | + return RAW_MIN_NAMELEN; |
|---|
| 514 | 512 | } |
|---|
| 515 | 513 | |
|---|
| 516 | 514 | static int raw_setsockopt(struct socket *sock, int level, int optname, |
|---|
| 517 | | - char __user *optval, unsigned int optlen) |
|---|
| 515 | + sockptr_t optval, unsigned int optlen) |
|---|
| 518 | 516 | { |
|---|
| 519 | 517 | struct sock *sk = sock->sk; |
|---|
| 520 | 518 | struct raw_sock *ro = raw_sk(sk); |
|---|
| .. | .. |
|---|
| 529 | 527 | return -EINVAL; |
|---|
| 530 | 528 | |
|---|
| 531 | 529 | switch (optname) { |
|---|
| 532 | | - |
|---|
| 533 | 530 | case CAN_RAW_FILTER: |
|---|
| 534 | 531 | if (optlen % sizeof(struct can_filter) != 0) |
|---|
| 535 | 532 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 541 | 538 | |
|---|
| 542 | 539 | if (count > 1) { |
|---|
| 543 | 540 | /* filter does not fit into dfilter => alloc space */ |
|---|
| 544 | | - filter = memdup_user(optval, optlen); |
|---|
| 541 | + filter = memdup_sockptr(optval, optlen); |
|---|
| 545 | 542 | if (IS_ERR(filter)) |
|---|
| 546 | 543 | return PTR_ERR(filter); |
|---|
| 547 | 544 | } else if (count == 1) { |
|---|
| 548 | | - if (copy_from_user(&sfilter, optval, sizeof(sfilter))) |
|---|
| 545 | + if (copy_from_sockptr(&sfilter, optval, sizeof(sfilter))) |
|---|
| 549 | 546 | return -EFAULT; |
|---|
| 550 | 547 | } |
|---|
| 551 | 548 | |
|---|
| .. | .. |
|---|
| 607 | 604 | if (optlen != sizeof(err_mask)) |
|---|
| 608 | 605 | return -EINVAL; |
|---|
| 609 | 606 | |
|---|
| 610 | | - if (copy_from_user(&err_mask, optval, optlen)) |
|---|
| 607 | + if (copy_from_sockptr(&err_mask, optval, optlen)) |
|---|
| 611 | 608 | return -EFAULT; |
|---|
| 612 | 609 | |
|---|
| 613 | 610 | err_mask &= CAN_ERR_MASK; |
|---|
| .. | .. |
|---|
| 653 | 650 | if (optlen != sizeof(ro->loopback)) |
|---|
| 654 | 651 | return -EINVAL; |
|---|
| 655 | 652 | |
|---|
| 656 | | - if (copy_from_user(&ro->loopback, optval, optlen)) |
|---|
| 653 | + if (copy_from_sockptr(&ro->loopback, optval, optlen)) |
|---|
| 657 | 654 | return -EFAULT; |
|---|
| 658 | 655 | |
|---|
| 659 | 656 | break; |
|---|
| .. | .. |
|---|
| 662 | 659 | if (optlen != sizeof(ro->recv_own_msgs)) |
|---|
| 663 | 660 | return -EINVAL; |
|---|
| 664 | 661 | |
|---|
| 665 | | - if (copy_from_user(&ro->recv_own_msgs, optval, optlen)) |
|---|
| 662 | + if (copy_from_sockptr(&ro->recv_own_msgs, optval, optlen)) |
|---|
| 666 | 663 | return -EFAULT; |
|---|
| 667 | 664 | |
|---|
| 668 | 665 | break; |
|---|
| .. | .. |
|---|
| 671 | 668 | if (optlen != sizeof(ro->fd_frames)) |
|---|
| 672 | 669 | return -EINVAL; |
|---|
| 673 | 670 | |
|---|
| 674 | | - if (copy_from_user(&ro->fd_frames, optval, optlen)) |
|---|
| 671 | + if (copy_from_sockptr(&ro->fd_frames, optval, optlen)) |
|---|
| 675 | 672 | return -EFAULT; |
|---|
| 676 | 673 | |
|---|
| 677 | 674 | break; |
|---|
| .. | .. |
|---|
| 680 | 677 | if (optlen != sizeof(ro->join_filters)) |
|---|
| 681 | 678 | return -EINVAL; |
|---|
| 682 | 679 | |
|---|
| 683 | | - if (copy_from_user(&ro->join_filters, optval, optlen)) |
|---|
| 680 | + if (copy_from_sockptr(&ro->join_filters, optval, optlen)) |
|---|
| 684 | 681 | return -EFAULT; |
|---|
| 685 | 682 | |
|---|
| 686 | 683 | break; |
|---|
| .. | .. |
|---|
| 708 | 705 | return -EINVAL; |
|---|
| 709 | 706 | |
|---|
| 710 | 707 | switch (optname) { |
|---|
| 711 | | - |
|---|
| 712 | 708 | case CAN_RAW_FILTER: |
|---|
| 713 | 709 | lock_sock(sk); |
|---|
| 714 | 710 | if (ro->count > 0) { |
|---|
| 715 | 711 | int fsize = ro->count * sizeof(struct can_filter); |
|---|
| 712 | + |
|---|
| 716 | 713 | if (len > fsize) |
|---|
| 717 | 714 | len = fsize; |
|---|
| 718 | 715 | if (copy_to_user(optval, ro->filter, len)) |
|---|
| 719 | 716 | err = -EFAULT; |
|---|
| 720 | | - } else |
|---|
| 717 | + } else { |
|---|
| 721 | 718 | len = 0; |
|---|
| 719 | + } |
|---|
| 722 | 720 | release_sock(sk); |
|---|
| 723 | 721 | |
|---|
| 724 | 722 | if (!err) |
|---|
| .. | .. |
|---|
| 778 | 776 | if (msg->msg_name) { |
|---|
| 779 | 777 | DECLARE_SOCKADDR(struct sockaddr_can *, addr, msg->msg_name); |
|---|
| 780 | 778 | |
|---|
| 781 | | - if (msg->msg_namelen < sizeof(*addr)) |
|---|
| 779 | + if (msg->msg_namelen < RAW_MIN_NAMELEN) |
|---|
| 782 | 780 | return -EINVAL; |
|---|
| 783 | 781 | |
|---|
| 784 | 782 | if (addr->can_family != AF_CAN) |
|---|
| 785 | 783 | return -EINVAL; |
|---|
| 786 | 784 | |
|---|
| 787 | 785 | ifindex = addr->can_ifindex; |
|---|
| 788 | | - } else |
|---|
| 786 | + } else { |
|---|
| 789 | 787 | ifindex = ro->ifindex; |
|---|
| 788 | + } |
|---|
| 790 | 789 | |
|---|
| 791 | 790 | dev = dev_get_by_index(sock_net(sk), ifindex); |
|---|
| 792 | 791 | if (!dev) |
|---|
| .. | .. |
|---|
| 814 | 813 | if (err < 0) |
|---|
| 815 | 814 | goto free_skb; |
|---|
| 816 | 815 | |
|---|
| 817 | | - sock_tx_timestamp(sk, sk->sk_tsflags, &skb_shinfo(skb)->tx_flags); |
|---|
| 816 | + skb_setup_tx_timestamp(skb, sk->sk_tsflags); |
|---|
| 818 | 817 | |
|---|
| 819 | 818 | skb->dev = dev; |
|---|
| 820 | | - skb->sk = sk; |
|---|
| 819 | + skb->sk = sk; |
|---|
| 821 | 820 | skb->priority = sk->sk_priority; |
|---|
| 822 | 821 | |
|---|
| 823 | 822 | err = can_send(skb, ro->loopback); |
|---|
| .. | .. |
|---|
| 845 | 844 | int err = 0; |
|---|
| 846 | 845 | int noblock; |
|---|
| 847 | 846 | |
|---|
| 848 | | - noblock = flags & MSG_DONTWAIT; |
|---|
| 849 | | - flags &= ~MSG_DONTWAIT; |
|---|
| 847 | + noblock = flags & MSG_DONTWAIT; |
|---|
| 848 | + flags &= ~MSG_DONTWAIT; |
|---|
| 849 | + |
|---|
| 850 | + if (flags & MSG_ERRQUEUE) |
|---|
| 851 | + return sock_recv_errqueue(sk, msg, size, |
|---|
| 852 | + SOL_CAN_RAW, SCM_CAN_RAW_ERRQUEUE); |
|---|
| 850 | 853 | |
|---|
| 851 | 854 | skb = skb_recv_datagram(sk, flags, noblock, &err); |
|---|
| 852 | 855 | if (!skb) |
|---|
| .. | .. |
|---|
| 866 | 869 | sock_recv_ts_and_drops(msg, sk, skb); |
|---|
| 867 | 870 | |
|---|
| 868 | 871 | if (msg->msg_name) { |
|---|
| 869 | | - __sockaddr_check_size(sizeof(struct sockaddr_can)); |
|---|
| 870 | | - msg->msg_namelen = sizeof(struct sockaddr_can); |
|---|
| 872 | + __sockaddr_check_size(RAW_MIN_NAMELEN); |
|---|
| 873 | + msg->msg_namelen = RAW_MIN_NAMELEN; |
|---|
| 871 | 874 | memcpy(msg->msg_name, skb->cb, msg->msg_namelen); |
|---|
| 872 | 875 | } |
|---|
| 873 | 876 | |
|---|
| .. | .. |
|---|
| 879 | 882 | return size; |
|---|
| 880 | 883 | } |
|---|
| 881 | 884 | |
|---|
| 885 | +static int raw_sock_no_ioctlcmd(struct socket *sock, unsigned int cmd, |
|---|
| 886 | + unsigned long arg) |
|---|
| 887 | +{ |
|---|
| 888 | + /* no ioctls for socket layer -> hand it down to NIC layer */ |
|---|
| 889 | + return -ENOIOCTLCMD; |
|---|
| 890 | +} |
|---|
| 891 | + |
|---|
| 882 | 892 | static const struct proto_ops raw_ops = { |
|---|
| 883 | 893 | .family = PF_CAN, |
|---|
| 884 | 894 | .release = raw_release, |
|---|
| .. | .. |
|---|
| 888 | 898 | .accept = sock_no_accept, |
|---|
| 889 | 899 | .getname = raw_getname, |
|---|
| 890 | 900 | .poll = datagram_poll, |
|---|
| 891 | | - .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */ |
|---|
| 901 | + .ioctl = raw_sock_no_ioctlcmd, |
|---|
| 902 | + .gettstamp = sock_gettstamp, |
|---|
| 892 | 903 | .listen = sock_no_listen, |
|---|
| 893 | 904 | .shutdown = sock_no_shutdown, |
|---|
| 894 | 905 | .setsockopt = raw_setsockopt, |
|---|
| .. | .. |
|---|
| 921 | 932 | { |
|---|
| 922 | 933 | int err; |
|---|
| 923 | 934 | |
|---|
| 924 | | - pr_info("can: raw protocol (rev " CAN_RAW_VERSION ")\n"); |
|---|
| 935 | + pr_info("can: raw protocol\n"); |
|---|
| 925 | 936 | |
|---|
| 926 | 937 | err = can_proto_register(&raw_can_proto); |
|---|
| 927 | 938 | if (err < 0) |
|---|
| 928 | | - printk(KERN_ERR "can: registration of raw protocol failed\n"); |
|---|
| 939 | + pr_err("can: registration of raw protocol failed\n"); |
|---|
| 929 | 940 | else |
|---|
| 930 | 941 | register_netdevice_notifier(&canraw_notifier); |
|---|
| 931 | 942 | |
|---|