Skip to content

Commit

Permalink
MDEV-14647: Fixed crash when client receives extended ok packet with
Browse files Browse the repository at this point in the history
            SESSION_TRACK_STATE_CHANGE information flag.

SESSION_TRACK_STATE_CHANGE flag only contains one length encoded string (length =1) which value is always "1".
  • Loading branch information
9EOR9 committed Dec 15, 2017
1 parent 434b67e commit 6d2fb01
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
21 changes: 20 additions & 1 deletion libmariadb/mariadb_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -2093,7 +2093,6 @@ int mthd_my_read_query_result(MYSQL *mysql)
si_type= (enum enum_session_state_type)net_field_length(&pos);
switch(si_type) {
case SESSION_TRACK_SCHEMA:
case SESSION_TRACK_STATE_CHANGE:
case SESSION_TRACK_TRANSACTION_CHARACTERISTICS:
case SESSION_TRACK_SYSTEM_VARIABLES:
net_field_length(&pos); /* ignore total length, item length will follow next */
Expand Down Expand Up @@ -2156,6 +2155,26 @@ int mthd_my_read_query_result(MYSQL *mysql)
}
}
break;
/* Session track state change flag indicates if session state
tracking was enabled. The flag is represented as "1" */
case SESSION_TRACK_STATE_CHANGE:
plen = net_field_length(&pos);
if (!ma_multi_malloc(0,
&session_item, sizeof(LIST),
&str, sizeof(MYSQL_LEX_STRING),
&data, plen,
NULL))
{
SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
return -1;
}
str->length= plen;
str->str= data;
memcpy(str->str, (char *)pos, plen);
pos+= plen;
session_item->data= str;
mysql->extension->session_state[si_type].list= list_add(mysql->extension->session_state[si_type].list, session_item);
break;
default:
/* not supported yet */
plen= net_field_length(&pos);
Expand Down
37 changes: 37 additions & 0 deletions unittest/libmariadb/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -1398,7 +1398,44 @@ static int test_conc297(MYSQL *my __attribute__((unused)))
return OK;
}

static int test_mdev14647(MYSQL *my __attribute__((unused)))
{
MYSQL *mysql;
int rc;
char *data= "0";
size_t length= 0;
long server_capabilities;

mysql= mysql_init(NULL);
my_test_connect(mysql, hostname, username, password, schema,
port, socketname,
CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS);
FAIL_IF(mysql_errno(mysql), "No error expected");

mariadb_get_infov(mysql, MARIADB_CONNECTION_SERVER_CAPABILITIES, &server_capabilities);

if (!(server_capabilities & CLIENT_SESSION_TRACKING) ||
!mariadb_connection(mysql))
{
diag("Server doesn't support session tracking or doesn't send SESSION_TRACK_STATE_CHANGE information");
mysql_close(mysql);
return SKIP;
}

rc= mysql_query(mysql, "SET SESSION session_track_state_change = 1");
check_mysql_rc(rc, mysql);

rc= mysql_session_track_get_first(mysql, SESSION_TRACK_STATE_CHANGE, (const char **)&data, &length);

FAIL_IF(length != 1, "expected length=1");
FAIL_IF(data[0] != 0x31, "expected 1");

mysql_close(mysql);
return OK;
}

struct my_tests_st my_tests[] = {
{"test_mdev14647", test_mdev14647, TEST_CONNECTION_NONE, 0, NULL, NULL},
{"test_conc297", test_conc297, TEST_CONNECTION_NONE, 0, NULL, NULL},
{"test_conc277", test_conc277, TEST_CONNECTION_NONE, 0, NULL, NULL},
{"test_mdev9059_1", test_mdev9059_1, TEST_CONNECTION_NONE, 0, NULL, NULL},
Expand Down

1 comment on commit 6d2fb01

@ybbct
Copy link

@ybbct ybbct commented on 6d2fb01 Jun 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @9EOR9 when will this fix merge to master, I want contribute some code for mariadb server, which will make use of session tracker, and this bug blocks it;

Please sign in to comment.