• J
    net: Fix data corruption when splicing from sockets. · 8b9d3728
    Jarek Poplawski 提交于
    The trick in socket splicing where we try to convert the skb->data
    into a page based reference using virt_to_page() does not work so
    well.
    
    The idea is to pass the virt_to_page() reference via the pipe
    buffer, and refcount the buffer using a SKB reference.
    
    But if we are splicing from a socket to a socket (via sendpage)
    this doesn't work.
    
    The from side processing will grab the page (and SKB) references.
    The sendpage() calls will grab page references only, return, and
    then the from side processing completes and drops the SKB ref.
    
    The page based reference to skb->data is not enough to keep the
    kmalloc() buffer backing it from being reused.  Yet, that is
    all that the socket send side has at this point.
    
    This leads to data corruption if the skb->data buffer is reused
    by SLAB before the send side socket actually gets the TX packet
    out to the device.
    
    The fix employed here is to simply allocate a page and copy the
    skb->data bytes into that page.
    
    This will hurt performance, but there is no clear way to fix this
    properly without a copy at the present time, and it is important
    to get rid of the data corruption.
    
    With fixes from Herbert Xu.
    Tested-by: NWilly Tarreau <w@1wt.eu>
    Foreseen-by: NChangli Gao <xiaosuo@gmail.com>
    Diagnosed-by: NWilly Tarreau <w@1wt.eu>
    Reported-by: NWilly Tarreau <w@1wt.eu>
    Fixed-by: NJens Axboe <jens.axboe@oracle.com>
    Signed-off-by: NJarek Poplawski <jarkao2@gmail.com>
    Signed-off-by: NDavid S. Miller <davem@davemloft.net>
    8b9d3728
skbuff.c 71.9 KB