Re: Please help solve various memory corruption failures

From: "Tsunakawa, Takayuki" <tsunakawa(dot)takay(at)jp(dot)fujitsu(dot)com>
To: "pgsql-odbc(at)postgresql(dot)org" <pgsql-odbc(at)postgresql(dot)org>
Subject: Re: Please help solve various memory corruption failures
Date: 2016-01-28 05:39:38
Message-ID: 0A3221C70F24FB45833433255569204D1F4DB1CF@G01JPEXMBYT05
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-odbc

> I've been encountering various failures leading to application crash. They
> all seem to be caused by some memory corruption bugs. I tried to figure
> out the fix, but I couldn't. I would really appreciate your help!
>
> I'm using the latest release psqlodbc-09.03.0400 on Windows. The
> application is multi-threaded 32-bit program. The threads are independent
> workers, each of which uses ADO to perform simple data access:

I've just been able to solve this issue. There were some bugs in psqlODBC and a communication library we are using. Let me explain those.

> (6) Abrupt socket close
> Throughout the test, these messages are frequently output in the PostgreSQL
> server log file:
>
> LOG: could not receive data from client: No connection could be made
> because the target machine actively refused it.
> LOG: unexpected EOF on client connection

The communication library (not psqlODBC) mistakenly closed the same socket twice. Depending on the timing, that ended up closing a live socket which is being used for psqlODBC-postgres communication. This is the beginning of all mysterious crashes.

The sudden socket closure causes send()/recv() in psqlODBC to fail, leading to QR_next_tuple() and CC_fetch_tuples() failures. When CC_fetch_tuples() fails in CC_send_query_append(), the following code fragment sets cmdres to retres. Here, cmdres is just initialized and so has no error information.

[connection.c]
if (!CC_fetch_tuples(res, self, cursor, &ReadyToReturn, &kill_conn))
{
if (QR_command_maybe_successful(res))
retres = NULL;
else
retres = cmdres;
aborted = TRUE;
}

Returning from CC_send_query_append(), SC_execute() treats the result as success. But the returned QResult has no information about DECLARE+FETCH results. Finally, SC_execute() accesses the memory just freed by itself.

This problem does not occur with psqlodbc-09.05.0100. I confirmed it by reviewing the source code and actually running the same test.

> (5) NULL dereference
> The following line in SC_create_errorinfo() (statement.c) caused the crash.
> pgerror was NULL. That means that malloc() in ER_Constructor() failed.
> NULL check is necessary somewhere.
>
> strcpy(pgerror->sqlstate, EN_is_odbc3(env) ?
>
> Statement_sqlstate[errornum].ver3str :
>
> Statement_sqlstate[errornum].ver2str);

This bug still exists in the latest psqlodbc-09.05.0100. I'll submit the patch later.

Regards, Takayuki Tsunakawa

Browse pgsql-odbc by date

  From Date Subject
Next Message Tsunakawa, Takayuki 2016-01-28 06:27:14 psqlODBC crashes upon memory allocation failures
Previous Message John Kew 2016-01-25 21:26:41 Re: Re: 9.0.5 issue - duplicate rows returned when using SQL_ATTR_ROW_ARRAY_SIZE attribute