aboutsummaryrefslogtreecommitdiffstats
path: root/net/can/raw.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/can/raw.c')
-rw-r--r--net/can/raw.c31
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 }