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