1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

MDEV-33783 CREATE SERVER segfaults on wrong mysql.servers

Do basic checking of mysql.servers compatibility.
This commit is contained in:
Aleksey Midenkov
2024-12-03 13:49:43 +03:00
parent 27c25ceedb
commit 13f93da1f6
3 changed files with 80 additions and 26 deletions

View File

@ -462,7 +462,7 @@ get_server_from_table_to_cache(TABLE *table)
RETURN VALUES
0 - no error
other - error code
other - ER_ error code
*/
static int
@ -546,15 +546,19 @@ insert_server_record_into_cache(FOREIGN_SERVER *server)
advance of insertion into the mysql.servers table
RETURN VALUE
VOID
0 - no errors
>0 - ER_ error code
*/
static void
static int
store_server_fields(TABLE *table, FOREIGN_SERVER *server)
{
table->use_all_columns();
if (table->s->fields < 9)
return ER_CANT_FIND_SYSTEM_REC;
/*
"server" has already been prepped by prepare_server_struct_for_<>
so, all we need to do is check if the value is set (> -1 for port)
@ -563,30 +567,43 @@ store_server_fields(TABLE *table, FOREIGN_SERVER *server)
have changed will be set. If an insert, then all will be set,
even if with empty strings
*/
if (server->host)
if (server->host &&
table->field[1]->store(server->host,
(uint) strlen(server->host), system_charset_info);
if (server->db)
(uint) strlen(server->host), system_charset_info))
goto err;
if (server->db &&
table->field[2]->store(server->db,
(uint) strlen(server->db), system_charset_info);
if (server->username)
(uint) strlen(server->db), system_charset_info))
goto err;
if (server->username &&
table->field[3]->store(server->username,
(uint) strlen(server->username), system_charset_info);
if (server->password)
(uint) strlen(server->username), system_charset_info))
goto err;
if (server->password &&
table->field[4]->store(server->password,
(uint) strlen(server->password), system_charset_info);
if (server->port > -1)
table->field[5]->store(server->port);
if (server->socket)
(uint) strlen(server->password), system_charset_info))
goto err;
if (server->port > -1 &&
table->field[5]->store(server->port))
goto err;
if (server->socket &&
table->field[6]->store(server->socket,
(uint) strlen(server->socket), system_charset_info);
if (server->scheme)
(uint) strlen(server->socket), system_charset_info))
goto err;
if (server->scheme &&
table->field[7]->store(server->scheme,
(uint) strlen(server->scheme), system_charset_info);
if (server->owner)
(uint) strlen(server->scheme), system_charset_info))
goto err;
if (server->owner &&
table->field[8]->store(server->owner,
(uint) strlen(server->owner), system_charset_info);
(uint) strlen(server->owner), system_charset_info))
goto err;
return 0;
err:
THD *thd= table->in_use;
DBUG_ASSERT(thd->is_error());
return thd->get_stmt_da()->get_sql_errno();
}
/*
@ -608,7 +625,7 @@ store_server_fields(TABLE *table, FOREIGN_SERVER *server)
RETURN VALUE
0 - no errors
>0 - error code
>0 - ER_ error code
*/
@ -642,7 +659,8 @@ int insert_server_record(TABLE *table, FOREIGN_SERVER *server)
error= 1;
}
/* store each field to be inserted */
store_server_fields(table, server);
if ((error= store_server_fields(table, server)))
DBUG_RETURN(error);
DBUG_PRINT("info",("record for server '%s' not found!",
server->server_name));
@ -972,9 +990,15 @@ update_server_record(TABLE *table, FOREIGN_SERVER *server)
table->use_all_columns();
/* set the field that's the PK to the value we're looking for */
table->field[0]->store(server->server_name,
if (table->field[0]->store(server->server_name,
server->server_name_length,
system_charset_info);
system_charset_info))
{
DBUG_ASSERT(0); /* Protected by servers_cache */
THD *thd= table->in_use;
DBUG_ASSERT(thd->is_error());
return thd->get_stmt_da()->get_sql_errno();
}
if (unlikely((error=
table->file->ha_index_read_idx_map(table->record[0], 0,
@ -992,7 +1016,8 @@ update_server_record(TABLE *table, FOREIGN_SERVER *server)
{
/* ok, so we can update since the record exists in the table */
store_record(table,record[1]);
store_server_fields(table, server);
if ((error= store_server_fields(table, server)))
goto end;
if (unlikely((error=table->file->ha_update_row(table->record[1],
table->record[0])) &&
error != HA_ERR_RECORD_IS_THE_SAME))