Bug #29015 Stack overflow in processing temporary table name when tmpdir path is long
Submitted: 11 Jun 2007 8:15 Modified: 18 Jun 2007 15:45
Reporter: Alexey Kopytov Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: General Severity:S3 (Non-critical)
Version:5.0, 5.1 OS:Any
Assigned to: Alexey Kopytov CPU Architecture:Any

[11 Jun 2007 8:15] Alexey Kopytov
Description:
There is a number of places in code where table names are assumed to not exceed NAME_LEN (64) bytes. However, that that is not always true for internal temporary tables, because create_tmp_table() sets table_name to a full filesystem path of a table. This can lead to stack corruption in some cases when tmpdir patch is long enough to overflow the buffer.

Example:

shell> mkdir /tmp/long_temporary_directory_path_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

shell> ./mysqld --tmpdir=/tmp/long_temporary_directory_path_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

mysql> create view v1 as select table_name  from information_schema.TABLES;

ERROR 2013 (HY000): Lost connection to MySQL server during query

Backtrace:

(gdb) bt
#0  0xffffe410 in __kernel_vsyscall ()
#1  0xb7e13df0 in raise () from /lib/tls/i686/cmov/libc.so.6
#2  0xb7e15641 in abort () from /lib/tls/i686/cmov/libc.so.6
#3  0xb7e499bb in ?? () from /lib/tls/i686/cmov/libc.so.6
#4  0xb50927c4 in ?? ()
#5  0xfbad8004 in ?? ()
#6  0xb7fa11b5 in pthread_getspecific () from /lib/tls/i686/cmov/libpthread.so.0
#7  0xb7ecf0e1 in __stack_chk_fail () from /lib/tls/i686/cmov/libc.so.6
#8  0x08307178 in name_hash_search (name_hash=0x887dcc0, host=0x869164d "localhost", ip=0x0, db=0x8dcbe88 "information_schema", user=0x8d94578 "root",
    tname=0x8dd9400 "/tmp/long_temporary_directory_path_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789/#sql_2a87_0",
    exact=false) at sql_acl.cc:2296
#9  0x0831b72e in table_hash_search (host=0x869164d "localhost", ip=0x0, db=0x8dcbe88 "information_schema", user=0x8d94578 "root",
    tname=0x8dd9400 "/tmp/long_temporary_directory_path_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789/#sql_2a87_0",
    exact=false) at sql_acl.cc:2314
#10 0x0830bae5 in get_column_grant (thd=0x8d92a80, grant=0x8dd8af4, db_name=0x8dcbe88 "information_schema",
    table_name=0x8dd9400 "/tmp/long_temporary_directory_path_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789/#sql_2a87_0", field_name=0x8dcc190 "TABLE_NAME") at sql_acl.cc:4123
#11 0x081acbee in Item_field::fix_fields (this=0x8dcbdc0, thd=0x8d92a80, reference=0x8dcbe84) at item.cc:3898
#12 0x08295996 in setup_fields (thd=0x8d92a80, ref_pointer_array=0x8dcce50, fields=@0x8d93aac, set_query_id=true, sum_func_list=0x8dddc84,
    allow_sum_func=true) at sql_base.cc:4689
#13 0x082c9037 in JOIN::prepare (this=0x8ddcf48, rref_pointer_array=0x8d93b3c, tables_init=0x8dcbec8, wild_num=0, conds_init=0x0, og_num=0,
    order_init=0x0, group_init=0x0, having_init=0x0, proc_param_init=0x0, select_lex_arg=0x8d93a18, unit_arg=0x8d937e0) at sql_select.cc:468
#14 0x083ce991 in st_select_lex_unit::prepare (this=0x8d937e0, thd_arg=0x8d92a80, sel_result=0x0, additional_options=0) at sql_union.cc:256
#15 0x083dda35 in mysql_create_view (thd=0x8d92a80, views=0x8dcbc08, mode=VIEW_CREATE_NEW) at sql_view.cc:458
#16 0x0826a795 in mysql_execute_command (thd=0x8d92a80) at sql_parse.cc:4869
#17 0x0826b67f in mysql_parse (thd=0x8d92a80, inBuf=0x8dcbb60 "create view v1 as select table_name  from information_schema.TABLES", length=67)
    at sql_parse.cc:6018
#18 0x0826dfc8 in dispatch_command (command=COM_QUERY, thd=0x8d92a80,
    packet=0x8dc3b01 "create view v1 as select table_name  from information_schema.TABLES", packet_length=68) at sql_parse.cc:1802
#19 0x0826f7b7 in do_command (thd=0x8d92a80) at sql_parse.cc:1581
#20 0x08270ac0 in handle_one_connection (arg=0x8d92a80) at sql_parse.cc:1193
#21 0xb7f9c31b in start_thread () from /lib/tls/i686/cmov/libpthread.so.0
#22 0xb7eb957e in clone () from /lib/tls/i686/cmov/libc.so.6

The reason for the above crash is the following code in name_hash_search():
--- cut ---
static GRANT_NAME *name_hash_search(HASH *name_hash,
              const char *host,const char* ip,
              const char *db,
              const char *user, const char *tname,
              bool exact)
{
  char helping [NAME_LEN*2+USERNAME_LENGTH+3];
  uint len;
  ...
   len  = (uint) (strmov(strmov(strmov(helping,user)+1,db)+1,tname)-helping)+ 1;
--- cut ---

How to repeat:
shell> mkdir /tmp/long_temporary_directory_path_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

shell> ./mysqld --tmpdir=/tmp/long_temporary_directory_path_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

mysql> create view v1 as select table_name  from information_schema.TABLES;

ERROR 2013 (HY000): Lost connection to MySQL server during query

Suggested fix:
Do not set filesystem path as a table name for temporary tables.
[11 Jun 2007 12:18] 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/28490

ChangeSet@1.2486, 2007-06-11 16:18:26+04:00, kaa@polly.local +4 -0
  Fix for bug #29015 "Stack overflow in processing temporary table name when tmpdir path is long"
  
  In create_tmp_table() don't set full table path as a table name. Other code assumes table names to not exceed NAME_LEN bytes.
[11 Jun 2007 19:06] 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/28517

ChangeSet@1.2486, 2007-06-11 23:06:20+04:00, kaa@polly.local +5 -0
  Fix for bug #29015 "Stack overflow in processing temporary table name when tmpdir path is long"
  
  In create_tmp_table() don't set full table path as a table name. Other code assumes table names to not exceed NAME_LEN bytes.
[16 Jun 2007 4:50] Bugs System
Pushed into 5.0.44
[16 Jun 2007 4:50] Bugs System
Pushed into 5.1.20-beta
[18 Jun 2007 15:45] Paul Dubois
Noted in 5.0.44, 5.1.20 changelogs.

Long pathnames for internal temporary tables could cause stack
overflows.
[24 Jul 2008 7:20] James Day
This fix caused bug #30287 which was fixed in 5.0.48 and 5.1.22.