sec-mod/main: eliminate mem leaks related to vhost transition

Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
This commit is contained in:
Nikos Mavrogiannopoulos 2018-04-14 14:22:02 +02:00
parent 9af953383e
commit cf8304cadf
7 changed files with 41 additions and 14 deletions

View File

@ -1048,9 +1048,13 @@ static int cfg_ini_handler(void *_ctx, const char *section, const char *name, co
return 0;
}
enum {
CFG_FLAG_RELOAD = (1<<0),
CFG_FLAG_SECMOD = (1<<1)
};
static void parse_cfg_file(void *pool, const char *file, struct list_head *head,
unsigned reload)
unsigned flags)
{
int ret;
struct cfg_st *config;
@ -1060,7 +1064,7 @@ static void parse_cfg_file(void *pool, const char *file, struct list_head *head,
memset(&ctx, 0, sizeof(ctx));
ctx.file = file;
ctx.reload = reload;
ctx.reload = (flags&CFG_FLAG_RELOAD)?1:0;
ctx.head = head;
/* parse configuration
@ -1109,11 +1113,14 @@ static void parse_cfg_file(void *pool, const char *file, struct list_head *head,
defvhost = NULL;
/* this check copies mandatory fields from default vhost if needed */
check_cfg(vhost, defvhost, reload);
check_cfg(vhost, defvhost, ctx.reload);
tls_load_files(NULL, vhost);
tls_load_prio(NULL, vhost);
tls_reload_crl(NULL, vhost, 1);
/* the following are only useful in main process */
if (!(flags & CFG_FLAG_SECMOD)) {
tls_load_files(NULL, vhost);
tls_load_prio(NULL, vhost);
tls_reload_crl(NULL, vhost, 1);
}
#ifdef HAVE_GSSAPI
if (vhost->urlfw_size > 0) {
@ -1550,12 +1557,16 @@ static void print_version(void)
}
void reload_cfg_file(void *pool, struct list_head *configs, unsigned archive)
void reload_cfg_file(void *pool, struct list_head *configs, unsigned sec_mod)
{
struct vhost_cfg_st* vhost = NULL;
unsigned flags = CFG_FLAG_RELOAD;
if (sec_mod)
flags |= CFG_FLAG_SECMOD;
/* Archive or clear any non-permanent configs */
if (archive)
if (!sec_mod)
archive_cfg(configs);
else
clear_cfg(configs);
@ -1567,7 +1578,7 @@ void reload_cfg_file(void *pool, struct list_head *configs, unsigned archive)
}
/* parse the config again */
parse_cfg_file(pool, cfg_file, configs, 1);
parse_cfg_file(pool, cfg_file, configs, flags);
return;
}

View File

@ -675,6 +675,16 @@ void secmod_socket_file_name(struct perm_cfg_st *perm_config, char *name, unsign
perm_config->socket_file_prefix, (unsigned)getpid());
}
static void clear_unneeded_mem(struct list_head *vconfig)
{
vhost_cfg_st *vhost = NULL;
/* deinitialize certificate credentials etc. */
list_for_each_rev(vconfig, vhost, list) {
tls_vhost_deinit(vhost);
}
}
/* Returns two file descriptors to be used for communication with sec-mod.
* The sync_fd is used by main to send synchronous commands- commands which
* expect a reply immediately.
@ -728,6 +738,7 @@ int run_sec_mod(main_server_st *s, int *sync_fd)
close(sfd[1]);
set_cloexec_flag (fd[0], 1);
set_cloexec_flag (sfd[0], 1);
clear_unneeded_mem(s->vconfig);
sec_mod_server(s->main_pool, s->config_pool, s->vconfig, p, fd[0], sfd[0]);
exit(0);
} else if (pid > 0) { /* parent */

View File

@ -1033,7 +1033,7 @@ static void reload_sig_watcher_cb(struct ev_loop *loop, ev_signal *w, int revent
* That's because of a test that the certificate matches the
* used key. */
ms_sleep(1500);
reload_cfg_file(s->config_pool, s->vconfig, 1);
reload_cfg_file(s->config_pool, s->vconfig, 0);
}
static void cmd_watcher_cb (EV_P_ ev_io *w, int revents)

View File

@ -626,13 +626,13 @@ static void check_other_work(sec_mod_st *sec)
sec_mod_client_db_deinit(sec);
tls_cache_deinit(&sec->tls_db);
talloc_free(sec->config_pool);
talloc_free(sec);
talloc_free(sec->sec_mod_pool);
exit(0);
}
if (need_reload) {
seclog(sec, LOG_DEBUG, "reloading configuration");
reload_cfg_file(sec, sec->vconfig, 0);
reload_cfg_file(sec, sec->vconfig, 1);
load_keys(sec, 0);
list_for_each(sec->vconfig, vhost, list) {
@ -918,6 +918,7 @@ void sec_mod_server(void *main_pool, void *config_pool, struct list_head *vconfi
sec->vconfig = vconfig;
sec->config_pool = config_pool;
sec->sec_mod_pool = sec_mod_pool;
tls_cache_init(sec, &sec->tls_db);
sup_config_init(sec);

View File

@ -35,6 +35,7 @@
typedef struct sec_mod_st {
struct list_head *vconfig;
void *config_pool;
void *sec_mod_pool;
struct htable *client_db;
int cmd_fd;

View File

@ -816,7 +816,7 @@ int load_cert_files(main_server_st *s, struct vhost_cfg_st *vhost)
}
pcert_list_size = 8;
pcert_list = gnutls_malloc(sizeof(pcert_list[0])*pcert_list_size);
pcert_list = talloc_size(vhost->pool, sizeof(pcert_list[0])*pcert_list_size);
if (pcert_list == NULL) {
mslog(s, NULL, LOG_ERR, "error allocating memory");
return -1;
@ -1038,6 +1038,9 @@ void tls_load_prio(main_server_st *s, struct vhost_cfg_st *vhost)
int ret;
const char* perr;
if (vhost->creds.cprio != NULL)
gnutls_priority_deinit(vhost->creds.cprio);
ret = gnutls_priority_init(&vhost->creds.cprio, vhost->perm_config.config->priorities, &perr);
if (ret == GNUTLS_E_PARSING_ERROR)
mslog(s, NULL, LOG_ERR, "error in TLS priority string: %s", perr);

View File

@ -427,7 +427,7 @@ enum option_types { OPTION_NUMERIC, OPTION_STRING, OPTION_BOOLEAN, OPTION_MULTI_
#include <ip-util.h>
void reload_cfg_file(void *pool, struct list_head *configs, unsigned archive);
void reload_cfg_file(void *pool, struct list_head *configs, unsigned sec_mod);
void clear_old_configs(struct list_head *configs);
void write_pid_file(void);
void remove_pid_file(void);