@@ -928,14 +928,15 @@ static int llc_ui_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
928
928
*/
929
929
static int llc_ui_sendmsg (struct socket * sock , struct msghdr * msg , size_t len )
930
930
{
931
+ DECLARE_SOCKADDR (struct sockaddr_llc * , addr , msg -> msg_name );
931
932
struct sock * sk = sock -> sk ;
932
933
struct llc_sock * llc = llc_sk (sk );
933
- DECLARE_SOCKADDR (struct sockaddr_llc * , addr , msg -> msg_name );
934
934
int flags = msg -> msg_flags ;
935
935
int noblock = flags & MSG_DONTWAIT ;
936
+ int rc = - EINVAL , copied = 0 , hdrlen , hh_len ;
936
937
struct sk_buff * skb = NULL ;
938
+ struct net_device * dev ;
937
939
size_t size = 0 ;
938
- int rc = - EINVAL , copied = 0 , hdrlen ;
939
940
940
941
dprintk ("%s: sending from %02X to %02X\n" , __func__ ,
941
942
llc -> laddr .lsap , llc -> daddr .lsap );
@@ -955,22 +956,29 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
955
956
if (rc )
956
957
goto out ;
957
958
}
958
- hdrlen = llc -> dev -> hard_header_len + llc_ui_header_len (sk , addr );
959
+ dev = llc -> dev ;
960
+ hh_len = LL_RESERVED_SPACE (dev );
961
+ hdrlen = llc_ui_header_len (sk , addr );
959
962
size = hdrlen + len ;
960
- if (size > llc -> dev -> mtu )
961
- size = llc -> dev -> mtu ;
963
+ size = min_t (size_t , size , READ_ONCE (dev -> mtu ));
962
964
copied = size - hdrlen ;
963
965
rc = - EINVAL ;
964
966
if (copied < 0 )
965
967
goto out ;
966
968
release_sock (sk );
967
- skb = sock_alloc_send_skb (sk , size , noblock , & rc );
969
+ skb = sock_alloc_send_skb (sk , hh_len + size , noblock , & rc );
968
970
lock_sock (sk );
969
971
if (!skb )
970
972
goto out ;
971
- skb -> dev = llc -> dev ;
973
+ if (sock_flag (sk , SOCK_ZAPPED ) ||
974
+ llc -> dev != dev ||
975
+ hdrlen != llc_ui_header_len (sk , addr ) ||
976
+ hh_len != LL_RESERVED_SPACE (dev ) ||
977
+ size > READ_ONCE (dev -> mtu ))
978
+ goto out ;
979
+ skb -> dev = dev ;
972
980
skb -> protocol = llc_proto_type (addr -> sllc_arphrd );
973
- skb_reserve (skb , hdrlen );
981
+ skb_reserve (skb , hh_len + hdrlen );
974
982
rc = memcpy_from_msg (skb_put (skb , copied ), msg , copied );
975
983
if (rc )
976
984
goto out ;
0 commit comments