diff --git a/NEWS b/NEWS index 8fcd7df8..9c73c2e8 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,7 @@ NEWS * add comments for switch fall throughs * remove logical dead code * [buffer] fix length check in buffer_is_equal_right_len + * fix resource leaks in error cases on config parsing and other initializations - 1.4.34 * [mod_auth] explicitly link ssl for SHA1 (fixes #2517) diff --git a/src/configfile.c b/src/configfile.c index 51c7d0a8..1b788a84 100644 --- a/src/configfile.c +++ b/src/configfile.c @@ -1133,6 +1133,8 @@ int config_read(server *srv, const char *fn) { dcwd->value->used = strlen(dcwd->value->ptr) + 1; buffer_copy_string_len(dcwd->key, CONST_STR_LEN("var.CWD")); array_insert_unique(srv->config, (data_unset *)dcwd); + } else { + dcwd->free((data_unset*) dcwd); } ret = config_parse_file(srv, &context, fn); diff --git a/src/mod_fastcgi.c b/src/mod_fastcgi.c index 0e155531..1a70da96 100644 --- a/src/mod_fastcgi.c +++ b/src/mod_fastcgi.c @@ -1164,6 +1164,7 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) { data_unset *du; size_t i = 0; buffer *fcgi_mode = buffer_init(); + fcgi_extension_host *host = NULL; config_values_t cv[] = { { "fastcgi.server", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ @@ -1191,7 +1192,7 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) { ca = ((data_config *)srv->config_context->data[i])->value; if (0 != config_insert_values_global(srv, ca, cv)) { - return HANDLER_ERROR; + goto error; } /* @@ -1206,7 +1207,7 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) { log_error_write(srv, __FILE__, __LINE__, "sss", "unexpected type for key: ", "fastcgi.server", "array of strings"); - return HANDLER_ERROR; + goto error; } @@ -1224,7 +1225,7 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) { "unexpected type for key: ", "fastcgi.server", "[", da->value->data[j]->key, "](string)"); - return HANDLER_ERROR; + goto error; } /* @@ -1242,8 +1243,6 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) { for (n = 0; n < da_ext->value->used; n++) { data_array *da_host = (data_array *)da_ext->value->data[n]; - fcgi_extension_host *host; - config_values_t fcv[] = { { "host", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ { "docroot", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ @@ -1274,7 +1273,7 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) { "fastcgi.server", "[", da_host->key, "](string)"); - return HANDLER_ERROR; + goto error; } host = fastcgi_host_init(); @@ -1311,7 +1310,7 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) { fcv[15].destination = &(host->fix_root_path_name); if (0 != config_insert_values_internal(srv, da_host->value, fcv)) { - return HANDLER_ERROR; + goto error; } if ((!buffer_is_empty(host->host) || host->port) && @@ -1322,7 +1321,7 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) { da_ext->key, " => (", da_host->key, " ( ..."); - return HANDLER_ERROR; + goto error; } if (!buffer_is_empty(host->unixsocket)) { @@ -1336,7 +1335,7 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) { da_ext->key, " => (", da_host->key, " ( ..."); - return HANDLER_ERROR; + goto error; } } else { /* tcp/ip */ @@ -1349,7 +1348,7 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) { da_ext->key, " => (", da_host->key, " ( ..."); - return HANDLER_ERROR; + goto error; } else if (host->port == 0) { log_error_write(srv, __FILE__, __LINE__, "sbsbsbs", "port has to be set in:", @@ -1357,7 +1356,7 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) { da_ext->key, " => (", da_host->key, " ( ..."); - return HANDLER_ERROR; + goto error; } } @@ -1400,13 +1399,14 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) { if (fcgi_spawn_connection(srv, p, host, proc)) { log_error_write(srv, __FILE__, __LINE__, "s", "[ERROR]: spawning fcgi failed."); - return HANDLER_ERROR; + fastcgi_process_free(proc); + goto error; } fastcgi_status_init(srv, p->statuskey, host, proc); proc->next = host->first; - if (host->first) host->first->prev = proc; + if (host->first) host->first->prev = proc; host->first = proc; } @@ -1440,7 +1440,7 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) { if (buffer_is_empty(host->docroot)) { log_error_write(srv, __FILE__, __LINE__, "s", "ERROR: docroot is required for authorizer mode."); - return HANDLER_ERROR; + goto error; } } else { log_error_write(srv, __FILE__, __LINE__, "sbs", @@ -1451,14 +1451,19 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) { /* if extension already exists, take it */ fastcgi_extension_insert(s->exts, da_ext->key, host); + host = NULL; } } } } buffer_free(fcgi_mode); - return HANDLER_GO_ON; + +error: + if (NULL != host) fastcgi_host_free(host); + buffer_free(fcgi_mode); + return HANDLER_ERROR; } static int fcgi_set_state(server *srv, handler_ctx *hctx, fcgi_connection_state_t state) { diff --git a/src/mod_proxy.c b/src/mod_proxy.c index 2e867eb3..d57c33cb 100644 --- a/src/mod_proxy.c +++ b/src/mod_proxy.c @@ -298,6 +298,7 @@ SETDEFAULTS_FUNC(mod_proxy_set_defaults) { pcv[1].destination = &(df->port); if (0 != config_insert_values_internal(srv, da_host->value, pcv)) { + df->free((data_unset*) df); return HANDLER_ERROR; } @@ -309,6 +310,7 @@ SETDEFAULTS_FUNC(mod_proxy_set_defaults) { da_host->key, "host"); + df->free((data_unset*) df); return HANDLER_ERROR; } diff --git a/src/mod_scgi.c b/src/mod_scgi.c index fe280a1e..d1ab78bf 100644 --- a/src/mod_scgi.c +++ b/src/mod_scgi.c @@ -921,6 +921,7 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) { plugin_data *p = p_d; data_unset *du; size_t i = 0; + scgi_extension_host *df = NULL; config_values_t cv[] = { { "scgi.server", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ @@ -996,8 +997,6 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) { for (n = 0; n < da_ext->value->used; n++) { data_array *da_host = (data_array *)da_ext->value->data[n]; - scgi_extension_host *df; - config_values_t fcv[] = { { "host", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ { "docroot", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ @@ -1058,7 +1057,7 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) { if (0 != config_insert_values_internal(srv, da_host->value, fcv)) { - return HANDLER_ERROR; + goto error; } if ((!buffer_is_empty(df->host) || df->port) && @@ -1066,7 +1065,7 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) { log_error_write(srv, __FILE__, __LINE__, "s", "either host+port or socket"); - return HANDLER_ERROR; + goto error; } if (!buffer_is_empty(df->unixsocket)) { @@ -1076,7 +1075,7 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) { if (df->unixsocket->used > sizeof(un.sun_path) - 2) { log_error_write(srv, __FILE__, __LINE__, "s", "path of the unixdomain socket is too large"); - return HANDLER_ERROR; + goto error; } } else { /* tcp/ip */ @@ -1090,7 +1089,7 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) { da_host->key, "host"); - return HANDLER_ERROR; + goto error; } else if (df->port == 0) { log_error_write(srv, __FILE__, __LINE__, "sbbbs", "missing key (short):", @@ -1098,7 +1097,7 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) { da_ext->key, da_host->key, "port"); - return HANDLER_ERROR; + goto error; } } @@ -1148,7 +1147,8 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) { if (scgi_spawn_connection(srv, p, df, proc)) { log_error_write(srv, __FILE__, __LINE__, "s", "[ERROR]: spawning fcgi failed."); - return HANDLER_ERROR; + scgi_process_free(proc); + goto error; } proc->next = df->first; @@ -1179,12 +1179,17 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) { /* if extension already exists, take it */ scgi_extension_insert(s->exts, da_ext->key, df); + df = NULL; } } } } return HANDLER_GO_ON; + +error: + if (NULL != df) scgi_host_free(df); + return HANDLER_ERROR; } static int scgi_set_state(server *srv, handler_ctx *hctx, scgi_connection_state_t state) { diff --git a/src/network.c b/src/network.c index a56319f0..93764848 100644 --- a/src/network.c +++ b/src/network.c @@ -925,6 +925,7 @@ int network_init(server *srv) { buffer_append_long(b, srv->srvconf.port); if (0 != network_server_init(srv, b, srv->config_storage[0])) { + buffer_free(b); return -1; } buffer_free(b);