• Daniel Borkmann's avatar
    netlink, mmap: transform mmap skb into full skb on taps · 1853c949
    Daniel Borkmann authored
    Ken-ichirou reported that running netlink in mmap mode for receive in
    combination with nlmon will throw a NULL pointer dereference in
    __kfree_skb() on nlmon_xmit(), in my case I can also trigger an "unable
    to handle kernel paging request". The problem is the skb_clone() in
    __netlink_deliver_tap_skb() for skbs that are mmaped.
    
    I.e. the cloned skb doesn't have a destructor, whereas the mmap netlink
    skb has it pointed to netlink_skb_destructor(), set in the handler
    netlink_ring_setup_skb(). There, skb->head is being set to NULL, so
    that in such cases, __kfree_skb() doesn't perform a skb_release_data()
    via skb_release_all(), where skb->head is possibly being freed through
    kfree(head) into slab allocator, although netlink mmap skb->head points
    to the mmap buffer. Similarly, the same has to be done also for large
    netlink skbs where the data area is vmalloced. Therefore, as discussed,
    make a copy for these rather rare cases for now. This fixes the issue
    on my and Ken-ichirou's test-cases.
    
    Reference: http://thread.gmane.org/gmane.linux.network/371129
    Fixes: bcbde0d4 ("net: netlink: virtual tap device management")
    Reported-by: default avatarKen-ichirou MATSUZAWA <chamaken@gmail.com>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Tested-by: default avatarKen-ichirou MATSUZAWA <chamaken@gmail.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    1853c949
af_netlink.c 77 KB