Bug #8330 mysql_stmt_execute crashes
Submitted: 5 Feb 2005 7:26 Modified: 10 Feb 2005 21:25
Reporter: Georg Richter
Status: Closed
Category:Server Severity:S2 (Serious)
Version:4.1.x + 5.0.x OS:Any (all)
Assigned to: Konstantin Osipov Target Version:

[5 Feb 2005 7:26] Georg Richter
Description:
When executing different prepared statements libmysql crashes (see how to repeat).
Note: this only happens if an input parameter was bound before.

Thanks to Mike Wyatt for reporting this bug (see http://bugs.php.net/bug.php?id=31526)

How to repeat:
Table-Definition:
CREATE TABLE t1 (a int, b int);

C-Code:
#include <stdio.h>
#include <mysql.h>

int main (int argc, char **argv) {
	MYSQL *mysql;
	MYSQL_STMT *stmt[2];
	int i;
	char *query = "SELECT a,b FROM t1 WHERE a=?";
	MYSQL_BIND bind[2];
	long lval[2];

	mysql = mysql_init(NULL);
	mysql_real_connect(mysql, "localhost", "root", "", "test", 0, NULL, 0);

	for (i=0; i < 2; i++) {
		stmt[i] = mysql_stmt_init(mysql);
		mysql_stmt_prepare(stmt[i], query, strlen(query));
		bind[i].buffer_type = MYSQL_TYPE_LONG;
		bind[i].buffer = (gptr)&lval[i];
		bind[i].is_null = 0;
		mysql_stmt_bind_param(stmt[i], &bind[i]);
	}

	if (mysql_stmt_execute(stmt[0]))
	    printf("Error [0]: %s\n", mysql_stmt_error(stmt[0]));
	if (mysql_stmt_execute(stmt[1]))
	    printf("Error [1]: %s\n", mysql_stmt_error(stmt[1]));

	/* boom !!! */
	if (mysql_stmt_execute(stmt[0]))
	    printf("Error [0]: %s\n", mysql_stmt_error(stmt[0]));

	mysql_stmt_close(stmt[0]);
	mysql_stmt_close(stmt[1]);
	
	mysql_close(mysql);
}
[9 Feb 2005 22:31] Konstantin Osipov
Subject: bk commit - 4.1 tree (konstantin:1.2165) BUG#8330

ChangeSet
  1.2165 05/02/10 00:19:38 konstantin@mysql.com +2 -0
  A fix and test case for Bug#8330 "mysql_stmt_execute crashes" (libmysql).
[10 Feb 2005 9:32] Patrick Galbraith
I have tested and reviewed this patch as follows:

Compiled the latest from bk for 4.1, placed the new test that contains the code that
exposes this bug into mysql_client_test, and saw that it caused a seg fault, running it
three times with the same results. I then patched libmysql.c with the patch, and
recompiled both the libmysql and mysql_client_test, reran the test 3 times, the test
passing every time.

In looking at this patch, the if block that checks the status of the statement handle is
in from within cli_stmt_execute, is placed best possible place (right before the call to
net_clear which is where without this check, it will segfault) to ensure that if the
statement handle is not ready (still dealing with the results of another statement), to
not proceed within cli_stmt_execute. This is what prevents the segfault from occurring for
the libmysql developer/user.

I consider this patch ready to be pushed.
[10 Feb 2005 12:58] Konstantin Osipov
Pushed into current 4.1 tree, which is tagged 4.1.10
[10 Feb 2005 21:25] Paul DuBois
Mentioned in 4.1.10 change notes.