• Peter Eisentraut's avatar
    Distrust external OpenSSL clients; clear err queue · 7c7d4fdd
    Peter Eisentraut authored
    OpenSSL has an unfortunate tendency to mix per-session state error
    handling with per-thread error handling.  This can cause problems when
    programs that link to libpq with OpenSSL enabled have some other use of
    OpenSSL; without care, one caller of OpenSSL may cause problems for the
    other caller.  Backend code might similarly be affected, for example
    when a third party extension independently uses OpenSSL without taking
    the appropriate precautions.
    
    To fix, don't trust other users of OpenSSL to clear the per-thread error
    queue.  Instead, clear the entire per-thread queue ahead of certain I/O
    operations when it appears that there might be trouble (these I/O
    operations mostly need to call SSL_get_error() to check for success,
    which relies on the queue being empty).  This is slightly aggressive,
    but it's pretty clear that the other callers have a very dubious claim
    to ownership of the per-thread queue.  Do this is both frontend and
    backend code.
    
    Finally, be more careful about clearing our own error queue, so as to
    not cause these problems ourself.  It's possibly that control previously
    did not always reach SSLerrmessage(), where ERR_get_error() was supposed
    to be called to clear the queue's earliest code.  Make sure
    ERR_get_error() is always called, so as to spare other users of OpenSSL
    the possibility of similar problems caused by libpq (as opposed to
    problems caused by a third party OpenSSL library like PHP's OpenSSL
    extension).  Again, do this is both frontend and backend code.
    
    See bug #12799 and https://bugs.php.net/bug.php?id=68276
    
    Based on patches by Dave Vitek and Peter Eisentraut.
    
    From: Peter Geoghegan <pg@bowt.ie>
    7c7d4fdd
be-secure-openssl.c 29 KB