Bug #8330 mysql_stmt_execute crashes
Submitted: 5 Feb 2005 6:26 Modified: 10 Feb 2005 20:25
Reporter: Georg Richter Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S2 (Serious)
Version:4.1.x + 5.0.x OS:Any (all)
Assigned to: Konstantin Osipov CPU Architecture:Any

[5 Feb 2005 6: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 21: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 8: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 11:58] Konstantin Osipov
Pushed into current 4.1 tree, which is tagged 4.1.10
[10 Feb 2005 20:25] Paul DuBois
Mentioned in 4.1.10 change notes.