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: