Bug #102477 When one row of result exceeded 4GB, the server does not response appropriately
Description:
create table t1 (a longblob);
insert into t1 values (load_file("../../mysql64_linux.tar.gz"));
-- make sure the length of one row of result exceeded 4GB.
select a,a,a,a,a,a,a,a,a,a,a from t1;
1. When the server is compiled as debug, the server failed for DBUG_ASSERT:
virtual bool Sql_cmd_dml::execute(THD*): Assertion `thd->is_error() || thd->killed' failed.
06:31:03 UTC - mysqld got signal 6 ;
Most likely, you have hit a bug, but this error can also be caused by malfunctioning hardware.
Thread pointer: 0x4ea0e800
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 7fb49c7abba8 thread_stack 0x46000
/home/wqldb_8018/bin/mysqld(my_print_stacktrace(unsigned char const*, unsigned long)+0x43) [0x4c35aa4]
/home/wqldb_8018/bin/mysqld(handle_fatal_signal+0x2bf) [0x38e6be6]
/usr/lib64/libpthread.so.0(+0xf5e0) [0x7fb49c0d25e0]
/usr/lib64/libc.so.6(gsignal+0x37) [0x7fb49a21e1f7]
/usr/lib64/libc.so.6(abort+0x148) [0x7fb49a21f8e8]
/usr/lib64/libc.so.6(+0x2e266) [0x7fb49a217266]
/usr/lib64/libc.so.6(+0x2e312) [0x7fb49a217312]
/home/wqldb_8018/bin/mysqld(Sql_cmd_dml::execute(THD*)+0x699) [0x372dc39]
/home/wqldb_8018/bin/mysqld(mysql_execute_command(THD*, bool)+0x5c69) [0x36c9833]
/home/wqldb_8018/bin/mysqld(mysql_parse(THD*, Parser_state*)+0x798) [0x36cca0b]
/home/wqldb_8018/bin/mysqld(dispatch_command(THD*, COM_DATA const*, enum_server_command)+0x1609) [0x36c0768]
/home/wqldb_8018/bin/mysqld(do_command(THD*)+0x47d) [0x36bda37]
/home/wqldb_8018/bin/mysqld(threadpool_process_request(THD*, int*)+0x19e) [0x3856e61]
/home/wqldb_8018/bin/mysqld() [0x38ad285]
/home/wqldb_8018/bin/mysqld() [0x38ad41b]
/home/wqldb_8018/bin/mysqld() [0x540999e]
/usr/lib64/libpthread.so.0(+0x7e25) [0x7fb49c0cae25]
/usr/lib64/libc.so.6(clone+0x6d) [0x7fb49a2e134d]
2. When the server is compiled as release, the client returns a error message:
ERROR 2027 (HY000) at line 1: Malformed packet
3. The two expressions are both caused by the failure of memory realloc in String class:
bool String::mem_realloc(size_t alloc_length, bool force_on_heap) {
...
// Signal an error if len exceeds uint32 max on 64-bit word platform.
#if defined(__WORDSIZE) && (__WORDSIZE == 64)
if (len > std::numeric_limits<uint32>::max()) return true;
#endif
...
}
Please notice that no error message is pushed on the error stack when len exceeds uint32 max.
Go on the process of failure:
bool Sql_cmd_dml::execute(THD *thd) {
...
// Perform statement-specific execution
res = execute_inner(thd); // res = true here
...
if (res) goto err;
...
err:
DBUG_ASSERT(thd->is_error() || thd->killed); // debug builds failed here, no error in error stack, thd->is_error() = false
..
return thd->is_error(); // return false but in fact there is error and no record is send
}
Then, since Sql_cmd_dml::execute returns true, the server sends the OK packet and the client receives it but parses it as a data packet and fails as "ERROR 2027 (HY000) at line 1: Malformed packet".
In conclusion, error message should push to error stack in String::mem_realloc.
How to repeat:
As above.
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.050 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.
Description: create table t1 (a longblob); insert into t1 values (load_file("../../mysql64_linux.tar.gz")); -- make sure the length of one row of result exceeded 4GB. select a,a,a,a,a,a,a,a,a,a,a from t1; 1. When the server is compiled as debug, the server failed for DBUG_ASSERT: virtual bool Sql_cmd_dml::execute(THD*): Assertion `thd->is_error() || thd->killed' failed. 06:31:03 UTC - mysqld got signal 6 ; Most likely, you have hit a bug, but this error can also be caused by malfunctioning hardware. Thread pointer: 0x4ea0e800 Attempting backtrace. You can use the following information to find out where mysqld died. If you see no messages after this, something went terribly wrong... stack_bottom = 7fb49c7abba8 thread_stack 0x46000 /home/wqldb_8018/bin/mysqld(my_print_stacktrace(unsigned char const*, unsigned long)+0x43) [0x4c35aa4] /home/wqldb_8018/bin/mysqld(handle_fatal_signal+0x2bf) [0x38e6be6] /usr/lib64/libpthread.so.0(+0xf5e0) [0x7fb49c0d25e0] /usr/lib64/libc.so.6(gsignal+0x37) [0x7fb49a21e1f7] /usr/lib64/libc.so.6(abort+0x148) [0x7fb49a21f8e8] /usr/lib64/libc.so.6(+0x2e266) [0x7fb49a217266] /usr/lib64/libc.so.6(+0x2e312) [0x7fb49a217312] /home/wqldb_8018/bin/mysqld(Sql_cmd_dml::execute(THD*)+0x699) [0x372dc39] /home/wqldb_8018/bin/mysqld(mysql_execute_command(THD*, bool)+0x5c69) [0x36c9833] /home/wqldb_8018/bin/mysqld(mysql_parse(THD*, Parser_state*)+0x798) [0x36cca0b] /home/wqldb_8018/bin/mysqld(dispatch_command(THD*, COM_DATA const*, enum_server_command)+0x1609) [0x36c0768] /home/wqldb_8018/bin/mysqld(do_command(THD*)+0x47d) [0x36bda37] /home/wqldb_8018/bin/mysqld(threadpool_process_request(THD*, int*)+0x19e) [0x3856e61] /home/wqldb_8018/bin/mysqld() [0x38ad285] /home/wqldb_8018/bin/mysqld() [0x38ad41b] /home/wqldb_8018/bin/mysqld() [0x540999e] /usr/lib64/libpthread.so.0(+0x7e25) [0x7fb49c0cae25] /usr/lib64/libc.so.6(clone+0x6d) [0x7fb49a2e134d] 2. When the server is compiled as release, the client returns a error message: ERROR 2027 (HY000) at line 1: Malformed packet 3. The two expressions are both caused by the failure of memory realloc in String class: bool String::mem_realloc(size_t alloc_length, bool force_on_heap) { ... // Signal an error if len exceeds uint32 max on 64-bit word platform. #if defined(__WORDSIZE) && (__WORDSIZE == 64) if (len > std::numeric_limits<uint32>::max()) return true; #endif ... } Please notice that no error message is pushed on the error stack when len exceeds uint32 max. Go on the process of failure: bool Sql_cmd_dml::execute(THD *thd) { ... // Perform statement-specific execution res = execute_inner(thd); // res = true here ... if (res) goto err; ... err: DBUG_ASSERT(thd->is_error() || thd->killed); // debug builds failed here, no error in error stack, thd->is_error() = false .. return thd->is_error(); // return false but in fact there is error and no record is send } Then, since Sql_cmd_dml::execute returns true, the server sends the OK packet and the client receives it but parses it as a data packet and fails as "ERROR 2027 (HY000) at line 1: Malformed packet". In conclusion, error message should push to error stack in String::mem_realloc. How to repeat: As above.