Bug #5173 MyODBC: extend_buffer function returns wrong value when to == NULL
Submitted: 23 Aug 2004 22:42 Modified: 13 Jun 2013 13:31
Reporter: Mark Smith Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / ODBC Severity:S2 (Serious)
Version:3.51.07 OS:Any (x86 Linux (Fedora Core 2))
Assigned to: Bogdan Degtyariov CPU Architecture:Any

[23 Aug 2004 22:42] Mark Smith
Description:
The extend_buffer() function in driver/execute.c returns the wrong value when the to parameter is passed in as NULL.  In fact, it returns a pointer to memory which is outside net->buff.  The problem is that the local variable nead is initialized to zero but never set to the number of bytes required in the to == NULL case.

This can lead to problems when, for example, the client has lost its connection to the MySQL server (apparently someone resets the statement buffer to NULL when that happens).  This leads to crashes when using bound parameters.

How to repeat:
Create a test program that does something like this:
  1. Open a connection to a server using SQLDriverConnect(), etc.
  2. Use SQLBindParameter() to bind one simple string parameter.
  3. Do a simple SELECT by calling SQLExecDirect().
  4. Reset the statement handle by calling SQLCloseCursor(hstmt) and SQLFreeStmt(hstmt, SQL_RESET_PARAMS).
  5. Pause (e.g., do a gets() to wait for a Return).
  6. Repeat steps 2-4 two more times.

Then stop the MySQL Server during the Pause.  You will likely see a SIGSEGV.  If run under Valgrind you will see a series of "Invalid write" errors, e.g.,

==13185==
==13185== Invalid write of size 1
==13185==    at 0x1B9046DA: memcpy (mac_replace_strmem.c:283)
==13185==    by 0x1BAAA6CE: add_to_buffer (execute.c:169)
==13185==    by 0x1BAAA897: insert_params (execute.c:231)
==13185==    by 0x1BAAB58C: my_SQLExecute (execute.c:595)
==13185==    by 0x1BAAB1EB: SQLExecute (execute.c:519)
==13185==    by 0x1B919D16: ??? (execute.c:194)
==13185==    by 0x1B919F9D: SQLExecute (execute.c:279)
==13185==    by 0x804917E: ODBC_Test (iodbctest.c:419)
==13185==    by 0x80496D8: main (iodbctest.c:631)
==13185==  Address 0x1B9B8477 is 1 bytes before a block of size 8192 alloc'd
==13185==    at 0x1B904A7C: malloc (vg_replace_malloc.c:131)
==13185==    by 0x1B90546B: realloc (vg_replace_malloc.c:189)
==13185==    by 0x1BABB1BC: my_realloc (in /usr/local/packages/myodbc-3.51-from-src/lib/libmyodbc3_r-3.51.07)
==13185==    by 0x1BAAA5AA: extend_buffer (execute.c:146)
==13185==    by 0x1BAAA69B: add_to_buffer (execute.c:167)
==13185==    by 0x1BAAA897: insert_params (execute.c:231)
==13185==    by 0x1BAAB58C: my_SQLExecute (execute.c:595)
==13185==    by 0x1BAAB1EB: SQLExecute (execute.c:519)
==13185==    by 0x1B919D16: ??? (execute.c:194)
==13185==    by 0x1B919F9D: SQLExecute (execute.c:279)
==13185==    by 0x804917E: ODBC_Test (iodbctest.c:419)
==13185==    by 0x80496D8: main (iodbctest.c:631)

Suggested fix:
Here is one possible fix:

--- execute.c.orig      2004-03-16 17:45:31.000000000 -0500
+++ execute.c   2004-08-23 16:15:01.801915528 -0400
@@ -126,18 +126,18 @@
 {
   ulong nead= 0;
   DBUG_ENTER("extend_buffer");
   DBUG_PRINT("enter",("current_length: %ld  length: %ld  buffer_length: %ld",
                      (ulong) (to - (char*) net->buff),
                      (ulong) length,
                      (ulong) net->max_packet));
 
-  if (!to ||
-      (nead= (ulong) (to - (char*) net->buff)+length) > net->max_packet-10)
+  nead = (ulong) (to - (char*) net->buff)+length;
+  if (!to || nead > net->max_packet-10)
   {
     ulong pkt_length= (nead+8192) & ~(8192-1);
     uchar *buff;
 
     if (pkt_length > max_allowed_packet)
     {
       DBUG_PRINT("error",("Needed %ld but max_allowed_packet is %ld",
                          pkt_length,max_allowed_packet));
[20 Dec 2004 10:58] Hartmut Holzgraefe
the proposed patch seems valid to me as 
assignments within a multicondition if() depend to much on lazy evaluation order
to be considered best practice anyway (or even assignments within if() in general)
[29 Dec 2004 19:07] Harun Eren
complete test program for bug

Attachment: test5173.zip (application/zip, text), 11.96 KiB.

[29 Dec 2004 19:18] Harun Eren
Hi, 

I have write a test program for this bug how describe, but it work on windows correctly, without crashing the mysql server.

Please, can you tell me: Whats server version from your application is used?

Best Regards.
[30 Dec 2004 14:50] Harun Eren
Hi,

it is not possible to reproduce this bug, the test programm is 
exactly writing how bug was described.

The test programm is as file attachment.

Please, can you check the test programm with your environment 
and whats happening.   Or can you give us a test program, 
which we can reproduce it.

Thanks.
Best Regards.
[30 Dec 2004 14:53] Harun Eren
new complete test program for bug

Attachment: test5173new.zip (application/zip, text), 6.71 KiB.

[14 Feb 2005 22:54] Bugs System
No feedback was provided for this bug for over a month, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
[31 May 2013 7:42] Bogdan Degtyariov
this bug report needs re-checking
[13 Jun 2013 13:31] Bogdan Degtyariov
The latest Connector/ODBC Driver code already contains the solution similar to what was proposed.
Closing the bug.