• Guillaume Nault's avatar
    ppp: avoid loop in xmit recursion detection code · 6d066734
    Guillaume Nault authored
    We already detect situations where a PPP channel sends packets back to
    its upper PPP device. While this is enough to avoid deadlocking on xmit
    locks, this doesn't prevent packets from looping between the channel
    and the unit.
    
    The problem is that ppp_start_xmit() enqueues packets in ppp->file.xq
    before checking for xmit recursion. Therefore, __ppp_xmit_process()
    might dequeue a packet from ppp->file.xq and send it on the channel
    which, in turn, loops it back on the unit. Then ppp_start_xmit()
    queues the packet back to ppp->file.xq and __ppp_xmit_process() picks
    it up and sends it again through the channel. Therefore, the packet
    will loop between __ppp_xmit_process() and ppp_start_xmit() until some
    other part of the xmit path drops it.
    
    For L2TP, we rapidly fill the skb's headroom and pppol2tp_xmit() drops
    the packet after a few iterations. But PPTP reallocates the headroom
    if necessary, letting the loop run and exhaust the machine resources
    (as reported in https://bugzilla.kernel.org/show_bug.cgi?id=199109).
    
    Fix this by letting __ppp_xmit_process() enqueue the skb to
    ppp->file.xq, so that we can check for recursion before adding it to
    the queue. Now ppp_xmit_process() can drop the packet when recursion is
    detected.
    
    __ppp_channel_push() is a bit special. It calls __ppp_xmit_process()
    without having any actual packet to send. This is used by
    ppp_output_wakeup() to re-enable transmission on the parent unit (for
    implementations like ppp_async.c, where the .start_xmit() function
    might not consume the skb, leaving it in ppp->xmit_pending and
    disabling transmission).
    Therefore, __ppp_xmit_process() needs to handle the case where skb is
    NULL, dequeuing as many packets as possible from ppp->file.xq.
    Reported-by: default avatarxu heng <xuheng333@zoho.com>
    Fixes: 55454a56 ("ppp: avoid dealock on recursive xmit")
    Signed-off-by: default avatarGuillaume Nault <g.nault@alphalink.fr>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    6d066734
ppp_generic.c 76.7 KB