mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-10 17:17:06 +02:00
[MEDIUM] Fix memory freeing at exit, part 2
- free oldpids - call free(exp->preg), not only regfree(exp->preg): req_exp, rsp_exp - build a list of unique uri_auths and eventually free it - prune_acl_cond/free for switching_rules - add a callback pointer to free ptr from acl_pattern (used for regexs) and execute it ==1180== malloc/free: in use at exit: 0 bytes in 0 blocks. ==1180== malloc/free: 5,599 allocs, 5,599 frees, 4,220,556 bytes allocated. ==1180== All heap blocks were freed -- no leaks are possible.
This commit is contained in:
parent
a643baf091
commit
8001d6162e
@ -42,6 +42,7 @@ struct uri_auth {
|
|||||||
int flags; /* some flags describing the statistics page */
|
int flags; /* some flags describing the statistics page */
|
||||||
struct user_auth *users; /* linked list of valid user:passwd couples */
|
struct user_auth *users; /* linked list of valid user:passwd couples */
|
||||||
struct stat_scope *scope; /* linked list of authorized proxies */
|
struct stat_scope *scope; /* linked list of authorized proxies */
|
||||||
|
struct uri_auth *next; /* Used at deinit() to build a list of unique elements */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This is the default statistics URI */
|
/* This is the default statistics URI */
|
||||||
|
@ -101,6 +101,7 @@ struct acl_pattern {
|
|||||||
char *str; /* any string */
|
char *str; /* any string */
|
||||||
regex_t *reg; /* a compiled regex */
|
regex_t *reg; /* a compiled regex */
|
||||||
} ptr; /* indirect values, allocated */
|
} ptr; /* indirect values, allocated */
|
||||||
|
void(*freeptrbuf)(void *ptr); /* a destructor able to free objects from the ptr */
|
||||||
int len; /* data length when required */
|
int len; /* data length when required */
|
||||||
int flags; /* expr or pattern flags. */
|
int flags; /* expr or pattern flags. */
|
||||||
};
|
};
|
||||||
|
15
src/acl.c
15
src/acl.c
@ -285,6 +285,12 @@ int acl_parse_str(const char **text, struct acl_pattern *pattern, int *opaque)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Free data allocated by acl_parse_reg */
|
||||||
|
static void acl_free_reg(void *ptr) {
|
||||||
|
|
||||||
|
regfree((regex_t *)ptr);
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse a regex. It is allocated. */
|
/* Parse a regex. It is allocated. */
|
||||||
int acl_parse_reg(const char **text, struct acl_pattern *pattern, int *opaque)
|
int acl_parse_reg(const char **text, struct acl_pattern *pattern, int *opaque)
|
||||||
{
|
{
|
||||||
@ -303,6 +309,7 @@ int acl_parse_reg(const char **text, struct acl_pattern *pattern, int *opaque)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pattern->ptr.reg = preg;
|
pattern->ptr.reg = preg;
|
||||||
|
pattern->freeptrbuf = &acl_free_reg;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -452,8 +459,14 @@ struct acl_keyword *find_acl_kw(const char *kw)
|
|||||||
|
|
||||||
static void free_pattern(struct acl_pattern *pat)
|
static void free_pattern(struct acl_pattern *pat)
|
||||||
{
|
{
|
||||||
if (pat->ptr.ptr)
|
|
||||||
|
if (pat->ptr.ptr) {
|
||||||
|
if (pat->freeptrbuf)
|
||||||
|
pat->freeptrbuf(pat->ptr.ptr);
|
||||||
|
|
||||||
free(pat->ptr.ptr);
|
free(pat->ptr.ptr);
|
||||||
|
}
|
||||||
|
|
||||||
free(pat);
|
free(pat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -647,6 +647,9 @@ void deinit(void)
|
|||||||
struct acl_cond *cond, *condb;
|
struct acl_cond *cond, *condb;
|
||||||
struct hdr_exp *exp, *expb;
|
struct hdr_exp *exp, *expb;
|
||||||
struct acl *acl, *aclb;
|
struct acl *acl, *aclb;
|
||||||
|
struct switching_rule *rule, *ruleb;
|
||||||
|
struct uri_auth *uap, *ua = NULL;
|
||||||
|
struct user_auth *user;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
while (p) {
|
while (p) {
|
||||||
@ -699,8 +702,11 @@ void deinit(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (exp = p->req_exp; exp != NULL; ) {
|
for (exp = p->req_exp; exp != NULL; ) {
|
||||||
if (exp->preg)
|
if (exp->preg) {
|
||||||
regfree((regex_t *)exp->preg);
|
regfree((regex_t *)exp->preg);
|
||||||
|
free((regex_t *)exp->preg);
|
||||||
|
}
|
||||||
|
|
||||||
if (exp->replace && exp->action != ACT_SETBE)
|
if (exp->replace && exp->action != ACT_SETBE)
|
||||||
free((char *)exp->replace);
|
free((char *)exp->replace);
|
||||||
expb = exp;
|
expb = exp;
|
||||||
@ -709,8 +715,11 @@ void deinit(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (exp = p->rsp_exp; exp != NULL; ) {
|
for (exp = p->rsp_exp; exp != NULL; ) {
|
||||||
if (exp->preg)
|
if (exp->preg) {
|
||||||
regfree((regex_t *)exp->preg);
|
regfree((regex_t *)exp->preg);
|
||||||
|
free((regex_t *)exp->preg);
|
||||||
|
}
|
||||||
|
|
||||||
if (exp->replace && exp->action != ACT_SETBE)
|
if (exp->replace && exp->action != ACT_SETBE)
|
||||||
free((char *)exp->replace);
|
free((char *)exp->replace);
|
||||||
expb = exp;
|
expb = exp;
|
||||||
@ -718,9 +727,21 @@ void deinit(void)
|
|||||||
free(expb);
|
free(expb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: this must also be freed :
|
/* build a list of unique uri_auths */
|
||||||
* - uri_auth (but it's shared)
|
if (!ua)
|
||||||
*/
|
ua = p->uri_auth;
|
||||||
|
else {
|
||||||
|
/* check if p->uri_auth is unique */
|
||||||
|
for (uap = ua; uap; uap=uap->next)
|
||||||
|
if (uap == p->uri_auth)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!uap) {
|
||||||
|
/* add it, if it is */
|
||||||
|
p->uri_auth->next = ua;
|
||||||
|
ua = p->uri_auth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
list_for_each_entry_safe(acl, aclb, &p->acl, list) {
|
list_for_each_entry_safe(acl, aclb, &p->acl, list) {
|
||||||
LIST_DEL(&acl->list);
|
LIST_DEL(&acl->list);
|
||||||
@ -728,6 +749,15 @@ void deinit(void)
|
|||||||
free(acl);
|
free(acl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_for_each_entry_safe(rule, ruleb, &p->switching_rules, list) {
|
||||||
|
LIST_DEL(&rule->list);
|
||||||
|
|
||||||
|
prune_acl_cond(rule->cond);
|
||||||
|
free(rule->cond);
|
||||||
|
|
||||||
|
free(rule);
|
||||||
|
}
|
||||||
|
|
||||||
if (p->appsession_name)
|
if (p->appsession_name)
|
||||||
free(p->appsession_name);
|
free(p->appsession_name);
|
||||||
|
|
||||||
@ -791,6 +821,27 @@ void deinit(void)
|
|||||||
free(p0);
|
free(p0);
|
||||||
}/* end while(p) */
|
}/* end while(p) */
|
||||||
|
|
||||||
|
while (ua) {
|
||||||
|
uap = ua;
|
||||||
|
ua = ua->next;
|
||||||
|
|
||||||
|
if (uap->uri_prefix)
|
||||||
|
free(uap->uri_prefix);
|
||||||
|
|
||||||
|
if (uap->auth_realm)
|
||||||
|
free(uap->auth_realm);
|
||||||
|
|
||||||
|
while (uap->users) {
|
||||||
|
user = uap->users;
|
||||||
|
uap->users = uap->users->next;
|
||||||
|
|
||||||
|
free(user->user_pwd);
|
||||||
|
free(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(uap);
|
||||||
|
}
|
||||||
|
|
||||||
protocol_unbind_all();
|
protocol_unbind_all();
|
||||||
|
|
||||||
if (global.chroot) free(global.chroot);
|
if (global.chroot) free(global.chroot);
|
||||||
@ -802,6 +853,9 @@ void deinit(void)
|
|||||||
if (fdtab) free(fdtab);
|
if (fdtab) free(fdtab);
|
||||||
fdtab = NULL;
|
fdtab = NULL;
|
||||||
|
|
||||||
|
if (oldpids)
|
||||||
|
free(oldpids);
|
||||||
|
|
||||||
pool_destroy2(pool2_session);
|
pool_destroy2(pool2_session);
|
||||||
pool_destroy2(pool2_buffer);
|
pool_destroy2(pool2_buffer);
|
||||||
pool_destroy2(pool2_requri);
|
pool_destroy2(pool2_requri);
|
||||||
|
Loading…
Reference in New Issue
Block a user