Continue: Bug #924: Segmentation fault in libpq/PQconsumeInput on SSL connection - Mailing list pgsql-bugs

From Sergey N. Yatskevich
Subject Continue: Bug #924: Segmentation fault in libpq/PQconsumeInput on SSL connection
Date
Msg-id 3E8A1B5C.1090207@n21lab.gosniias.msk.ru
Whole thread Raw
Responses Re: Continue: Bug #924: Segmentation fault in libpq/PQconsumeInput
List pgsql-bugs
I try to explain this bug. Attached files contains example and patch
for libpq.

I hope, that you look at it and replay me what you think.

---
Segey N. Yatskevich <syatskevich@n21lab.gosniias.msk.ru>
#
# $Id$
#

ssl-async-query: ssl-async-query.cc
    c++ -g -I`pg_config --includedir` /usr/lib/libpq.so.3 -o ssl-async-query ssl-async-query.cc

clean:
    rm -f ssl-async-query
--- fe-secure.c.orig    2003-01-09 02:18:35 +0300
+++ fe-secure.c    2003-04-02 02:06:27 +0400
@@ -268,7 +268,10 @@
             case SSL_ERROR_NONE:
                 break;
             case SSL_ERROR_WANT_READ:
-                    n = pqsecure_read(conn, ptr, len);
+                // I think this mean, that SSL layer have
+                // no any data for us and we must try
+                // to read it later.
+                n = 0;
                 break;
             case SSL_ERROR_SYSCALL:
                 printfPQExpBuffer(&conn->errorMessage,
@@ -314,7 +317,10 @@
             case SSL_ERROR_NONE:
                 break;
             case SSL_ERROR_WANT_WRITE:
-                    n = pqsecure_write(conn, ptr, len);
+                // I think this mean, that SSL layer have
+                // no free space for buffering our data and
+                // we must try to write it later.
+                n = 0;
                 break;
             case SSL_ERROR_SYSCALL:
                 printfPQExpBuffer(&conn->errorMessage,
/*
 * SSL-test
 */
#include <iostream>
#include <libpq-fe.h>

static void
exit_nicely (PGconn *conn) {
    std::cerr << "ERROR: " << PQerrorMessage (conn) << '\n';

    PQfinish (conn);
    exit (1);
}

int
main (int _argc, char *_argv[]) {
    PGconn    *conn = PQconnectdb ("user=postgres dbname=template1 host=127.0.0.1 requiressl=1");
    if (PQstatus (conn) == CONNECTION_BAD)
        exit_nicely (conn);

    PQsendQuery (conn, "select * from pg_class; select * from pg_type; select * from pg_proc");

    for (;;) {
        std::cout << "before DANGEROUS section of code\n";

#ifndef NO_STACK_OVERFLOW_DEMO
        // This is a DANGEROUS code. If we call PQconsumeInput here,
        // after getting last PGresult, we will go into infinite
        // recursive call of pqsecure_read on SSL_ERROR_WANT_READ.
        PQconsumeInput (conn);
        if (PQisBusy (conn))
            continue;
        // Call PQcounsumeInput on SSL connection when server
        // don't send any data to us is DANGEROUS.
#else
        // This code is safe, becouse end of data determine before
        // call of PQconsumeInput and we don't go into pqsecure_read
        // when server have no data.
        if (PQisBusy (conn)) {
            PQconsumeInput (conn);
            continue;
        }
#endif
        // But I think PQconsumeInput must be safe to be called in
        // any time, becouse, for example, we can use it not only
        // for async query processing, but for getting asynhronous
        // notification from server in case when we don't send any
        // query to it and can't be sure, that server have data for
        // us.
        std::cout << "after DANGEROUS section of code\n";

        // When we don't use SSL this code in both case is completly
        // safe, becouse recv simple return 0 if no data avaliable.
        // I think this is good for SSL connection too.

        PGresult *res = PQgetResult (conn);
        if (res) {
            if (PQresultStatus (res) == PGRES_TUPLES_OK)
                std::cout << "SELECT\n";
            else
                std::cerr << "UNKNOWN\n";

            PQclear (res);
            continue;
        }

        break;
    }

    PQfinish(conn);
    return 0;
}

pgsql-bugs by date:

Previous
From:
Date:
Subject: geometry test fails on FreeBSD 4.7
Next
From: pgsql-bugs@postgresql.org
Date:
Subject: Bug #930: UNIQUE CONSTRAINT