| Bug #90412 | potential stack corruption with function casting (int-returning to void-returnin | ||
|---|---|---|---|
| Submitted: | 12 Apr 2018 11:16 | Modified: | 19 Apr 2018 17:47 |
| Reporter: | Przemysław Skibiński (OCA) | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: MyISAM storage engine | Severity: | S3 (Non-critical) |
| Version: | 5.5, 5.6, 5.7 | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
[12 Apr 2018 13:25]
MySQL Verification Team
Hi, Thank you, very much, for your bug report. Your analysis is quite correct and I agree with your findings. I only do not agree about how critical is this bug, since this code is in production for decades. Verified as reported.
[18 Apr 2018 10:44]
Tor Didriksen
Posted by developer:
I haven't seen the gcc warning, but clang/UBSAN agrees:
./mtr --mem --sanitize main.ctype_utf8
mysys/tree.cc:160:11: runtime error: call to function keys_free(unsigned char*, TREE_FREE, bulk_insert_param*) through pointer to incorrect function type 'void (*)(void *, TREE_FREE, const void *)'
storage/myisam/mi_write.cc:826: note: keys_free(unsigned char*, TREE_FREE, bulk_insert_param*) defined here
#0 0x9b9f507 in free_tree(TREE*, int) mysys/tree.cc:160:11
#1 0x9b9f0b2 in delete_tree(TREE*) mysys/tree.cc:175:3
#2 0xb23f7c9 in mi_end_bulk_insert(MI_INFO*) storage/myisam/mi_write.cc:922:9
#3 0xb07938b in ha_myisam::end_bulk_insert() storage/myisam/ha_myisam.cc:1466:3
#4 0x555c95d in handler::ha_end_bulk_insert() sql/handler.cc:4419:3
#5 0x62e0360 in Query_result_insert::send_eof() sql/sql_insert.cc:2098:47
#6 0x6210d53 in do_select(JOIN*) sql/sql_executor.cc:1216:45
#7 0x620d48d in JOIN::exec() sql/sql_executor.cc:294:11
#8 0x4767661 in Sql_cmd_dml::execute_inner(THD*) sql/sql_select.cc:651:35
#9 0x4765006 in Sql_cmd_dml::execute(THD*) sql/sql_select.cc:554:7
[19 Apr 2018 17:47]
Paul DuBois
Posted by developer: Fixed in 8.0.13. Code cleanup. No changelog entry needed.

Description: Calling a int-returning function static int keys_free(uchar *key, TREE_FREE mode, bulk_insert_param *param) that is cast to a void-returning function: typedef void (*tree_element_free)(void*, TREE_FREE, void *); can potentially lead to a stack corruption. gcc-8 show this as a warning: [ 26%] Building C object storage/myisam/CMakeFiles/myisam.dir/mi_write.c.o /github/mysql-server/storage/myisam/mi_write.c: In function ‘mi_init_bulk_insert’: /github/mysql-server/storage/myisam/mi_write.c:1016:3: warning: cast between incompatible function types from ‘int (*)(uchar *, TREE_FREE, bulk_insert_param *)’ {aka ‘int (*)(unsigned char *, enum <anonymous>, struct <anonymous> *)’} to ‘void (*)(void *, TREE_FREE, const void *)’ {aka ‘void (*)(void *, enum <anonymous>, const void *)’} [-Wcast-function-type] (tree_element_free) keys_free, (void *)params++); ^ How to repeat: mysql-server/storage/myisam/mi_write.c:1012 init_tree(&info->bulk_insert[i], cache_size * key[i].maxlength, cache_size * key[i].maxlength, 0, (qsort_cmp2)keys_compare, 0, (tree_element_free) keys_free, (void *)params++); Suggested fix: Convert keys_free() to: void keys_free(void*, TREE_FREE, void *);