• N
    AF_RAW: Augment raw_send_hdrinc to expand skb to fit iphdr->ihl (v2) · 55888dfb
    Neil Horman 提交于
    Augment raw_send_hdrinc to correct for incorrect ip header length values
    
    A series of oopses was reported to me recently.  Apparently when using AF_RAW
    sockets to send data to peers that were reachable via ipsec encapsulation,
    people could panic or BUG halt their systems.
    
    I've tracked the problem down to user space sending an invalid ip header over an
    AF_RAW socket with IP_HDRINCL set to 1.
    
    Basically what happens is that userspace sends down an ip frame that includes
    only the header (no data), but sets the ip header ihl value to a large number,
    one that is larger than the total amount of data passed to the sendmsg call.  In
    raw_send_hdrincl, we allocate an skb based on the size of the data in the msghdr
    that was passed in, but assume the data is all valid.  Later during ipsec
    encapsulation, xfrm4_tranport_output moves the entire frame back in the skbuff
    to provide headroom for the ipsec headers.  During this operation, the
    skb->transport_header is repointed to a spot computed by
    skb->network_header + the ip header length (ihl).  Since so little data was
    passed in relative to the value of ihl provided by the raw socket, we point
    transport header to an unknown location, resulting in various crashes.
    
    This fix for this is pretty straightforward, simply validate the value of of
    iph->ihl when sending over a raw socket.  If (iph->ihl*4U) > user data buffer
    size, drop the frame and return -EINVAL.  I just confirmed this fixes the
    reported crashes.
    Signed-off-by: NNeil Horman <nhorman@tuxdriver.com>
    Acked-by: NEric Dumazet <eric.dumazet@gmail.com>
    Signed-off-by: NDavid S. Miller <davem@davemloft.net>
    55888dfb
raw.c 23.7 KB