diff options
Diffstat (limited to 'net/can/raw.c')
-rw-r--r-- | net/can/raw.c | 31 |
1 files changed, 8 insertions, 23 deletions
diff --git a/net/can/raw.c b/net/can/raw.c index 641e1c895123..081e81fd017f 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
@@ -121,13 +121,9 @@ static void raw_rcv(struct sk_buff *oskb, void *data) | |||
121 | if (!ro->recv_own_msgs && oskb->sk == sk) | 121 | if (!ro->recv_own_msgs && oskb->sk == sk) |
122 | return; | 122 | return; |
123 | 123 | ||
124 | /* do not pass frames with DLC > 8 to a legacy socket */ | 124 | /* do not pass non-CAN2.0 frames to a legacy socket */ |
125 | if (!ro->fd_frames) { | 125 | if (!ro->fd_frames && oskb->len != CAN_MTU) |
126 | struct canfd_frame *cfd = (struct canfd_frame *)oskb->data; | 126 | return; |
127 | |||
128 | if (unlikely(cfd->len > CAN_MAX_DLEN)) | ||
129 | return; | ||
130 | } | ||
131 | 127 | ||
132 | /* clone the given skb to be able to enqueue it into the rcv queue */ | 128 | /* clone the given skb to be able to enqueue it into the rcv queue */ |
133 | skb = skb_clone(oskb, GFP_ATOMIC); | 129 | skb = skb_clone(oskb, GFP_ATOMIC); |
@@ -675,8 +671,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
675 | int err; | 671 | int err; |
676 | 672 | ||
677 | if (msg->msg_name) { | 673 | if (msg->msg_name) { |
678 | struct sockaddr_can *addr = | 674 | DECLARE_SOCKADDR(struct sockaddr_can *, addr, msg->msg_name); |
679 | (struct sockaddr_can *)msg->msg_name; | ||
680 | 675 | ||
681 | if (msg->msg_namelen < sizeof(*addr)) | 676 | if (msg->msg_namelen < sizeof(*addr)) |
682 | return -EINVAL; | 677 | return -EINVAL; |
@@ -716,6 +711,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
716 | 711 | ||
717 | skb->dev = dev; | 712 | skb->dev = dev; |
718 | skb->sk = sk; | 713 | skb->sk = sk; |
714 | skb->priority = sk->sk_priority; | ||
719 | 715 | ||
720 | err = can_send(skb, ro->loopback); | 716 | err = can_send(skb, ro->loopback); |
721 | 717 | ||
@@ -738,9 +734,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
738 | struct msghdr *msg, size_t size, int flags) | 734 | struct msghdr *msg, size_t size, int flags) |
739 | { | 735 | { |
740 | struct sock *sk = sock->sk; | 736 | struct sock *sk = sock->sk; |
741 | struct raw_sock *ro = raw_sk(sk); | ||
742 | struct sk_buff *skb; | 737 | struct sk_buff *skb; |
743 | int rxmtu; | ||
744 | int err = 0; | 738 | int err = 0; |
745 | int noblock; | 739 | int noblock; |
746 | 740 | ||
@@ -751,20 +745,10 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
751 | if (!skb) | 745 | if (!skb) |
752 | return err; | 746 | return err; |
753 | 747 | ||
754 | /* | 748 | if (size < skb->len) |
755 | * when serving a legacy socket the DLC <= 8 is already checked inside | ||
756 | * raw_rcv(). Now check if we need to pass a canfd_frame to a legacy | ||
757 | * socket and cut the possible CANFD_MTU/CAN_MTU length to CAN_MTU | ||
758 | */ | ||
759 | if (!ro->fd_frames) | ||
760 | rxmtu = CAN_MTU; | ||
761 | else | ||
762 | rxmtu = skb->len; | ||
763 | |||
764 | if (size < rxmtu) | ||
765 | msg->msg_flags |= MSG_TRUNC; | 749 | msg->msg_flags |= MSG_TRUNC; |
766 | else | 750 | else |
767 | size = rxmtu; | 751 | size = skb->len; |
768 | 752 | ||
769 | err = memcpy_toiovec(msg->msg_iov, skb->data, size); | 753 | err = memcpy_toiovec(msg->msg_iov, skb->data, size); |
770 | if (err < 0) { | 754 | if (err < 0) { |
@@ -775,6 +759,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
775 | sock_recv_ts_and_drops(msg, sk, skb); | 759 | sock_recv_ts_and_drops(msg, sk, skb); |
776 | 760 | ||
777 | if (msg->msg_name) { | 761 | if (msg->msg_name) { |
762 | __sockaddr_check_size(sizeof(struct sockaddr_can)); | ||
778 | msg->msg_namelen = sizeof(struct sockaddr_can); | 763 | msg->msg_namelen = sizeof(struct sockaddr_can); |
779 | memcpy(msg->msg_name, skb->cb, msg->msg_namelen); | 764 | memcpy(msg->msg_name, skb->cb, msg->msg_namelen); |
780 | } | 765 | } |