Continue: Bug #924: Segmentation fault in libpq/PQconsumeInput on SSL connection
| От | Sergey N. Yatskevich |
|---|---|
| Тема | Continue: Bug #924: Segmentation fault in libpq/PQconsumeInput on SSL connection |
| Дата | |
| Msg-id | 3E8A1B5C.1090207@n21lab.gosniias.msk.ru обсуждение исходный текст |
| Ответы |
Re: Continue: Bug #924: Segmentation fault in libpq/PQconsumeInput
|
| Список | 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 по дате отправления: