MXS-2274 Prevent dynamic creation of object with invalid name

Unfortunately there is not a single place where the name could be
validated, but it has to be done separately for each object type.
This commit is contained in:
Johan Wikman
2019-01-24 12:54:08 +02:00
parent 5afceb1185
commit 7d92717b66
2 changed files with 90 additions and 53 deletions

View File

@ -210,59 +210,68 @@ bool runtime_create_server(const char* name,
const char* port, const char* port,
const char* protocol, const char* protocol,
const char* authenticator, const char* authenticator,
bool serialize) bool external)
{ {
std::lock_guard<std::mutex> guard(crt_lock); std::lock_guard<std::mutex> guard(crt_lock);
bool rval = false; bool rval = false;
if (Server::find_by_unique_name(name) == NULL) if (Server::find_by_unique_name(name) == NULL)
{ {
if (protocol == NULL) std::string reason;
if (!external || config_is_valid_name(name, &reason))
{ {
protocol = "mariadbbackend"; if (protocol == NULL)
}
CONFIG_CONTEXT ctx {(char*)""};
bool ok;
tie(ok, ctx.parameters) = load_defaults(protocol, MODULE_PROTOCOL, CN_SERVER);
if (ok)
{
config_replace_param(&ctx, CN_PROTOCOL, protocol);
if (address)
{ {
config_replace_param(&ctx, "address", address); protocol = "mariadbbackend";
}
if (port)
{
config_replace_param(&ctx, "port", port);
}
if (authenticator)
{
config_replace_param(&ctx, "authenticator", authenticator);
} }
Server* server = Server::server_alloc(name, ctx.parameters); CONFIG_CONTEXT ctx {(char*)""};
bool ok;
tie(ok, ctx.parameters) = load_defaults(protocol, MODULE_PROTOCOL, CN_SERVER);
if (server && (!serialize || server->serialize())) if (ok)
{ {
rval = true; config_replace_param(&ctx, CN_PROTOCOL, protocol);
MXS_NOTICE("Created server '%s' at %s:%u",
server->name(), if (address)
server->address, {
server->port); config_replace_param(&ctx, "address", address);
}
if (port)
{
config_replace_param(&ctx, "port", port);
}
if (authenticator)
{
config_replace_param(&ctx, "authenticator", authenticator);
}
Server* server = Server::server_alloc(name, ctx.parameters);
if (server && (!external || server->serialize()))
{
rval = true;
MXS_NOTICE("Created server '%s' at %s:%u",
server->name(),
server->address,
server->port);
}
else
{
config_runtime_error("Failed to create server '%s', see error log for more details",
name);
}
config_parameter_free(ctx.parameters);
} }
else else
{ {
config_runtime_error("Failed to create server '%s', see error log for more details", name); config_runtime_error("Server creation failed when loading protocol module '%s'", protocol);
} }
config_parameter_free(ctx.parameters);
} }
else else
{ {
config_runtime_error("Server creation failed when loading protocol module '%s'", protocol); config_runtime_error("%s", reason.c_str());
} }
} }
else else
@ -1071,6 +1080,7 @@ bool runtime_create_listener(Service* service,
bool rval = false; bool rval = false;
std::lock_guard<std::mutex> guard(crt_lock); std::lock_guard<std::mutex> guard(crt_lock);
std::string reason;
if (listener_find(name)) if (listener_find(name))
{ {
@ -1080,7 +1090,7 @@ bool runtime_create_listener(Service* service,
{ {
config_runtime_error("Listener '%s' already listens on [%s]:%u", l->name(), addr, u_port); config_runtime_error("Listener '%s' already listens on [%s]:%u", l->name(), addr, u_port);
} }
else else if (config_is_valid_name(name, &reason))
{ {
SSL_LISTENER* ssl = NULL; SSL_LISTENER* ssl = NULL;
@ -1126,6 +1136,10 @@ bool runtime_create_listener(Service* service,
} }
} }
} }
else
{
config_runtime_error("%s", reason.c_str());
}
return rval; return rval;
} }
@ -1180,14 +1194,14 @@ bool runtime_create_monitor(const char* name, const char* module)
if (monitor_find(name) == NULL) if (monitor_find(name) == NULL)
{ {
Monitor* monitor = monitor_repurpose_destroyed(name, module); Monitor* monitor = monitor_repurpose_destroyed(name, module);
std::string reason;
if (monitor) if (monitor)
{ {
MXS_DEBUG("Repurposed monitor '%s'", name); MXS_DEBUG("Repurposed monitor '%s'", name);
} }
else else if (config_is_valid_name(name, &reason))
{ {
MXS_CONFIG_PARAMETER* params; MXS_CONFIG_PARAMETER* params;
bool ok; bool ok;
@ -1203,6 +1217,10 @@ bool runtime_create_monitor(const char* name, const char* module)
config_parameter_free(params); config_parameter_free(params);
} }
} }
else
{
config_runtime_error("%s", reason.c_str());
}
if (monitor) if (monitor)
{ {
@ -1239,17 +1257,26 @@ bool runtime_create_filter(const char* name, const char* module, MXS_CONFIG_PARA
if (ok) if (ok)
{ {
for (MXS_CONFIG_PARAMETER* p = params; p; p = p->next) std::string reason;
{
config_replace_param(&ctx, p->name, p->value);
}
if (!(filter = filter_alloc(name, module, ctx.parameters))) if (config_is_valid_name(name, &reason))
{ {
config_runtime_error("Could not create filter '%s' with module '%s'", name, module); for (MXS_CONFIG_PARAMETER* p = params; p; p = p->next)
} {
config_replace_param(&ctx, p->name, p->value);
}
config_parameter_free(ctx.parameters); if (!(filter = filter_alloc(name, module, ctx.parameters)))
{
config_runtime_error("Could not create filter '%s' with module '%s'", name, module);
}
config_parameter_free(ctx.parameters);
}
else
{
config_runtime_error("%s", reason.c_str());
}
} }
if (filter) if (filter)
@ -1308,17 +1335,25 @@ static bool runtime_create_service(const char* name, const char* router, MXS_CON
if (ok) if (ok)
{ {
for (MXS_CONFIG_PARAMETER* p = params; p; p = p->next) std::string reason;
if (config_is_valid_name(name, &reason))
{ {
config_replace_param(&ctx, p->name, p->value); for (MXS_CONFIG_PARAMETER* p = params; p; p = p->next)
} {
config_replace_param(&ctx, p->name, p->value);
}
if ((service = service_alloc(name, router, ctx.parameters)) == NULL) if ((service = service_alloc(name, router, ctx.parameters)) == NULL)
{
config_runtime_error("Could not create service '%s' with module '%s'", name, router);
}
config_parameter_free(ctx.parameters);
}
else
{ {
config_runtime_error("Could not create service '%s' with module '%s'", name, router); config_runtime_error("%s", reason.c_str());
} }
config_parameter_free(ctx.parameters);
} }
if (service) if (service)

View File

@ -51,6 +51,8 @@ void config_runtime_error(const char* fmt, ...) mxs_attribute((format (printf, 1
* @param port Network port * @param port Network port
* @param protocol Protocol module name * @param protocol Protocol module name
* @param authenticator Authenticator module name * @param authenticator Authenticator module name
* @param external If true, the name will be validated and the created server
* serialized.
* @return True on success, false if an error occurred * @return True on success, false if an error occurred
*/ */
bool runtime_create_server(const char* name, bool runtime_create_server(const char* name,
@ -58,7 +60,7 @@ bool runtime_create_server(const char* name,
const char* port, const char* port,
const char* protocol, const char* protocol,
const char* authenticator, const char* authenticator,
bool serialize = true); bool external = true);
/** /**
* @brief Destroy a server * @brief Destroy a server