summaryrefslogtreecommitdiff
path: root/sql/sql_servers.cc
diff options
context:
space:
mode:
authorunknown <svoj@mysql.com/june.mysql.com>2008-03-20 11:40:26 +0400
committerunknown <svoj@mysql.com/june.mysql.com>2008-03-20 11:40:26 +0400
commite023ad1a837c87c21c42d9a6fc219b4df7266fe9 (patch)
tree73b45a1bdbdf604baae026af826bd588178760a3 /sql/sql_servers.cc
parent34be40168db4c469afcfb9400332f69092b1c4b2 (diff)
downloadmariadb-git-e023ad1a837c87c21c42d9a6fc219b4df7266fe9.tar.gz
BUG#34790 - 'create server' doesn't handle out of memory scenario
well enough CREATE SERVER may cause server crash if there is not enough memory to execute this operation. Fixed that create_server() and prepare_server_struct_for_insert() didn't check return value of functions that allocate memory. As this is out of memory issue fix, not test case available. sql/sql_servers.cc: Fixed that create_server() and prepare_server_struct_for_insert() didn't check return value of functions that allocate memory.
Diffstat (limited to 'sql/sql_servers.cc')
-rw-r--r--sql/sql_servers.cc68
1 files changed, 42 insertions, 26 deletions
diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc
index 8203ca92eed..6255901d782 100644
--- a/sql/sql_servers.cc
+++ b/sql/sql_servers.cc
@@ -55,8 +55,8 @@ static bool get_server_from_table_to_cache(TABLE *table);
static int insert_server(THD *thd, FOREIGN_SERVER *server_options);
static int insert_server_record(TABLE *table, FOREIGN_SERVER *server);
static int insert_server_record_into_cache(FOREIGN_SERVER *server);
-static void prepare_server_struct_for_insert(LEX_SERVER_OPTIONS *server_options,
- FOREIGN_SERVER *server);
+static FOREIGN_SERVER *
+prepare_server_struct_for_insert(LEX_SERVER_OPTIONS *server_options);
/* drop functions */
static int delete_server_record(TABLE *table,
char *server_name,
@@ -966,10 +966,14 @@ int create_server(THD *thd, LEX_SERVER_OPTIONS *server_options)
server_options->server_name_length))
goto end;
- server= (FOREIGN_SERVER *)alloc_root(&mem,
- sizeof(FOREIGN_SERVER));
- prepare_server_struct_for_insert(server_options, server);
+ if (!(server= prepare_server_struct_for_insert(server_options)))
+ {
+ /* purecov: begin inspected */
+ error= ER_OUT_OF_RESOURCES;
+ goto end;
+ /* purecov: end */
+ }
error= insert_server(thd, server);
@@ -1040,52 +1044,64 @@ end:
SYNOPSIS
prepare_server_struct_for_insert()
LEX_SERVER_OPTIONS *server_options
- FOREIGN_SERVER *server
NOTES
+ As FOREIGN_SERVER members are allocated on mem_root, we do not need to
+ free them in case of error.
RETURN VALUE
- none
+ On success filled FOREIGN_SERVER, or NULL in case out of memory.
*/
-static void
-prepare_server_struct_for_insert(LEX_SERVER_OPTIONS *server_options,
- FOREIGN_SERVER *server)
+static FOREIGN_SERVER *
+prepare_server_struct_for_insert(LEX_SERVER_OPTIONS *server_options)
{
char *unset_ptr= (char*)"";
+ FOREIGN_SERVER *server;
DBUG_ENTER("prepare_server_struct");
+ if (!(server= (FOREIGN_SERVER *)alloc_root(&mem, sizeof(FOREIGN_SERVER))))
+ DBUG_RETURN(NULL); /* purecov: inspected */
+
/* these two MUST be set */
- server->server_name= strdup_root(&mem, server_options->server_name);
+ if (!(server->server_name= strdup_root(&mem, server_options->server_name)))
+ DBUG_RETURN(NULL); /* purecov: inspected */
server->server_name_length= server_options->server_name_length;
- server->host= server_options->host ?
- strdup_root(&mem, server_options->host) : unset_ptr;
+ if (!(server->host= server_options->host ?
+ strdup_root(&mem, server_options->host) : unset_ptr))
+ DBUG_RETURN(NULL); /* purecov: inspected */
- server->db= server_options->db ?
- strdup_root(&mem, server_options->db) : unset_ptr;
+ if (!(server->db= server_options->db ?
+ strdup_root(&mem, server_options->db) : unset_ptr))
+ DBUG_RETURN(NULL); /* purecov: inspected */
- server->username= server_options->username ?
- strdup_root(&mem, server_options->username) : unset_ptr;
+ if (!(server->username= server_options->username ?
+ strdup_root(&mem, server_options->username) : unset_ptr))
+ DBUG_RETURN(NULL); /* purecov: inspected */
- server->password= server_options->password ?
- strdup_root(&mem, server_options->password) : unset_ptr;
+ if (!(server->password= server_options->password ?
+ strdup_root(&mem, server_options->password) : unset_ptr))
+ DBUG_RETURN(NULL); /* purecov: inspected */
/* set to 0 if not specified */
server->port= server_options->port > -1 ?
server_options->port : 0;
- server->socket= server_options->socket ?
- strdup_root(&mem, server_options->socket) : unset_ptr;
+ if (!(server->socket= server_options->socket ?
+ strdup_root(&mem, server_options->socket) : unset_ptr))
+ DBUG_RETURN(NULL); /* purecov: inspected */
- server->scheme= server_options->scheme ?
- strdup_root(&mem, server_options->scheme) : unset_ptr;
+ if (!(server->scheme= server_options->scheme ?
+ strdup_root(&mem, server_options->scheme) : unset_ptr))
+ DBUG_RETURN(NULL); /* purecov: inspected */
- server->owner= server_options->owner ?
- strdup_root(&mem, server_options->owner) : unset_ptr;
+ if (!(server->owner= server_options->owner ?
+ strdup_root(&mem, server_options->owner) : unset_ptr))
+ DBUG_RETURN(NULL); /* purecov: inspected */
- DBUG_VOID_RETURN;
+ DBUG_RETURN(server);
}
/*