Skip to content
  • Clément Bœsch's avatar
    Fix: cleanup format residual after close · 6598fd21
    Clément Bœsch authored and Philipp Schafft's avatar Philipp Schafft committed
    This fixes the situation where shout_open(), shout_close(), and
    shout_open() again are called on the same shout_t context. If this
    happens, the shout_t.send callback will remain set after close,
    preventing the stream from being re-opened in try_connect().  As a
    result, the next write will cause a use after free on
    shout_t.format_data (free happened on the shout_close() call).
    
    Technically, only reseting shout_t.send is enough to fix the crash, but
    making sure format_data is always reset as well makes similar issues
    much more deterministic and understandable when crashing. The close
    callback is also reset for consistency and integrity.
    
    This issue was observed with the libshout output of MPD.
    
    For the record, here are the steps to reproduce the crash:
    
    In a mpd.conf:
    
        audio_output {
            type        "shout"
            name        "My Shout Stream"
            host        "localhost"
            port        "8000"
            mount       "/mpd.ogg"
            password    "hackme"
            bitrate     "128"
            format      "44100:16:1"
        }
    
    Then assuming icecast is running with the default configuration:
    
        mpc add /             # add all files to the playlist
        mpc play              # start writing to the shout stream
        mpc toggleoutput 1    # disable shout output (calls shout_close)
        mpc toggleoutput 1    # enable shout output (calls shout_open on the same shout_t)
        mpc play              # write again to the shout stream
    
    Closes #2312, #2318
    6598fd21