| Bug #70664 | mysql embedded mysql_stmt_execute return "malformed communication packet" error | ||
|---|---|---|---|
| Submitted: | 19 Oct 2013 8:16 | Modified: | 2 Dec 2015 14:22 |
| Reporter: | ZiYe Shi | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: Embedded Library ( libmysqld ) | Severity: | S2 (Serious) |
| Version: | 5.6.14, 5.6.28 | OS: | Linux |
| Assigned to: | CPU Architecture: | Any | |
[29 Nov 2013 20:34]
Sveta Smirnova
Thank you for the report. Verified as described.
[29 Nov 2013 20:36]
Sveta Smirnova
test case to compile and run
Attachment: bug70664.c (text/x-c), 972 bytes.
[29 Nov 2013 20:36]
Sveta Smirnova
Configuration file for the test case (change paths)
Attachment: bug70664.cnf (application/octet-stream, text), 118 bytes.
[7 Feb 2015 14:34]
Oliver Foo
I can confirm this bug but the suggested fix didn't work for me.
Instead I had to remove the check to be able to execute prepared statements:
--- sql/sql_prepare.cc.org 2015-02-07 14:58:12.729942921 +0100
+++ sql/sql_prepare.cc 2015-02-07 14:58:12.725942921 +0100
@@ -2667,12 +2667,6 @@
bool open_cursor;
DBUG_ENTER("mysqld_stmt_execute");
- if (packet + 9 > packet_end)
- {
- my_error(ER_MALFORMED_PACKET, MYF(0));
- DBUG_VOID_RETURN;
- }
-
stmt_id= uint4korr(packet);
flags= (ulong) packet[4];
packet+= 9; /* stmt_id + 5 bytes of flags */
I have MySQL 5.6.23, my application worked fine before with older version 5.5.42.
[26 Oct 2015 7:50]
MySQL Verification Team
// repeatable with 5.6.28 // Build and OS [umshastr@hod04]/export/umesh/server/mysql-advanced-5.6.28: cat docs/INFO_SRC commit: 55f4637c9e22a236e440663279e527bce048cb71 date: 2015-10-22 17:03:45 +0530 build-date: 2015-10-24 09:01:20 +0200 short: 55f4637 branch: mysql-5.6 MySQL source 5.6.28 [umshastr@hod04]/export/umesh/server/mysql-advanced-5.6.28: cat /etc/*release Oracle Linux Server release 7.1 NAME="Oracle Linux Server" VERSION="7.1" ID="ol" VERSION_ID="7.1" PRETTY_NAME="Oracle Linux Server 7.1" ANSI_COLOR="0;31" CPE_NAME="cpe:/o:oracle:linux:7:1" HOME_URL="https://linux.oracle.com/" BUG_REPORT_URL="https://bugzilla.oracle.com/" ORACLE_BUGZILLA_PRODUCT="Oracle Linux 7" ORACLE_BUGZILLA_PRODUCT_VERSION=7.1 ORACLE_SUPPORT_PRODUCT="Oracle Linux" ORACLE_SUPPORT_PRODUCT_VERSION=7.1 Red Hat Enterprise Linux Server release 7.1 (Maipo) Oracle Linux Server release 7.1 ## Test case used from Bug #70664 [umshastr@hod04]/export/umesh/server/mysql-advanced-5.6.28: g++ bug70664.c -g -o bug70664 -I/export/umesh/server/mysql-advanced-5.6.28/include -L/export/umesh/server/mysql-advanced-5.6.28/lib -lmysqld -lpthread -lm -lrt -ldl -lcrypt -laio bug70664.c:10:123: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] static char *server_options[] = { "mysql_test", "--defaults-file=/export/umesh/server/mysql-advanced-5.6.28/bug70664.cnf" }; ^ bug70664.c:10:123: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] bug70664.c:13:53: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] static char *server_groups[] = { "mysqld", "client" }; ^ bug70664.c:13:53: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] [umshastr@hod04]/export/umesh/server/mysql-advanced-5.6.28: ./bug70664 failed to execute stmt:Malformed communication packet. [umshastr@hod04]/export/umesh/server/mysql-advanced-5.6.28: [umshastr@hod04]/export/umesh/server/mysql-advanced-5.6.28: ./bug70664 failed to execute stmt:Malformed communication packet. [umshastr@hod04]/export/umesh/server/mysql-advanced-5.6.28: ./bug70664 failed to execute stmt:Malformed communication packet.
[26 Oct 2015 8:00]
MySQL Verification Team
// 5.5.47 - Segmentation fault [umshastr@hod04]/export/umesh/server/mysql-5.5.47-linux2.6-x86_64: g++ bug70664.c -g -o bug70664 -I/export/umesh/server/mysql-5.5.47-linux2.6-x86_64/include -L/export/umesh/server/mysql-5.5.47-linux2.6-x86_64/lib -lmysqld -lpthread -lm -lrt -lcrypt -ldl -laio -lz bug70664.c:10:123: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] static char *server_options[] = { "mysql_test", "--defaults-file=/export/umesh/server/mysql-advanced-5.6.28/bug70664.cnf" }; ^ bug70664.c:10:123: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] bug70664.c:13:53: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] static char *server_groups[] = { "mysqld", "client" }; ^ bug70664.c:13:53: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] [umshastr@hod04]/export/umesh/server/mysql-5.5.47-linux2.6-x86_64: ./bug70664 Segmentation fault (core dumped) [umshastr@hod04]/export/umesh/server/mysql-5.5.47-linux2.6-x86_64:
[2 Dec 2015 14:22]
Paul DuBois
Noted in 5.6.29, 5.7.11, 5.8.0 changelogs. When used with the libmysqld embedded server, the mysql_stmt_execute() C API function failed with a "malformed communication packet" error, even for simple prepared statments.

Description: When using prepared statement with libmysqld, if you call mysql_stmt_execute, it will return "malformed communication packet" error. Even a very simple query without any bind will throw the error. I have read the sources, and found a packet bug in libmysqld/lib_sql.cc. The packet size(5 bytes) is wrong, it shuold be 9 bytes (see sql/sql_prepare.cc[mysql_stmt_execute] & libmysql/libmysql.c[execute]). This bug also exists in version 5.1.72 & 5.5.34, but it is not activated because sql_prepare.cc do not care about the packet size. In version 5.6.14, sql/sql_prepare.cc[mysql_stmt_execute] add some code to check packet size. if (packet + 9 > packet_end) { my_error(ER_MALFORMED_PACKET, MYF(0)); DBUG_VOID_RETURN; } The bug was activated then. After fix the bug (see my suggestion), embedded version prepared statement will work fine. How to repeat: // a simple stmt query will break; char sql[] ="select version()"; mysql_stmt_prepare(stmt, sql, strlen(sql)); if (mysql_stmt_execute(stmt)) printf("failed to execute stmt:%s\n", mysql_stmt_error(stmt)); Suggested fix: libmysqld/lib_sql.cc static int emb_stmt_execute(MYSQL_STMT *stmt) { DBUG_ENTER("emb_stmt_execute"); uchar header[9]; // fix packet size, 5->9 THD *thd; my_bool res; int4store(header, stmt->stmt_id); header[4]= (uchar) stmt->flags; int4store(header+5, 1); // add this line, see ../libmysql/libmysql.c[execute] ... }