@@ -927,14 +927,15 @@ static int llc_ui_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
927927 */
928928static int llc_ui_sendmsg (struct socket * sock , struct msghdr * msg , size_t len )
929929{
930+ DECLARE_SOCKADDR (struct sockaddr_llc * , addr , msg -> msg_name );
930931 struct sock * sk = sock -> sk ;
931932 struct llc_sock * llc = llc_sk (sk );
932- DECLARE_SOCKADDR (struct sockaddr_llc * , addr , msg -> msg_name );
933933 int flags = msg -> msg_flags ;
934934 int noblock = flags & MSG_DONTWAIT ;
935+ int rc = - EINVAL , copied = 0 , hdrlen , hh_len ;
935936 struct sk_buff * skb = NULL ;
937+ struct net_device * dev ;
936938 size_t size = 0 ;
937- int rc = - EINVAL , copied = 0 , hdrlen ;
938939
939940 dprintk ("%s: sending from %02X to %02X\n" , __func__ ,
940941 llc -> laddr .lsap , llc -> daddr .lsap );
@@ -954,22 +955,29 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
954955 if (rc )
955956 goto out ;
956957 }
957- hdrlen = llc -> dev -> hard_header_len + llc_ui_header_len (sk , addr );
958+ dev = llc -> dev ;
959+ hh_len = LL_RESERVED_SPACE (dev );
960+ hdrlen = llc_ui_header_len (sk , addr );
958961 size = hdrlen + len ;
959- if (size > llc -> dev -> mtu )
960- size = llc -> dev -> mtu ;
962+ size = min_t (size_t , size , READ_ONCE (dev -> mtu ));
961963 copied = size - hdrlen ;
962964 rc = - EINVAL ;
963965 if (copied < 0 )
964966 goto out ;
965967 release_sock (sk );
966- skb = sock_alloc_send_skb (sk , size , noblock , & rc );
968+ skb = sock_alloc_send_skb (sk , hh_len + size , noblock , & rc );
967969 lock_sock (sk );
968970 if (!skb )
969971 goto out ;
970- skb -> dev = llc -> dev ;
972+ if (sock_flag (sk , SOCK_ZAPPED ) ||
973+ llc -> dev != dev ||
974+ hdrlen != llc_ui_header_len (sk , addr ) ||
975+ hh_len != LL_RESERVED_SPACE (dev ) ||
976+ size > READ_ONCE (dev -> mtu ))
977+ goto out ;
978+ skb -> dev = dev ;
971979 skb -> protocol = llc_proto_type (addr -> sllc_arphrd );
972- skb_reserve (skb , hdrlen );
980+ skb_reserve (skb , hh_len + hdrlen );
973981 rc = memcpy_from_msg (skb_put (skb , copied ), msg , copied );
974982 if (rc )
975983 goto out ;
0 commit comments