• Xin Long's avatar
    macsec: drop skb sk before calling gro_cells_receive · ba56d8ce
    Xin Long authored
    Fei Liu reported a crash when doing netperf on a topo of macsec
    dev over veth:
      [  448.919128] refcount_t: underflow; use-after-free.
      [  449.090460] Call trace:
      [  449.092895]  refcount_sub_and_test+0xb4/0xc0
      [  449.097155]  tcp_wfree+0x2c/0x150
      [  449.100460]  ip_rcv+0x1d4/0x3a8
      [  449.103591]  __netif_receive_skb_core+0x554/0xae0
      [  449.108282]  __netif_receive_skb+0x28/0x78
      [  449.112366]  netif_receive_skb_internal+0x54/0x100
      [  449.117144]  napi_gro_complete+0x70/0xc0
      [  449.121054]  napi_gro_flush+0x6c/0x90
      [  449.124703]  napi_complete_done+0x50/0x130
      [  449.128788]  gro_cell_poll+0x8c/0xa8
      [  449.132351]  net_rx_action+0x16c/0x3f8
      [  449.136088]  __do_softirq+0x128/0x320
    The issue was caused by skb's true_size changed without its sk's
    sk_wmem_alloc increased in tcp/skb_gro_receive(). Later when the
    skb is being freed and the skb's truesize is subtracted from its
    sk's sk_wmem_alloc in tcp_wfree(), underflow occurs.
    macsec is calling gro_cells_receive() to receive a packet, which
    actually requires skb->sk to be NULL. However when macsec dev is
    over veth, it's possible the skb->sk is still set if the skb was
    not unshared or expanded from the peer veth.
    ip_rcv() is calling skb_orphan() to drop the skb's sk for tproxy,
    but it is too late for macsec's calling gro_cells_receive(). So
    fix it by dropping the skb's sk earlier on rx path of macsec.
    Fixes: 5491e7c6
     ("macsec: enable GRO and RPS on macsec devices")
    Reported-by: default avatarXiumei Mu <xmu@redhat.com>
    Reported-by: default avatarFei Liu <feliu@redhat.com>
    Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>