race condition fixed on configuration reload

Race condition on service free'ing
This commit is contained in:
z3APA3A 2015-11-29 00:01:41 +03:00
parent 0e4a507dd8
commit 62775da1d5
3 changed files with 124 additions and 121 deletions

View File

@ -24,6 +24,7 @@ pthread_mutex_t bandlim_mutex;
pthread_mutex_t tc_mutex; pthread_mutex_t tc_mutex;
pthread_mutex_t pwl_mutex; pthread_mutex_t pwl_mutex;
pthread_mutex_t hash_mutex; pthread_mutex_t hash_mutex;
pthread_mutex_t config_mutex;
#ifndef NOODBC #ifndef NOODBC
pthread_mutex_t odbc_mutex; pthread_mutex_t odbc_mutex;
@ -84,6 +85,113 @@ FILE * confopen(){
} }
void freeconf(struct extparam *confp){
struct bandlim * bl;
struct bandlim * blout;
struct trafcount * tc;
struct passwords *pw;
struct ace *acl;
struct filemon *fm;
int counterd, archiverc;
unsigned char *logname, *logtarget;
unsigned char **archiver;
unsigned char * logformat;
int i;
pthread_mutex_lock(&tc_mutex);
confp->trafcountfunc = NULL;
tc = confp->trafcounter;
confp->trafcounter = NULL;
counterd = confp->counterd;
confp->counterd = -1;
pthread_mutex_unlock(&tc_mutex);
if(tc)dumpcounters(tc,counterd);
for(; tc; tc = (struct trafcount *) itfree(tc, tc->next)){
if(tc->comment)myfree(tc->comment);
freeacl(tc->ace);
}
confp->countertype = NONE;
logtarget = confp->logtarget;
confp->logtarget = NULL;
logformat = confp->logformat;
confp->logformat = NULL;
pthread_mutex_lock(&bandlim_mutex);
bl = confp->bandlimiter;
blout = confp->bandlimiterout;
confp->bandlimiter = NULL;
confp->bandlimiterout = NULL;
confp->bandlimfunc = NULL;
pthread_mutex_unlock(&bandlim_mutex);
logname = confp->logname;
confp->logname = NULL;
archiverc = confp->archiverc;
confp->archiverc = 0;
archiver = confp->archiver;
confp->archiver = NULL;
fm = confp->fmon;
confp->fmon = NULL;
pw = confp->pwl;
confp->pwl = NULL;
confp->rotate = 0;
confp->logtype = NONE;
confp->authfunc = ipauth;
confp->bandlimfunc = NULL;
memset(&confp->intsa, 0, sizeof(confp->intsa));
memset(&confp->extsa, 0, sizeof(confp->extsa));
#ifndef NOIPV6
memset(&confp->extsa6, 0, sizeof(confp->extsa6));
*SAFAMILY(&confp->extsa6) = AF_INET6;
#endif
*SAFAMILY(&confp->intsa) = AF_INET;
*SAFAMILY(&confp->extsa) = AF_INET;
confp->singlepacket = 0;
confp->maxchild = 100;
resolvfunc = NULL;
numservers = 0;
acl = confp->acl;
confp->acl = NULL;
confp->logtime = confp->time = 0;
usleep(SLEEPTIME);
freeacl(acl);
freepwl(pw);
for(; bl; bl = (struct bandlim *) itfree(bl, bl->next)) freeacl(bl->ace);
for(; blout; blout = (struct bandlim *) itfree(blout, blout->next))freeacl(blout->ace);
if(counterd != -1) {
close(counterd);
}
for(; fm; fm = (struct filemon *)itfree(fm, fm->next)){
if(fm->path) myfree(fm->path);
}
if(logtarget) {
myfree(logtarget);
}
if(logname) {
myfree(logname);
}
if(logformat) {
myfree(logformat);
}
if(archiver) {
for(i = 0; i < archiverc; i++) myfree(archiver[i]);
myfree(archiver);
}
}
void clearall(){ void clearall(){
freeconf(&conf); freeconf(&conf);
} }
@ -135,15 +243,7 @@ void __stdcall CommandHandler( DWORD dwCommand )
break; break;
case SERVICE_CONTROL_CONTINUE: case SERVICE_CONTROL_CONTINUE:
SetStatus( SERVICE_CONTINUE_PENDING, 0, 1 ); SetStatus( SERVICE_CONTINUE_PENDING, 0, 1 );
clearall(); conf.needreload = 1;
fp = confopen();
if(fp){
error = readconfig(fp);
if(error) {
clearall();
}
if(!writable)fclose(fp);
}
SetStatus( SERVICE_RUNNING, 0, 0 ); SetStatus( SERVICE_RUNNING, 0, 0 );
break; break;
default: ; default: ;
@ -2087,6 +2187,7 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
return 1; return 1;
} }
pthread_mutex_init(&config_mutex, NULL);
pthread_mutex_init(&bandlim_mutex, NULL); pthread_mutex_init(&bandlim_mutex, NULL);
pthread_mutex_init(&hash_mutex, NULL); pthread_mutex_init(&hash_mutex, NULL);
pthread_mutex_init(&tc_mutex, NULL); pthread_mutex_init(&tc_mutex, NULL);

View File

@ -246,6 +246,7 @@ unsigned long udpresolve(int af, unsigned char * name, unsigned char * value, un
struct ace * copyacl (struct ace *ac); struct ace * copyacl (struct ace *ac);
struct auth * copyauth (struct auth *); struct auth * copyauth (struct auth *);
void * itfree(void *data, void * retval);
void freeacl(struct ace *ac); void freeacl(struct ace *ac);
void freeauth(struct auth *); void freeauth(struct auth *);
void freefilter(struct filter *filter); void freefilter(struct filter *filter);
@ -308,6 +309,7 @@ struct dictionary;
struct node; struct node;
struct property; struct property;
extern pthread_mutex_t config_mutex;
extern pthread_mutex_t bandlim_mutex; extern pthread_mutex_t bandlim_mutex;
extern pthread_mutex_t hash_mutex; extern pthread_mutex_t hash_mutex;
extern pthread_mutex_t tc_mutex; extern pthread_mutex_t tc_mutex;

View File

@ -632,18 +632,21 @@ int MODULEMAINFUNC (int argc, char** argv){
if(!srv.silent) srv.logfunc(&defparam, (unsigned char *)"Exiting thread"); if(!srv.silent) srv.logfunc(&defparam, (unsigned char *)"Exiting thread");
if(fp) fclose(fp); if(fp) fclose(fp);
srvfree(&srv); srvfree(&srv);
if(defparam.hostname)myfree(defparam.hostname);
if(cbc_string)myfree(cbc_string);
if(cbl_string)myfree(cbc_string);
#ifndef STDMAIN #ifndef STDMAIN
pthread_mutex_lock(&config_mutex);
if(srv.next)srv.next->prev = srv.prev; if(srv.next)srv.next->prev = srv.prev;
if(srv.prev)srv.prev->next = srv.next; if(srv.prev)srv.prev->next = srv.next;
else conf.services = srv.next; else conf.services = srv.next;
freeacl(srv.acl); pthread_mutex_unlock(&config_mutex);
freeauth(srv.authfuncs);
#endif #endif
if(defparam.hostname)myfree(defparam.hostname);
if(cbc_string)myfree(cbc_string);
if(cbl_string)myfree(cbl_string);
return 0; return 0;
} }
@ -720,6 +723,9 @@ void srvfree(struct srvparam * srv){
} }
myfree(srv->filter); myfree(srv->filter);
} }
if(srv->acl)freeacl(srv->acl);
if(srv->authfuncs)freeauth(srv->authfuncs);
#endif #endif
pthread_mutex_destroy(&srv->counter_mutex); pthread_mutex_destroy(&srv->counter_mutex);
if(srv->target) myfree(srv->target); if(srv->target) myfree(srv->target);
@ -903,7 +909,7 @@ FILTER_ACTION makefilters (struct srvparam *srv, struct clientparam *param){
return res; return res;
} }
static void * itfree(void *data, void * retval){ void * itfree(void *data, void * retval){
myfree(data); myfree(data);
return retval; return retval;
} }
@ -944,112 +950,6 @@ void freeacl(struct ace *ac){
} }
} }
void freeconf(struct extparam *confp){
struct bandlim * bl;
struct bandlim * blout;
struct trafcount * tc;
struct passwords *pw;
struct ace *acl;
struct filemon *fm;
int counterd, archiverc;
unsigned char *logname, *logtarget;
unsigned char **archiver;
unsigned char * logformat;
int i;
pthread_mutex_lock(&tc_mutex);
confp->trafcountfunc = NULL;
tc = confp->trafcounter;
confp->trafcounter = NULL;
counterd = confp->counterd;
confp->counterd = -1;
pthread_mutex_unlock(&tc_mutex);
if(tc)dumpcounters(tc,counterd);
for(; tc; tc = (struct trafcount *) itfree(tc, tc->next)){
if(tc->comment)myfree(tc->comment);
freeacl(tc->ace);
}
confp->countertype = NONE;
logtarget = confp->logtarget;
confp->logtarget = NULL;
logformat = confp->logformat;
confp->logformat = NULL;
pthread_mutex_lock(&bandlim_mutex);
bl = confp->bandlimiter;
blout = confp->bandlimiterout;
confp->bandlimiter = NULL;
confp->bandlimiterout = NULL;
confp->bandlimfunc = NULL;
pthread_mutex_unlock(&bandlim_mutex);
logname = confp->logname;
confp->logname = NULL;
archiverc = confp->archiverc;
confp->archiverc = 0;
archiver = confp->archiver;
confp->archiver = NULL;
fm = confp->fmon;
confp->fmon = NULL;
pw = confp->pwl;
confp->pwl = NULL;
confp->rotate = 0;
confp->logtype = NONE;
confp->authfunc = ipauth;
confp->bandlimfunc = NULL;
memset(&confp->intsa, 0, sizeof(confp->intsa));
memset(&confp->extsa, 0, sizeof(confp->extsa));
#ifndef NOIPV6
memset(&confp->extsa6, 0, sizeof(confp->extsa6));
*SAFAMILY(&confp->extsa6) = AF_INET6;
#endif
*SAFAMILY(&confp->intsa) = AF_INET;
*SAFAMILY(&confp->extsa) = AF_INET;
confp->singlepacket = 0;
confp->maxchild = 100;
resolvfunc = NULL;
numservers = 0;
acl = confp->acl;
confp->acl = NULL;
confp->logtime = confp->time = 0;
usleep(SLEEPTIME);
freeacl(acl);
freepwl(pw);
for(; bl; bl = (struct bandlim *) itfree(bl, bl->next)) freeacl(bl->ace);
for(; blout; blout = (struct bandlim *) itfree(blout, blout->next))freeacl(blout->ace);
if(counterd != -1) {
close(counterd);
}
for(; fm; fm = (struct filemon *)itfree(fm, fm->next)){
if(fm->path) myfree(fm->path);
}
if(logtarget) {
myfree(logtarget);
}
if(logname) {
myfree(logname);
}
if(logformat) {
myfree(logformat);
}
if(archiver) {
for(i = 0; i < archiverc; i++) myfree(archiver[i]);
myfree(archiver);
}
}
FILTER_ACTION handlereqfilters(struct clientparam *param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){ FILTER_ACTION handlereqfilters(struct clientparam *param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
FILTER_ACTION action; FILTER_ACTION action;
int i; int i;