Bug #25972 Uninitialized value in archive read()/write() causing havoc
Submitted: 31 Jan 2007 11:51 Modified: 1 Feb 2007 7:44
Reporter: Kristian Nielsen Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Archive storage engine Severity:S3 (Non-critical)
Version:5.1.16-BK OS:Linux (Linux x86_64)
Assigned to: Brian Aker CPU Architecture:Any

[31 Jan 2007 11:51] Kristian Nielsen
Description:
There is a bug introduced in 5.1 in this changeset:

    brian@zim.(none)|ChangeSet|20070124183405|20201

Valgrind says this:

VALGRIND: 'Syscall param read(count) contains uninitialised byte(s)'
    COUNT: 1
    FUNCTION: (within    FILES:    master.err
    TESTS:    partition
    STACK: at 0x4D49F4B: (within /lib64/libpthread-2.4.so)
             by 0x99E417: my_read (my_read.c:47)
             by 0x7E03E3: ha_archive::create(char const*, st_table*, st_ha_create_information*) (ha_archive.cc:661)
             by 0x70DB4E: ha_partition::del_ren_cre_table(char const*, char const*, st_table*, st_ha_create_information*) (ha_partition.cc:1686)
             by 0x70DD2D: ha_partition::create(char const*, st_table*, st_ha_create_information*) (ha_partition.cc:557)
             by 0x702709: ha_create_table(THD*, char const*, char const*, char const*, st_ha_create_information*, bool) (handler.cc:2610)
             by 0x6DD7A4: rea_create_table(THD*, char const*, char const*, char const*, st_ha_create_information*, List<create_field>&, unsigned, st_key*, handler*) (unireg.cc:361)
             by 0x753D57: mysql_create_table_internal(THD*, char const*, char const*, st_ha_create_information*, List<create_field>&, List<Key>&, bool, unsigned, bool) (sql_table.cc:3509)
             by 0x754245: mysql_create_table(THD*, char const*, char const*, st_ha_create_information*, List<create_field>&, List<Key>&, bool, unsigned, bool) (sql_table.cc:3589)
             by 0x634274: mysql_execute_command(THD*) (sql_parse.cc:3091)
             by 0x634FB5: mysql_parse(THD*, char*, unsigned) (sql_parse.cc:6162)
             by 0x635F21: dispatch_command(enum_server_command, THD*, char*, unsigned) (sql_parse.cc:1857)
             by 0x6372BC: do_command(THD*) (sql_parse.cc:1626)
             by 0x637EFC: handle_one_connection (sql_parse.cc:1232)
             by 0x4D44192: start_thread (in /lib64/libpthread-2.4.so)
             by 0x52B745C: clone (in /lib64/libc-2.4.so)

VALGRIND: 'Syscall param pwrite64(count) contains uninitialised byte(s)'
    COUNT: 1
    FUNCTION: (within    FILES:    master.err
    TESTS:    partition
    STACK: at 0x4D4AB58: (within /lib64/libpthread-2.4.so)
             by 0x99E623: my_pwrite (my_pread.c:149)
             by 0x7E39DC: azwrite_frm (azio.c:817)
             by 0x7E03F7: ha_archive::create(char const*, st_table*, st_ha_create_information*) (ha_archive.cc:662)
             by 0x70DB4E: ha_partition::del_ren_cre_table(char const*, char const*, st_table*, st_ha_create_information*) (ha_partition.cc:1686)
             by 0x70DD2D: ha_partition::create(char const*, st_table*, st_ha_create_information*) (ha_partition.cc:557)
             by 0x702709: ha_create_table(THD*, char const*, char const*, char const*, st_ha_create_information*, bool) (handler.cc:2610)
             by 0x6DD7A4: rea_create_table(THD*, char const*, char const*, char const*, st_ha_create_information*, List<create_field>&, unsigned, st_key*, handler*) (unireg.cc:361)
             by 0x753D57: mysql_create_table_internal(THD*, char const*, char const*, st_ha_create_information*, List<create_field>&, List<Key>&, bool, unsigned, bool) (sql_table.cc:3509)
             by 0x754245: mysql_create_table(THD*, char const*, char const*, st_ha_create_information*, List<create_field>&, List<Key>&, bool, unsigned, bool) (sql_table.cc:3589)
             by 0x634274: mysql_execute_command(THD*) (sql_parse.cc:3091)
             by 0x634FB5: mysql_parse(THD*, char*, unsigned) (sql_parse.cc:6162)
             by 0x635F21: dispatch_command(enum_server_command, THD*, char*, unsigned) (sql_parse.cc:1857)
             by 0x6372BC: do_command(THD*) (sql_parse.cc:1626)
             by 0x637EFC: handle_one_connection (sql_parse.cc:1232)
             by 0x4D44192: start_thread (in /lib64/libpthread-2.4.so)

and so on...

This is the relevant part of the changeset diff where the problem is reported

diff -Nru a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
--- a/storage/archive/ha_archive.cc	2007-01-24 21:01:42 +01:00
+++ b/storage/archive/ha_archive.cc	2007-01-24 21:01:42 +01:00

+    frm_file= my_open(name_buff, O_RDONLY, MYF(0));
+    VOID(my_fstat(frm_file, &file_stat, MYF(MY_WME)));
+    frm_ptr= (char *)my_malloc(sizeof(char) * file_stat.st_size , MYF(0));
+    my_read(frm_file, frm_ptr, file_stat.st_size, MYF(0));
+    azwrite_frm(&create_stream, frm_ptr, file_stat.st_size);
+    my_close(frm_file, MYF(0));
+    my_free(frm_ptr, MYF(0));

Note the missing error check of my_fstat(). Probably fstat() fails, causing file_stat to not be initialised? No error check on my_open() either.

How to repeat:
mysql-test-run.pl --valgrind partition.

Suggested fix:
open() and fstat() needs error check, so we don't pass random data to read() and write(). And maybe fix root cause of fstat() failure.