Commit fc28c720 authored by Geoff Simmons's avatar Geoff Simmons

Don't leak resources in the constructor if it fails.

parent 590c4359
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <signal.h> #include <signal.h>
#include <time.h> #include <time.h>
#include <stdio.h> #include <stdio.h>
#include <stdbool.h>
#include "cache/cache.h" #include "cache/cache.h"
#include "vcl.h" #include "vcl.h"
...@@ -347,13 +348,14 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp, ...@@ -347,13 +348,14 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
VCL_STRING name, VCL_STRING path, VCL_DURATION ttl, VCL_STRING name, VCL_STRING path, VCL_DURATION ttl,
VCL_BOOL log_checks, VCL_BOOL enable_sha256) VCL_BOOL log_checks, VCL_BOOL enable_sha256)
{ {
struct VPFX(file_reader) *rdr; struct VPFX(file_reader) *rdr = NULL;
struct file_info *info; struct file_info *info = NULL;
struct sigevent sigev; struct sigevent sigev;
timer_t timerid; timer_t timerid;
struct itimerspec timerspec; struct itimerspec timerspec;
struct obj_head *objh; struct obj_head *objh;
struct obj_entry *objent; struct obj_entry *objent = NULL;
bool lock_init = false;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(rdrp); AN(rdrp);
...@@ -383,7 +385,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp, ...@@ -383,7 +385,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
if (rdr == NULL) { if (rdr == NULL) {
VFAIL(ctx, "new %s: allocating space for object: %s", VFAIL(ctx, "new %s: allocating space for object: %s",
vcl_name, VAS_errtxt(errno)); vcl_name, VAS_errtxt(errno));
return; goto init_err;
} }
AZ(rdr->lock); AZ(rdr->lock);
...@@ -392,7 +394,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp, ...@@ -392,7 +394,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
if (rdr->lock == NULL) { if (rdr->lock == NULL) {
VFAIL(ctx, "new %s: allocating space for lock: %s", VFAIL(ctx, "new %s: allocating space for lock: %s",
vcl_name, VAS_errtxt(errno)); vcl_name, VAS_errtxt(errno));
return; goto init_err;
} }
AZ(info->sha256); AZ(info->sha256);
...@@ -402,11 +404,13 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp, ...@@ -402,11 +404,13 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
if (info->sha256 == NULL) { if (info->sha256 == NULL) {
VFAIL(ctx, "new %s: allocating space for SHA256: %s", VFAIL(ctx, "new %s: allocating space for SHA256: %s",
vcl_name, VAS_errtxt(errno)); vcl_name, VAS_errtxt(errno));
return; goto init_err;
} }
} }
rdr->info = info; rdr->info = info;
AZ(rdr->obj_name);
AZ(rdr->vcl_name);
rdr->obj_name = strdup(vcl_name); rdr->obj_name = strdup(vcl_name);
rdr->vcl_name = strdup(VCL_Name(ctx->vcl)); rdr->vcl_name = strdup(VCL_Name(ctx->vcl));
info->log_checks = log_checks; info->log_checks = log_checks;
...@@ -421,7 +425,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp, ...@@ -421,7 +425,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
AZ(info->path); AZ(info->path);
if (path == NULL || *path == '\0') { if (path == NULL || *path == '\0') {
VFAIL(ctx, "new %s: path is empty", vcl_name); VFAIL(ctx, "new %s: path is empty", vcl_name);
return; goto init_err;
} }
search = VSB_new_auto(); search = VSB_new_auto();
for (const char *start = path; delim == ':'; VSB_clear(search), for (const char *start = path; delim == ':'; VSB_clear(search),
...@@ -445,7 +449,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp, ...@@ -445,7 +449,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
VSB_destroy(&search); VSB_destroy(&search);
closefd(&fd); closefd(&fd);
VFAIL(ctx, "new %s: allocating path", vcl_name); VFAIL(ctx, "new %s: allocating path", vcl_name);
return; goto init_err;
} }
strcpy(info->path, VSB_data(search)); strcpy(info->path, VSB_data(search));
break; break;
...@@ -456,7 +460,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp, ...@@ -456,7 +460,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
if (info->path == NULL) { if (info->path == NULL) {
VFAIL(ctx, "new %s: %s not found or not readable on " VFAIL(ctx, "new %s: %s not found or not readable on "
"path %s", vcl_name, name, path); "path %s", vcl_name, name, path);
return; goto init_err;
} }
} }
...@@ -464,17 +468,19 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp, ...@@ -464,17 +468,19 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
if (pthread_rwlock_init(rdr->lock, NULL) != 0) { if (pthread_rwlock_init(rdr->lock, NULL) != 0) {
VFAIL(ctx, "new %s: initializing lock: %s", vcl_name, VFAIL(ctx, "new %s: initializing lock: %s", vcl_name,
VAS_errtxt(errno)); VAS_errtxt(errno));
return; goto init_err;
} }
lock_init = true;
rdr->errlen = ERRMSG_LEN + strlen(name) + strlen(vcl_name) rdr->errlen = ERRMSG_LEN + strlen(name) + strlen(vcl_name)
+ strlen(VCL_Name(ctx->vcl)); + strlen(VCL_Name(ctx->vcl));
AZ(rdr->errbuf);
errno = 0; errno = 0;
rdr->errbuf = malloc(rdr->errlen); rdr->errbuf = malloc(rdr->errlen);
if (rdr->errbuf == NULL) { if (rdr->errbuf == NULL) {
VFAIL(ctx, "new %s: allocating error message buffer: %s", VFAIL(ctx, "new %s: allocating error message buffer: %s",
vcl_name, VAS_errtxt(errno)); vcl_name, VAS_errtxt(errno));
return; goto init_err;
} }
memset(&sigev, 0, sizeof(sigev)); memset(&sigev, 0, sizeof(sigev));
...@@ -486,7 +492,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp, ...@@ -486,7 +492,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
if (timer_create(CLOCK_MONOTONIC, &sigev, &timerid) != 0) { if (timer_create(CLOCK_MONOTONIC, &sigev, &timerid) != 0) {
VFAIL(ctx, "new %s: cannot create update timer: %s", vcl_name, VFAIL(ctx, "new %s: cannot create update timer: %s", vcl_name,
VAS_errtxt(errno)); VAS_errtxt(errno));
return; goto init_err;
} }
rdr->timerid = timerid; rdr->timerid = timerid;
rdr->flags |= RDR_TIMER_INIT; rdr->flags |= RDR_TIMER_INIT;
...@@ -505,7 +511,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp, ...@@ -505,7 +511,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
if (objent == NULL) { if (objent == NULL) {
VFAIL(ctx, "new %s: allocating object list entry: %s", vcl_name, VFAIL(ctx, "new %s: allocating object list entry: %s", vcl_name,
VAS_errtxt(errno)); VAS_errtxt(errno));
return; goto init_err;
} }
objent->obj = rdr; objent->obj = rdr;
VSLIST_INSERT_HEAD(objh, objent, list); VSLIST_INSERT_HEAD(objh, objent, list);
...@@ -519,7 +525,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp, ...@@ -519,7 +525,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
if (timer_settime(timerid, 0, &timerspec, NULL) != 0) { if (timer_settime(timerid, 0, &timerspec, NULL) != 0) {
VFAIL(ctx, "new %s: cannot start update timer: %s", vcl_name, VFAIL(ctx, "new %s: cannot start update timer: %s", vcl_name,
VAS_errtxt(errno)); VAS_errtxt(errno));
return; goto init_err;
} }
rdr->flags |= RDR_TIMER_ON; rdr->flags |= RDR_TIMER_ON;
do { do {
...@@ -529,7 +535,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp, ...@@ -529,7 +535,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
if (rdr->flags & RDR_ERROR) { if (rdr->flags & RDR_ERROR) {
AN(strcmp(rdr->errbuf, NO_ERR)); AN(strcmp(rdr->errbuf, NO_ERR));
VFAIL(ctx, "new %s: %s", vcl_name, rdr->errbuf); VFAIL(ctx, "new %s: %s", vcl_name, rdr->errbuf);
return; goto init_err;
} }
AN(rdr->flags & RDR_MAPPED); AN(rdr->flags & RDR_MAPPED);
...@@ -538,6 +544,58 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp, ...@@ -538,6 +544,58 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
AN(rdr->info->mtime.tv_sec); AN(rdr->info->mtime.tv_sec);
*rdrp = rdr; *rdrp = rdr;
return;
init_err:
if (objent != NULL) {
VSLIST_REMOVE(objh, objent, obj_entry, list);
FREE_OBJ(objent);
}
if (rdr != NULL) {
CHECK_OBJ(rdr, FILE_READER_MAGIC);
if (rdr->flags & RDR_TIMER_INIT) {
errno = 0;
if (timer_delete(timerid) != 0)
VSL(SLT_Error, NO_VXID, "vmod file %s.%s "
"deallocation: cannot delete timer: %s",
vcl_name, name, VAS_errtxt(errno));
}
if (rdr->addr != NULL && (rdr->flags & RDR_MAPPED)) {
errno = 0;
if (unmap(rdr, rdr->addr) != 0)
VSL(SLT_Error, NO_VXID, "vmod file %s.%s "
"deallocation: cannot unmap: %s",
vcl_name, name, VAS_errtxt(errno));
}
if (rdr->lock != NULL) {
if (lock_init) {
errno = 0;
if (pthread_rwlock_destroy(rdr->lock) != 0)
VSL(SLT_Error, NO_VXID,
"vmod file %s.%s deallocation: "
"cannot destroy lock: %s",
vcl_name, name, VAS_errtxt(errno));
}
free(rdr->lock);
}
if (rdr->errbuf != NULL)
free(rdr->errbuf);
if (rdr->obj_name != NULL)
free(rdr->obj_name);
if (rdr->vcl_name != NULL)
free(rdr->vcl_name);
FREE_OBJ(rdr);
}
if (info != NULL) {
CHECK_OBJ(info, FILE_INFO_MAGIC);
if (info->path != NULL)
free(info->path);
if (info->sha256 != NULL)
free(info->sha256);
FREE_OBJ(info);
}
} }
VCL_VOID VCL_VOID
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment