Bug #68244 | lock_rec_validate_page() may dereference a pointer to a freed lock | ||
---|---|---|---|
Submitted: | 1 Feb 2013 13:24 | Modified: | 6 Jun 2013 15:13 |
Reporter: | Laurynas Biveinis (OCA) | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: InnoDB storage engine | Severity: | S3 (Non-critical) |
Version: | 5.5 | OS: | Any |
Assigned to: | CPU Architecture: | Any | |
Tags: | innodb, valgrind |
[1 Feb 2013 13:24]
Laurynas Biveinis
[1 Feb 2013 13:39]
MySQL Verification Team
I can confirm seeing this valgrind error on 5.5.31 today. I generic DML testcase with innodb_lock_monitor enabled. Thread 61: Invalid read of size 8 at: lock_rec_validate_page (lock0lock.c:5048) by: lock_rec_block_validate (lock0lock.c:5139) by: lock_validate (lock0lock.c:5192) by: lock_print_info_all_transactions (lock0lock.c:4663) by: srv_printf_innodb_monitor (srv0srv.c:1900) by: innodb_show_status (ha_innodb.cc:9458) by: innobase_show_status (ha_innodb.cc:9704) by: ha_show_status (handler.cc:4916) by: mysql_execute_command (sql_parse.cc:2330) by: mysql_parse (sql_parse.cc:5627) by: dispatch_command (sql_parse.cc:1037) by: do_command (sql_parse.cc:773) by: do_handle_one_connection (sql_connect.cc:853) by: handle_one_connection (sql_connect.cc:772) by: start_thread (pthread_create.c:309) by: clone (clone.S:115) Address 0x149769a0 is 320 bytes inside a block of size 376 free'd at: free (vg_replace_malloc.c:446) by: mem_area_free (mem0pool.c:519) by: mem_heap_block_free (mem0mem.c:511) by: mem_heap_free_func (mem0mem.ic:500) by: trx_free (trx0trx.c:323) by: trx_free_for_mysql (trx0trx.c:409) by: innobase_close_connection(handlerton*, THD*) (ha_innodb.cc:3049) by: closecon_handlerton (handler.cc:725) by: plugin_foreach_with_mask (sql_plugin.cc:2024) by: ha_close_connection(handler.cc:739) by: THD::~THD (sql_class.cc:1380) by: THD::~THD (sql_class.cc:1407) by: delete_thd (mysqld.cc:2160) by: unlink_thd (mysqld.cc:2189) by: one_thread_per_connection_end(THD*, bool) (mysqld.cc:2293) by: do_handle_one_connection(THD*) (sql_connect.cc:860) by: handle_one_connection (sql_connect.cc:772) by: start_thread (pthread_create.c:309) by: clone (clone.S:115)
[1 Feb 2013 13:45]
MySQL Verification Team
Same testcase hits another valgrind error: Conditional jump or move depends on uninitialised value(s) at 0x926995: rec_offs_validate (rem0rec.ic:971) by 0x9FA2B3: lock_rec_queue_validate (lock0lock.c:4839) by 0x9FAAD2: lock_rec_validate_page (lock0lock.c:5048) by 0x9FAD60: lock_rec_block_validate (lock0lock.c:5139) by 0x9FAE97: lock_validate (lock0lock.c:5192) by 0x9F9C8A: lock_print_info_all_transactions (lock0lock.c:4663) by 0x94D2C7: srv_printf_innodb_monitor (srv0srv.c:1900) by 0x917D44: innodb_show_status (ha_innodb.cc:9458) by 0x91877F: innobase_show_status (ha_innodb.cc:9704) by 0x76D801: ha_show_status (handler.cc:4916) by 0x5FA839: mysql_execute_command (sql_parse.cc:2330) by 0x6031A5: mysql_parse (sql_parse.cc:5627) by 0x5F7802: dispatch_command (sql_parse.cc:1037) by 0x5F6AB4: do_command (sql_parse.cc:773) by 0x6DC3F7: do_handle_one_connection(THD*) (sql_connect.cc:853) by 0x6DBED6: handle_one_connection (sql_connect.cc:772) by 0x3679C07D13: start_thread (pthread_create.c:309) by 0x36798F168C: clone (clone.S:115) ==31577== 971 if (index) { (gdb) p index $1 = (const dict_index_t *) 0x152fbfc8
[13 Feb 2013 0:17]
Roel Van de Paar
And a few other possibly related ones (seen directly after the first one) Conditional jump or move depends on uninitialised value(s) at 0x95CC5F: dict_index_get_n_unique_in_tree (dict0dict.ic:588) by 0x9609DA: rec_offs_validate (rem0rec.ic:974) by 0x966A2D: lock_rec_queue_validate (lock0lock.c:4760) by 0x9674C8: lock_rec_block_validate (lock0lock.c:4969) by 0x968FAB: lock_print_info_all_transactions (lock0lock.c:5113) by 0x880D10: srv_printf_innodb_monitor (srv0srv.c:2267) by 0x880F09: srv_monitor_thread (srv0srv.c:2584) by 0x4E34850: start_thread (in /lib64/libpthread-2.12.so) by 0x199CA6FF: ??? Conditional jump or move depends on uninitialised value(s) at 0x9609B4: rec_offs_validate (rem0rec.ic:973) by 0x966A2D: lock_rec_queue_validate (lock0lock.c:4760) by 0x9674C8: lock_rec_block_validate (lock0lock.c:4969) by 0x968FAB: lock_print_info_all_transactions (lock0lock.c:5113) by 0x880D10: srv_printf_innodb_monitor (srv0srv.c:2267) by 0x880F09: srv_monitor_thread (srv0srv.c:2584) by 0x4E34850: start_thread (in /lib64/libpthread-2.12.so) by 0x199CA6FF: ??? Conditional jump or move depends on uninitialised value(s) at 0x95C9B8: dict_index_is_clust (dict0dict.ic:250) by 0x95CCCF: dict_index_get_n_unique_in_tree (dict0dict.ic:592) by 0x9609DA: rec_offs_validate (rem0rec.ic:974) by 0x966A2D: lock_rec_queue_validate (lock0lock.c:4760) by 0x9674C8: lock_rec_block_validate (lock0lock.c:4969) by 0x968FAB: lock_print_info_all_transactions (lock0lock.c:5113) by 0x880D10: srv_printf_innodb_monitor (srv0srv.c:2267) by 0x880F09: srv_monitor_thread (srv0srv.c:2584) by 0x4E34850: start_thread (in /lib64/libpthread-2.12.so) by 0x199CA6FF: ??? Use of uninitialised value of size 8 at 0x95C9D7: dict_index_is_clust (dict0dict.ic:251) by 0x95CCCF: dict_index_get_n_unique_in_tree (dict0dict.ic:592) by 0x9609DA: rec_offs_validate (rem0rec.ic:974) by 0x966A2D: lock_rec_queue_validate (lock0lock.c:4760) by 0x9674C8: lock_rec_block_validate (lock0lock.c:4969) by 0x968FAB: lock_print_info_all_transactions (lock0lock.c:5113) by 0x880D10: srv_printf_innodb_monitor (srv0srv.c:2267) by 0x880F09: srv_monitor_thread (srv0srv.c:2584) by 0x4E34850: start_thread (in /lib64/libpthread-2.12.so) by 0x199CA6FF: ??? Use of uninitialised value of size 8 at 0x95CCD5: dict_index_get_n_unique_in_tree (dict0dict.ic:573) by 0x9609DA: rec_offs_validate (rem0rec.ic:974) by 0x966A2D: lock_rec_queue_validate (lock0lock.c:4760) by 0x9674C8: lock_rec_block_validate (lock0lock.c:4969) by 0x968FAB: lock_print_info_all_transactions (lock0lock.c:5113) by 0x880D10: srv_printf_innodb_monitor (srv0srv.c:2267) by 0x880F09: srv_monitor_thread (srv0srv.c:2584) by 0x4E34850: start_thread (in /lib64/libpthread-2.12.so) by 0x199CA6FF: ??? Use of uninitialised value of size 8 at 0x9609DB: rec_offs_validate (dict0dict.ic:551) by 0x966A2D: lock_rec_queue_validate (lock0lock.c:4760) by 0x9674C8: lock_rec_block_validate (lock0lock.c:4969) by 0x968FAB: lock_print_info_all_transactions (lock0lock.c:5113) by 0x880D10: srv_printf_innodb_monitor (srv0srv.c:2267) by 0x880F09: srv_monitor_thread (srv0srv.c:2584) by 0x4E34850: start_thread (in /lib64/libpthread-2.12.so) by 0x199CA6FF: ??? Conditional jump or move depends on uninitialised value(s) at 0x966C31: lock_rec_queue_validate (lock0lock.c:4799) by 0x9674C8: lock_rec_block_validate (lock0lock.c:4969) by 0x968FAB: lock_print_info_all_transactions (lock0lock.c:5113) by 0x880D10: srv_printf_innodb_monitor (srv0srv.c:2267) by 0x880F09: srv_monitor_thread (srv0srv.c:2584) by 0x4E34850: start_thread (in /lib64/libpthread-2.12.so) by 0x199CA6FF: ??? etc.
[13 Feb 2013 0:26]
Roel Van de Paar
Full error log with all Valgrind warnings
Attachment: 13213_master.err (application/octet-stream, text), 788.36 KiB.
[5 Mar 2013 12:54]
MySQL Verification Team
run mysqld in valgrind, then execute this testcase against it.
Attachment: bug68244.c (text/plain), 10.48 KiB.
[5 Mar 2013 22:29]
Roel Van de Paar
Shane: great, as always. Thanks!
[6 Mar 2013 5:38]
MySQL Verification Team
It took nearly an hour for this last testcase to hit a problem on my machine. So when it did, I just uploaded it. It does need improvement..
[8 Apr 2013 14:01]
Bugs System
Added changelog entry for 5.5.32, 5.6.12, 5.7.2: "When calling the "lock_rec_block_validate()" function after releasing the kernel mutex, there is a chance the lock might be invalid and result in a Valgrind error due to an invalid read on "lock->index". This fix copies the "lock->index" when the kernel mutex is being held and passes the "lock->index" to "lock_rec_block_validate()".
[6 Jun 2013 15:13]
Laurynas Biveinis
5.6$ bzr log -r 2875.437.8 ------------------------------------------------------------ revno: 2875.437.8 committer: Aditya A <aditya.a@oracle.com> branch nick: mysql-5.5 timestamp: Wed 2013-03-13 11:43:21 +0530 message: Bug#16268289 LOCK_REC_VALIDATE_PAGE() MAY DEREFERENCE A POINTER TO A FREED LOCK ANALYIS ------- In 5.5 code the lock_rec_block_validate() is called after releasing the kernel mutex. There is a chance that the lock might be invalid so, we are getting the valgrind error on invalid read on lock->index. FIX --- Fix would be to copy the lock->index when we are holding the kernel mutex and then pass it to the lock_rec_block_validate(). This implementation is present in 5.1 code. [ Approved by sunny rb.no.oracle.com/rb/r/2152/ ]