| Bug #44767 | invalid memory reads in password() and old_password() functions | ||
|---|---|---|---|
| Submitted: | 10 May 2009 16:53 | Modified: | 29 Jun 2009 19:39 |
| Reporter: | Shane Bester (Platinum Quality Contributor) | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: General | Severity: | S1 (Critical) |
| Version: | 5.0.82, 5.1.30, 5.1.34, 5.1.35, 6.0.10 | OS: | Linux (32-bit fc8) |
| Assigned to: | Alexey Kopytov | CPU Architecture: | Any |
| Tags: | old_password, password, valgrind | ||
[27 May 2009 10:24]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/75039 2748 Alexey Kopytov 2009-05-27 Bug #44767: invalid memory reads in password() and old_password() functions The PASSWORD() and OLD_PASSWORD() functions could lead to memory reads outside of an internal buffer when used with BLOB arguments. String::c_ptr() assumes there is at least one extra byte in the internally allocated buffer when adding the trailing '\0'. This, however, may not be the case when a String object was initialized with externally allocated buffer. The bug was fixed by adding an additional "length" argument to make_scrambled_password_323() and make_scrambled_password() in order to avoid String::c_ptr() calls for PASSWORD()/OLD_PASSWORD(). However, since the make_scrambled_password[_323] functions are a part of the client library ABI, the functions with the new interfaces were implemented with the 'my_' prefix in their names, with the old functions changed to be wrappers around the new ones to maintain interface compatibility. modified: mysql-test/r/func_crypt.result mysql-test/t/func_crypt.test sql/item_strfunc.cc sql/item_strfunc.h sql/mysql_priv.h sql/password.c sql/sql_yacc.yy
[16 Jun 2009 8:32]
Bugs System
Pushed into 5.0.84 (revid:gkodinov@mysql.com-20090616082753-kwe0l8uoictxhojf) (version source revid:alexey.kopytov@sun.com-20090601124224-zgt3yov9wou590e9) (merge vers: 5.0.83) (pib:6)
[16 Jun 2009 11:03]
Bugs System
Pushed into 5.1.36 (revid:joro@sun.com-20090616102155-3zhezogudt4uxdyn) (version source revid:alexey.kopytov@sun.com-20090601124316-kezp7g9u9lzcqhl0) (merge vers: 5.1.36) (pib:6)
[17 Jun 2009 19:24]
Bugs System
Pushed into 5.4.4-alpha (revid:alik@sun.com-20090616183122-chjzbaa30qopdra9) (version source revid:alexey.kopytov@sun.com-20090601124405-svrero3hrfse6esa) (merge vers: 6.0.12-alpha) (pib:11)
[29 Jun 2009 19:39]
Paul DuBois
Noted in 5.0.84, 5.1.36, 5.4.4 changelogs. The PASSWORD() and OLD_PASSWORD() functions could read memory outside of an internal buffer when used with BLOB arguments.
[12 Aug 2009 22:29]
Paul DuBois
Noted in 5.4.2 changelog because next 5.4 version will be 5.4.2 and not 5.4.4.
[15 Aug 2009 1:47]
Paul DuBois
Ignore previous comment about 5.4.2.
[26 Aug 2009 13:46]
Bugs System
Pushed into 5.1.37-ndb-7.0.8 (revid:jonas@mysql.com-20090826132541-yablppc59e3yb54l) (version source revid:jonas@mysql.com-20090826132541-yablppc59e3yb54l) (merge vers: 5.1.37-ndb-7.0.8) (pib:11)
[26 Aug 2009 13:46]
Bugs System
Pushed into 5.1.37-ndb-6.3.27 (revid:jonas@mysql.com-20090826105955-bkj027t47gfbamnc) (version source revid:jonas@mysql.com-20090826105955-bkj027t47gfbamnc) (merge vers: 5.1.37-ndb-6.3.27) (pib:11)
[26 Aug 2009 13:48]
Bugs System
Pushed into 5.1.37-ndb-6.2.19 (revid:jonas@mysql.com-20090825194404-37rtosk049t9koc4) (version source revid:jonas@mysql.com-20090825194404-37rtosk049t9koc4) (merge vers: 5.1.37-ndb-6.2.19) (pib:11)
[27 Aug 2009 16:33]
Bugs System
Pushed into 5.1.35-ndb-7.1.0 (revid:magnus.blaudd@sun.com-20090827163030-6o3kk6r2oua159hr) (version source revid:jonas@mysql.com-20090826132541-yablppc59e3yb54l) (merge vers: 5.1.37-ndb-7.0.8) (pib:11)
[7 Oct 2009 19:34]
Paul DuBois
The 5.4 fix has been pushed to 5.4.2.

Description: the password() and old_password() functions read invalid memory when their arguments are longer than 128k. When <128k valgrind still outputs warnings about jumps depending on uninitialized memory values. Invalid read of size 1 : Item_func_old_password::val_str(String*) (sql_string.h:102) : Item::send(Protocol*, String*) (item.cc:5302) : select_send::send_data(List<Item>&) (sql_class.cc:1587) : end_send(JOIN*, st_join_table*, bool) (sql_select.cc:11976) : evaluate_join_record(JOIN*, st_join_table*, int) (sql_select.cc:11236) : sub_select(JOIN*, st_join_table*, bool) (sql_select.cc:11121) : do_select(JOIN*, List<Item>*, st_table*, Procedure*) (sql_select.cc:10877) : JOIN::exec() (sql_select.cc:2199) : mysql_select (sql_select.cc:2378) : handle_select(THD*, st_lex*, select_result*, unsigned long) (sql_select.cc:268) : execute_sqlcom_select(THD*, TABLE_LIST*) (sql_parse.cc:5009) : mysql_execute_command(THD*) (sql_parse.cc:2211) Address 0xC215AA0 is 0 bytes after a block of size 131,152 alloc'd : malloc (vg_replace_malloc.c:149) : ut_malloc_low (ut0mem.c:82) : ut_malloc (ut0mem.c:189) : mem_area_alloc (mem0pool.c:355) : mem_heap_create_block (mem0mem.c:362) : mem_heap_add_block (mem0mem.c:465) : btr_copy_externally_stored_field (mem0mem.ic:155) : btr_rec_copy_externally_stored_field (btr0cur.c:3847) : row_sel_store_mysql_rec (row0sel.c:2638) : row_search_for_mysql (row0sel.c:4234) : ha_innobase::index_read (ha_innodb.cc:4410) : ha_innobase::index_first(unsigned char*) (ha_innodb.cc:4674) Invalid read of size 1 : make_scrambled_password_323 (password.c:148) : Item_func_old_password::val_str(String*) (item_strfunc.cc:1655) : Item::send(Protocol*, String*) (item.cc:5302) : select_send::send_data(List<Item>&) (sql_class.cc:1587) : end_send(JOIN*, st_join_table*, bool) (sql_select.cc:11976) : evaluate_join_record(JOIN*, st_join_table*, int) (sql_select.cc:11236) : sub_select(JOIN*, st_join_table*, bool) (sql_select.cc:11121) : do_select(JOIN*, List<Item>*, st_table*, Procedure*) (sql_select.cc:10877) : JOIN::exec() (sql_select.cc:2199) : mysql_select (sql_select.cc:2378) : handle_select(THD*, st_lex*, select_result*, unsigned long) (sql_select.cc:268) : execute_sqlcom_select(THD*, TABLE_LIST*) (sql_parse.cc:5009) Address 0xC215AA0 is 0 bytes after a block of size 131,152 alloc'd : malloc (vg_replace_malloc.c:149) : ut_malloc_low (ut0mem.c:82) : ut_malloc (ut0mem.c:189) : mem_area_alloc (mem0pool.c:355) : mem_heap_create_block (mem0mem.c:362) : mem_heap_add_block (mem0mem.c:465) : btr_copy_externally_stored_field (mem0mem.ic:155) : btr_rec_copy_externally_stored_field (btr0cur.c:3847) : row_sel_store_mysql_rec (row0sel.c:2638) : row_search_for_mysql (row0sel.c:4234) : ha_innobase::index_read (ha_innodb.cc:4410) : ha_innobase::index_first(unsigned char*) (ha_innodb.cc:4674) Invalid read of size 1 : Item_func_password::val_str(String*) (sql_string.h:102) : Item::send(Protocol*, String*) (item.cc:5302) : select_send::send_data(List<Item>&) (sql_class.cc:1587) : end_send(JOIN*, st_join_table*, bool) (sql_select.cc:11976) : evaluate_join_record(JOIN*, st_join_table*, int) (sql_select.cc:11236) : sub_select(JOIN*, st_join_table*, bool) (sql_select.cc:11121) : do_select(JOIN*, List<Item>*, st_table*, Procedure*) (sql_select.cc:10877) : JOIN::exec() (sql_select.cc:2199) : mysql_select (sql_select.cc:2378) : handle_select(THD*, st_lex*, select_result*, unsigned long) (sql_select.cc:268) : execute_sqlcom_select(THD*, TABLE_LIST*) (sql_parse.cc:5009) : mysql_execute_command(THD*) (sql_parse.cc:2211) Address 0xC215AA0 is 0 bytes after a block of size 131,152 alloc'd : malloc (vg_replace_malloc.c:149) : ut_malloc_low (ut0mem.c:82) : ut_malloc (ut0mem.c:189) : mem_area_alloc (mem0pool.c:355) : mem_heap_create_block (mem0mem.c:362) : mem_heap_add_block (mem0mem.c:465) : btr_copy_externally_stored_field (mem0mem.ic:155) : btr_rec_copy_externally_stored_field (btr0cur.c:3847) : row_sel_store_mysql_rec (row0sel.c:2638) : row_search_for_mysql (row0sel.c:4234) : ha_innobase::index_read (ha_innodb.cc:4410) : ha_innobase::index_first(unsigned char*) (ha_innodb.cc:4674) Invalid read of size 1 : make_scrambled_password (password.c:399) : Item_func_password::val_str(String*) (item_strfunc.cc:1632) : Item::send(Protocol*, String*) (item.cc:5302) : select_send::send_data(List<Item>&) (sql_class.cc:1587) : end_send(JOIN*, st_join_table*, bool) (sql_select.cc:11976) : evaluate_join_record(JOIN*, st_join_table*, int) (sql_select.cc:11236) : sub_select(JOIN*, st_join_table*, bool) (sql_select.cc:11121) : do_select(JOIN*, List<Item>*, st_table*, Procedure*) (sql_select.cc:10877) : JOIN::exec() (sql_select.cc:2199) : mysql_select (sql_select.cc:2378) : handle_select(THD*, st_lex*, select_result*, unsigned long) (sql_select.cc:268) : execute_sqlcom_select(THD*, TABLE_LIST*) (sql_parse.cc:5009) Address 0xC215AA0 is 0 bytes after a block of size 131,152 alloc'd : malloc (vg_replace_malloc.c:149) : ut_malloc_low (ut0mem.c:82) : ut_malloc (ut0mem.c:189) : mem_area_alloc (mem0pool.c:355) : mem_heap_create_block (mem0mem.c:362) : mem_heap_add_block (mem0mem.c:465) : btr_copy_externally_stored_field (mem0mem.ic:155) : btr_rec_copy_externally_stored_field (btr0cur.c:3847) : row_sel_store_mysql_rec (row0sel.c:2638) : row_search_for_mysql (row0sel.c:4234) : ha_innobase::index_read (ha_innodb.cc:4410) : ha_innobase::index_first(unsigned char*) (ha_innodb.cc:4674) How to repeat: #start mysqld under valgrind and run the following sql: drop table if exists `t1`; create table `t1`(`c3` mediumblob)engine=innodb; insert into t1 values (repeat('a',131072)); select old_password(`c3`),password(`c3`) from `t1`;