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

From Bruce Momjian
Subject Re: Continue: Bug #924: Segmentation fault in libpq/PQconsumeInput
Date
Msg-id 200305270459.h4R4xmG22355@candle.pha.pa.us
Whole thread Raw
In response to Continue: Bug #924: Segmentation fault in libpq/PQconsumeInput on SSL connection  ("Sergey N. Yatskevich" <syatskevich@n21lab.gosniias.msk.ru>)
List pgsql-bugs
This is fixed in the upcoming 7.3.3 release.

---------------------------------------------------------------------------

Sergey N. Yatskevich wrote:
> 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;
> }

>
> ---------------------------(end of broadcast)---------------------------
> TIP 6: Have you searched our list archives?
>
> http://archives.postgresql.org

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073

pgsql-bugs by date:

Previous
From: Dave E Martin XXIII
Date:
Subject: index not used for bigint without explicit cast
Next
From: Ruslan A Dautkhanov
Date:
Subject: ERROR: Memory exhausted in AllocSetAlloc(68)