[MDEV-9346] [PATCH] The federatedx and spider engine make mysqld crash when they are configured withtout username Created: 2015-12-30  Updated: 2016-02-16  Resolved: 2016-02-16

Status: Closed
Project: MariaDB Server
Component/s: Storage Engine - Federated, Storage Engine - Spider
Affects Version/s: 10.0, 10.1
Fix Version/s: 10.0.24, 10.1.12

Type: Bug Priority: Major
Reporter: chengxiaoz Assignee: Sergey Vojtovich
Resolution: Fixed Votes: 0
Labels: None
Environment:

windows centos



 Description   

When I use the federatedx and spider engine, on one occasion user name is omitted in connection information and it make mysqld crash.
For example, a remote server is runing on 192.168.217.1 and port is 3310.

    case 1
    create table s1(A int) ENGINE = SPIDER CONNECTION 'host "192.168.217.1", port "3310", database "test", table "t1"';
    select * from s1;
    ERROR 2013 (HY000): Lost connection to MySQL server during query   <--  Lost Connection Because Server Crashed
    case 2
    create table fedx1(A int) ENGINE=FEDERATED    CONNECTION='mysql://:123456@192.168.217.1:3310/db1/fed';
    ERROR 2013 (HY000): Lost connection to MySQL server during query
    case 3
    CREATE SERVER serv1 
      FOREIGN DATA WRAPPER mysql 
    OPTIONS( 
    HOST '192.168.217.1',
    PORT 3310,
    DATABASE 'DB1'
    );
    create table fedx2(A int) ENGINE=FEDERATED CONNECTION='serv1/fed';
    ERROR 2013 (HY000): Lost connection to MySQL server during query

The spider/federatedx engine and client program both use libmysql to connect to server, and both pass NULL as username to mysql_real_connect, while the client program will not crash in such condition. This makes me confused.

The problem trace back to send_client_reply_packet function called by mysql_real_connect.
In the following code snippet, user name ( NUL terminated string) is copied to the buffer(pointed by end), then strend() function find new end of buffer assuming end pointer point to a NUL terminated string.

  /* This needs to be changed as it's not useful with big packets */
  if (mysql->user[0])
    strmake(end, mysql->user, USERNAME_LENGTH);
  else
    read_user_name(end);
 
  /* We have to handle different version of handshake here */
  DBUG_PRINT("info",("user: %s",end));
  end= strend(end) + 1;

The read_user_name function is called when user name is null. It give a value to user name and copy the the value in client (libmysql.c), while it is defined empty in server(client_settings.h)
#define read_user_name(A) {}.
So strend will access uninitialized buffer, and will make server crash under some condition.

It may be reasonable that a user name value is given in read_user_name() in server code.
https://github.com/MariaDB/server/pull/138



 Comments   
Comment by Elena Stepanova [ 2016-01-10 ]

I am not getting the actual crash, but since svoj is okay with the patch (as it appears from the comments to the pull request), I am assigning it to him.

Comment by chengxiaoz [ 2016-01-18 ]

Hi Elena Stepanova
The Server will be crashed every time under windows in debug mode, because memory allocated is filled with 0xcc.
The behavior is undefined under linux.

Comment by Sergey Vojtovich [ 2016-02-16 ]

Reproduced with valgrind:

==27070== Thread 5:
==27070== Conditional jump or move depends on uninitialised value(s)
==27070==    at 0xEE5E50: strend (strend.c:45)
==27070==    by 0x82649E: send_client_reply_packet (client.c:2598)
==27070==    by 0x826915: client_mpvio_write_packet (client.c:2736)
==27070==    by 0x82BF59: native_password_auth_client (client.c:4673)
==27070==    by 0x826DA1: run_plugin_auth (client.c:2872)
==27070==    by 0x828C07: mysql_real_connect (client.c:3536)
==27070==    by 0xD43DA84: federatedx_io_mysql::actual_query(char const*, unsigned int) (federatedx_io_mysql.cc:443)
==27070==    by 0xD43D89F: federatedx_io_mysql::query(char const*, unsigned int) (federatedx_io_mysql.cc:414)
==27070==    by 0xD438198: test_connection(THD*, federatedx_io*, st_federatedx_share*) (ha_federatedx.cc:3332)
==27070==    by 0xD4385A6: ha_federatedx::create(char const*, TABLE*, HA_CREATE_INFO*) (ha_federatedx.cc:3403)
==27070==    by 0x867B5B: handler::ha_create(char const*, TABLE*, HA_CREATE_INFO*) (handler.cc:4328)
==27070==    by 0x868A8E: ha_create_table(THD*, char const*, char const*, char const*, HA_CREATE_INFO*, st_mysql_const_unsigned_lex_string*) (handler.cc:4697)
==27070==    by 0x758452: rea_create_table(THD*, st_mysql_const_unsigned_lex_string*, char const*, char const*, char const*, HA_CREATE_INFO*, handler*, bool) (unireg.cc:378)
==27070==    by 0x70ECBF: create_table_impl(THD*, char const*, char const*, char const*, char const*, char const*, HA_CREATE_INFO*, Alter_info*, int, bool*, st_key**, unsigned int*, st_mysql_const_unsigned_lex_string*) (sql_table.cc:4826)
==27070==    by 0x70F262: mysql_create_table_no_lock(THD*, char const*, char const*, HA_CREATE_INFO*, Alter_info*, bool*, int) (sql_table.cc:4941)
==27070==    by 0x70F506: mysql_create_table(THD*, TABLE_LIST*, HA_CREATE_INFO*, Alter_info*) (sql_table.cc:5001)
==27070== Syscall param socketcall.sendto(msg) points to uninitialised byte(s)
==27070==    at 0x5C752EF: send (send.c:31)
==27070==    by 0xEE862A: inline_mysql_socket_send (mysql_socket.h:759)
==27070==    by 0xEE92ED: vio_write (viosocket.c:279)
==27070==    by 0x599A5B: net_real_write (net_serv.cc:659)
==27070==    by 0x599154: net_flush (net_serv.cc:362)
==27070==    by 0x82671B: send_client_reply_packet (client.c:2640)
==27070==    by 0x826915: client_mpvio_write_packet (client.c:2736)
==27070==    by 0x82BF59: native_password_auth_client (client.c:4673)
==27070==    by 0x826DA1: run_plugin_auth (client.c:2872)
==27070==    by 0x828C07: mysql_real_connect (client.c:3536)
==27070==    by 0xD43DA84: federatedx_io_mysql::actual_query(char const*, unsigned int) (federatedx_io_mysql.cc:443)
==27070==    by 0xD43D89F: federatedx_io_mysql::query(char const*, unsigned int) (federatedx_io_mysql.cc:414)
==27070==    by 0xD438198: test_connection(THD*, federatedx_io*, st_federatedx_share*) (ha_federatedx.cc:3332)
==27070==    by 0xD4385A6: ha_federatedx::create(char const*, TABLE*, HA_CREATE_INFO*) (ha_federatedx.cc:3403)
==27070==    by 0x867B5B: handler::ha_create(char const*, TABLE*, HA_CREATE_INFO*) (handler.cc:4328)
==27070==    by 0x868A8E: ha_create_table(THD*, char const*, char const*, char const*, HA_CREATE_INFO*, st_mysql_const_unsigned_lex_string*) (handler.cc:4697)
==27070==  Address 0xde67384 is 148 bytes inside a block of size 16,508 alloc'd
==27070==    at 0x4C2BC9F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27070==    by 0xEA4A02: sf_malloc (safemalloc.c:115)
==27070==    by 0xE92E28: my_malloc (my_malloc.c:100)
==27070==    by 0x598C1E: my_net_init (net_serv.cc:132)
==27070==    by 0x828314: mysql_real_connect (client.c:3371)
==27070==    by 0xD43DA84: federatedx_io_mysql::actual_query(char const*, unsigned int) (federatedx_io_mysql.cc:443)
==27070==    by 0xD43D89F: federatedx_io_mysql::query(char const*, unsigned int) (federatedx_io_mysql.cc:414)
==27070==    by 0xD438198: test_connection(THD*, federatedx_io*, st_federatedx_share*) (ha_federatedx.cc:3332)
==27070==    by 0xD4385A6: ha_federatedx::create(char const*, TABLE*, HA_CREATE_INFO*) (ha_federatedx.cc:3403)
==27070==    by 0x867B5B: handler::ha_create(char const*, TABLE*, HA_CREATE_INFO*) (handler.cc:4328)
==27070==    by 0x868A8E: ha_create_table(THD*, char const*, char const*, char const*, HA_CREATE_INFO*, st_mysql_const_unsigned_lex_string*) (handler.cc:4697)
==27070==    by 0x758452: rea_create_table(THD*, st_mysql_const_unsigned_lex_string*, char const*, char const*, char const*, HA_CREATE_INFO*, handler*, bool) (unireg.cc:378)
==27070==    by 0x70ECBF: create_table_impl(THD*, char const*, char const*, char const*, char const*, char const*, HA_CREATE_INFO*, Alter_info*, int, bool*, st_key**, unsigned int*, st_mysql_const_unsigned_lex_string*) (sql_table.cc:4826)
==27070==    by 0x70F262: mysql_create_table_no_lock(THD*, char const*, char const*, HA_CREATE_INFO*, Alter_info*, bool*, int) (sql_table.cc:4941)
==27070==    by 0x70F506: mysql_create_table(THD*, TABLE_LIST*, HA_CREATE_INFO*, Alter_info*) (sql_table.cc:5001)
==27070==    by 0x656240: mysql_execute_command(THD*) (sql_parse.cc:3036)

Generated at Thu Feb 08 07:33:58 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.