Fix memory leaks related to configuration

This commit is contained in:
Daniel Winzen 2022-12-07 00:01:52 +01:00
parent e3cbdc94a8
commit a65286eb9d
No known key found for this signature in database
GPG Key ID: 222FCC3F35C41077
5 changed files with 94 additions and 32 deletions

View File

@ -169,7 +169,7 @@ int timechanged (time_t oldtime, time_t newtime, ROTATION lt){
)return 1; )return 1;
break; break;
default: default:
break; break;
} }
return 0; return 0;
} }
@ -204,12 +204,12 @@ void dumpcounters(struct trafcount *tlin, int counterd){
conf.time = time(0); conf.time = time(0);
if(cheader.updated && conf.countertype && timechanged(cheader.updated, conf.time, conf.countertype)){ if(cheader.updated && conf.countertype && timechanged(cheader.updated, conf.time, conf.countertype)){
FILE * cfp; FILE * cfp;
cfp = fopen((char *)dologname(tmpbuf, (unsigned char *)conf.counterfile, NULL, conf.countertype, cheader.updated), "w"); cfp = fopen((char *)dologname(tmpbuf, (unsigned char *)conf.counterfile, NULL, conf.countertype, cheader.updated), "w");
if(cfp){ if(cfp){
for(tl = tlin; cfp && tl; tl = tl->next){ for(tl = tlin; cfp && tl; tl = tl->next){
if(tl->type >= conf.countertype) if(tl->type >= conf.countertype)
fprintf(cfp, "%05d %020"PRIu64"u%s%s\n", tl->number, tl->traf64, tl->comment?" #" : "", tl->comment? tl->comment : ""); fprintf(cfp, "%05d %020"PRIu64"u%s%s\n", tl->number, tl->traf64, tl->comment?" #" : "", tl->comment? tl->comment : "");
} }
fclose(cfp); fclose(cfp);
} }
@ -218,10 +218,10 @@ void dumpcounters(struct trafcount *tlin, int counterd){
cheader.updated = conf.time; cheader.updated = conf.time;
lseek(counterd, 0, SEEK_SET); lseek(counterd, 0, SEEK_SET);
write(counterd, &cheader, sizeof(struct counter_header)); write(counterd, &cheader, sizeof(struct counter_header));
for(tl=tlin; tl; tl = tl->next){ for(tl=tlin; tl; tl = tl->next){
if(tl->number){ if(tl->number){
lseek(counterd, lseek(counterd,
sizeof(struct counter_header) + (tl->number - 1) * sizeof(struct counter_record), sizeof(struct counter_header) + (tl->number - 1) * sizeof(struct counter_record),
SEEK_SET); SEEK_SET);
crecord.traf64 = tl->traf64; crecord.traf64 = tl->traf64;
@ -245,7 +245,7 @@ void cyclestep(void){
minutecounter = time(0); minutecounter = time(0);
for(;;){ for(;;){
usleep(SLEEPTIME*999); usleep(SLEEPTIME*999);
conf.time = time(0); conf.time = time(0);
if(conf.needreload) { if(conf.needreload) {
doschedule(); doschedule();
@ -266,7 +266,7 @@ void cyclestep(void){
} }
} }
} }
} }
if(timechanged(basetime, conf.time, DAILY)) { if(timechanged(basetime, conf.time, DAILY)) {
tm = localtime(&conf.time); tm = localtime(&conf.time);
@ -336,7 +336,7 @@ void cyclestep(void){
usleep(SLEEPTIME*999); usleep(SLEEPTIME*999);
return; return;
} }
} }
} }
@ -392,11 +392,11 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
sprintf((char *)tmpbuf, "%s will be installed and started.\n" sprintf((char *)tmpbuf, "%s will be installed and started.\n"
"By clicking Yes you confirm you read and accepted License Agreement.\n" "By clicking Yes you confirm you read and accepted License Agreement.\n"
"You can use Administration/Services to control %s service.", "You can use Administration/Services to control %s service.",
conf.stringtable[1], conf.stringtable[2]); conf.stringtable[1], conf.stringtable[2]);
if(MessageBox(NULL, (LPCSTR)tmpbuf, (LPCSTR)conf.stringtable[2], MB_YESNO|MB_ICONASTERISK) != IDYES) return 1; if(MessageBox(NULL, (LPCSTR)tmpbuf, (LPCSTR)conf.stringtable[2], MB_YESNO|MB_ICONASTERISK) != IDYES) return 1;
*tmpbuf = '\"'; *tmpbuf = '\"';
if (!(res = SearchPath(NULL, argv[0], ".exe", 256, (char *)tmpbuf+1, (LPTSTR*)&arg))) { if (!(res = SearchPath(NULL, argv[0], ".exe", 256, (char *)tmpbuf+1, (LPTSTR*)&arg))) {
perror("Failed to find executable filename"); perror("Failed to find executable filename");
@ -427,7 +427,7 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
else { else {
HKEY runsrv; HKEY runsrv;
if(RegOpenKeyEx( HKEY_LOCAL_MACHINE, if(RegOpenKeyEx( HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices", "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",
0, 0,
KEY_ALL_ACCESS, KEY_ALL_ACCESS,
@ -468,7 +468,7 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
} }
else { else {
HKEY runsrv; HKEY runsrv;
if(RegOpenKeyEx( HKEY_LOCAL_MACHINE, if(RegOpenKeyEx( HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices", "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",
0, 0,
KEY_ALL_ACCESS, KEY_ALL_ACCESS,
@ -530,22 +530,22 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
if(!writable)fclose(fp); if(!writable)fclose(fp);
#ifdef _WIN32 #ifdef _WIN32
#ifndef _WINCE #ifndef _WINCE
if(service){ if(service){
SERVICE_TABLE_ENTRY ste[] = SERVICE_TABLE_ENTRY ste[] =
{ {
{ (LPSTR)conf.stringtable[1], (LPSERVICE_MAIN_FUNCTION)ServiceMain}, { (LPSTR)conf.stringtable[1], (LPSERVICE_MAIN_FUNCTION)ServiceMain},
{ NULL, NULL } { NULL, NULL }
}; };
if(!StartServiceCtrlDispatcher( ste ))cyclestep(); if(!StartServiceCtrlDispatcher( ste ))cyclestep();
} }
else else
#endif #endif
{ {
cyclestep(); cyclestep();
} }
#else #else
signal(SIGCONT, mysigpause); signal(SIGCONT, mysigpause);
@ -558,6 +558,12 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
CLEARRETURN: CLEARRETURN:
freeconf(&conf);
myfree(conf.conffile);
freeauth(conf.authfuncs);
destroyhashtable(&dns_table);
destroyhashtable(&dns6_table);
fprintf(stderr, "hi\n");
return 0; return 0;
} }

View File

@ -114,7 +114,6 @@ struct extparam conf = {
#else #else
{AF_INET},{AF_INET}, {AF_INET},{AF_INET},
#endif #endif
NULL,
NULL, NULL,
doconnect, doconnect,
lognone, lognone,

View File

@ -400,7 +400,7 @@ static int h_include(int argc, unsigned char **argv){
static int h_archiver(int argc, unsigned char **argv){ static int h_archiver(int argc, unsigned char **argv){
int j; int j;
conf.archiver = myalloc(argc * sizeof(char *)); conf.archiver = myalloc(argc * sizeof(unsigned char *));
if(conf.archiver) { if(conf.archiver) {
conf.archiverc = argc; conf.archiverc = argc;
for(j = 0; j < conf.archiverc; j++) conf.archiver[j] = (unsigned char *)mystrdup((char *)argv[j]); for(j = 0; j < conf.archiverc; j++) conf.archiver[j] = (unsigned char *)mystrdup((char *)argv[j]);
@ -532,9 +532,21 @@ static int h_users(int argc, unsigned char **argv){
pwl->password = (unsigned char *) mystrdup((char *)arg + 1); pwl->password = (unsigned char *) mystrdup((char *)arg + 1);
pwl->pwtype = UN; pwl->pwtype = UN;
} }
if(!pwl->password) return 3; if(!pwl->password){
if(pwl->user){
myfree(pwl->user);
}
myfree(pwl);
return 3;
}
}
if(!pwl->user){
if(pwl->password){
myfree(pwl->password);
}
myfree(pwl);
return 21;
} }
if(!pwl->user) return 21;
pthread_mutex_lock(&pwl_mutex); pthread_mutex_lock(&pwl_mutex);
pwl->next = conf.pwl; pwl->next = conf.pwl;
conf.pwl = pwl; conf.pwl = pwl;
@ -715,7 +727,10 @@ static int h_monitor(int argc, unsigned char **argv){
} }
else { else {
fm->path = mystrdup((char *)argv[1]); fm->path = mystrdup((char *)argv[1]);
if(!fm->path) return 21; if(!fm->path){
myfree(fm);
return 21;
}
fm->next = conf.fmon; fm->next = conf.fmon;
conf.fmon = fm; conf.fmon = fm;
} }
@ -743,6 +758,7 @@ static int h_parent(int argc, unsigned char **argv){
chains->weight = (unsigned)atoi((char *)argv[1]); chains->weight = (unsigned)atoi((char *)argv[1]);
if(chains->weight == 0 || chains->weight >1000) { if(chains->weight == 0 || chains->weight >1000) {
fprintf(stderr, "Chaining error: bad chain weight %u line %d\n", chains->weight, linenum); fprintf(stderr, "Chaining error: bad chain weight %u line %d\n", chains->weight, linenum);
myfree(chains);
return(3); return(3);
} }
if(!strcmp((char *)argv[2], "tcp"))chains->type = R_TCP; if(!strcmp((char *)argv[2], "tcp"))chains->type = R_TCP;
@ -762,6 +778,7 @@ static int h_parent(int argc, unsigned char **argv){
else if(!strcmp((char *)argv[2], "smtp"))chains->type = R_SMTP; else if(!strcmp((char *)argv[2], "smtp"))chains->type = R_SMTP;
else { else {
fprintf(stderr, "Chaining error: bad chain type (%s)\n", argv[2]); fprintf(stderr, "Chaining error: bad chain type (%s)\n", argv[2]);
myfree(chains);
return(4); return(4);
} }
cidr = strchr(argv[3], '/'); cidr = strchr(argv[3], '/');
@ -881,11 +898,15 @@ struct ace * make_ace (int argc, unsigned char ** argv){
} }
if(!userl) { if(!userl) {
fprintf(stderr, "No memory for ACL entry, line %d\n", linenum); fprintf(stderr, "No memory for ACL entry, line %d\n", linenum);
freeacl(acl);
return(NULL); return(NULL);
} }
memset(userl, 0, sizeof(struct userlist)); memset(userl, 0, sizeof(struct userlist));
userl->user=(unsigned char*)mystrdup((char *)arg); userl->user=(unsigned char*)mystrdup((char *)arg);
if(!userl->user) return NULL; if(!userl->user){
freeacl(acl);
return NULL;
}
} while((arg = (unsigned char *)strtok((char *)NULL, ","))); } while((arg = (unsigned char *)strtok((char *)NULL, ",")));
} }
if(argc > 1 && strcmp("*", (char *)argv[1])) { if(argc > 1 && strcmp("*", (char *)argv[1])) {
@ -900,11 +921,13 @@ struct ace * make_ace (int argc, unsigned char ** argv){
} }
if(!ipl) { if(!ipl) {
fprintf(stderr, "No memory for ACL entry, line %d\n", linenum); fprintf(stderr, "No memory for ACL entry, line %d\n", linenum);
freeacl(acl);
return(NULL); return(NULL);
} }
memset(ipl, 0, sizeof(struct iplist)); memset(ipl, 0, sizeof(struct iplist));
if (scanipl(arg, ipl)) { if (scanipl(arg, ipl)) {
fprintf(stderr, "Invalid IP, IP range or CIDR, line %d\n", linenum); fprintf(stderr, "Invalid IP, IP range or CIDR, line %d\n", linenum);
freeacl(acl);
return(NULL); return(NULL);
} }
} while((arg = (unsigned char *)strtok((char *)NULL, ","))); } while((arg = (unsigned char *)strtok((char *)NULL, ",")));
@ -928,6 +951,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){
} }
if(!hostnamel){ if(!hostnamel){
fprintf(stderr, "No memory for ACL entry, line %d\n", linenum); fprintf(stderr, "No memory for ACL entry, line %d\n", linenum);
freeacl(acl);
return(NULL); return(NULL);
} }
memset(hostnamel, 0, sizeof(struct hostname)); memset(hostnamel, 0, sizeof(struct hostname));
@ -946,6 +970,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){
hostnamel->name = (unsigned char *) mystrdup( (char *)pattern); hostnamel->name = (unsigned char *) mystrdup( (char *)pattern);
if(!hostnamel->name) { if(!hostnamel->name) {
fprintf(stderr, "No memory for ACL entry, line %d\n", linenum); fprintf(stderr, "No memory for ACL entry, line %d\n", linenum);
freeacl(acl);
return(NULL); return(NULL);
} }
} }
@ -960,6 +985,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){
} }
if(!ipl) { if(!ipl) {
fprintf(stderr, "No memory for ACL entry, line %d\n", linenum); fprintf(stderr, "No memory for ACL entry, line %d\n", linenum);
freeacl(acl);
return(NULL); return(NULL);
} }
*ipl = tmpip; *ipl = tmpip;
@ -978,12 +1004,14 @@ struct ace * make_ace (int argc, unsigned char ** argv){
} }
if(!portl) { if(!portl) {
fprintf(stderr, "No memory for ACL entry, line %d\n", linenum); fprintf(stderr, "No memory for ACL entry, line %d\n", linenum);
freeacl(acl);
return(NULL); return(NULL);
} }
memset(portl, 0, sizeof(struct portlist)); memset(portl, 0, sizeof(struct portlist));
res = sscanf((char *)arg, "%hu-%hu", &portl->startport, &portl->endport); res = sscanf((char *)arg, "%hu-%hu", &portl->startport, &portl->endport);
if(res < 1) { if(res < 1) {
fprintf(stderr, "Invalid port or port range, line %d\n", linenum); fprintf(stderr, "Invalid port or port range, line %d\n", linenum);
freeacl(acl);
return(NULL); return(NULL);
} }
if (res == 1) portl->endport = portl->startport; if (res == 1) portl->endport = portl->startport;
@ -1051,6 +1079,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){
} }
else { else {
fprintf(stderr, "Unknown operation type: %s line %d\n", arg, linenum); fprintf(stderr, "Unknown operation type: %s line %d\n", arg, linenum);
freeacl(acl);
return(NULL); return(NULL);
} }
} while((arg = (unsigned char *)strtok((char *)NULL, ","))); } while((arg = (unsigned char *)strtok((char *)NULL, ",")));
@ -1315,6 +1344,8 @@ static int h_ace(int argc, unsigned char **argv){
tl->cleared = crecord.cleared; tl->cleared = crecord.cleared;
tl->updated = crecord.updated; tl->updated = crecord.updated;
if(tl->cleared < 0 || tl->cleared >= MAX_COUNTER_TIME || tl->updated < 0 || tl->updated >= MAX_COUNTER_TIME){ if(tl->cleared < 0 || tl->cleared >= MAX_COUNTER_TIME || tl->updated < 0 || tl->updated >= MAX_COUNTER_TIME){
myfree(tl);
freeacl(acl);
fprintf(stderr, "Invalid, incompatible or corrupted counter file.\n"); fprintf(stderr, "Invalid, incompatible or corrupted counter file.\n");
return(6); return(6);
} }
@ -1731,6 +1762,7 @@ int readconfig(FILE * fp){
int res = 0; int res = 0;
if( !(buf = myalloc(bufsize)) || ! (argv = myalloc((NPARAMS + 1) * sizeof(unsigned char *))) ) { if( !(buf = myalloc(bufsize)) || ! (argv = myalloc((NPARAMS + 1) * sizeof(unsigned char *))) ) {
if(buf) myfree(buf);
fprintf(stderr, "No memory for configuration"); fprintf(stderr, "No memory for configuration");
return(10); return(10);
} }
@ -1740,6 +1772,8 @@ int readconfig(FILE * fp){
inbuf = (int)(strlen((char *)buf) + 1); inbuf = (int)(strlen((char *)buf) + 1);
argc = parsestr (buf, argv, NPARAMS-1, &buf, &inbuf, &bufsize); argc = parsestr (buf, argv, NPARAMS-1, &buf, &inbuf, &bufsize);
if(argc < 1) { if(argc < 1) {
myfree(buf);
myfree(argv);
fprintf(stderr, "Parse error line %d\n", linenum); fprintf(stderr, "Parse error line %d\n", linenum);
return(11); return(11);
} }
@ -1751,6 +1785,8 @@ int readconfig(FILE * fp){
if(!writable){ if(!writable){
writable = freopen(curconf, "r+", fp); writable = freopen(curconf, "r+", fp);
if(!writable){ if(!writable){
myfree(buf);
myfree(argv);
fprintf(stderr, "Unable to reopen config for writing: %s\n", curconf); fprintf(stderr, "Unable to reopen config for writing: %s\n", curconf);
return 1; return 1;
} }
@ -1764,6 +1800,8 @@ int readconfig(FILE * fp){
res = (*cm->handler)(argc, argv); res = (*cm->handler)(argc, argv);
if(res > 0){ if(res > 0){
fprintf(stderr, "Command: '%s' failed with code %d, line %d\n", argv[0], res, linenum); fprintf(stderr, "Command: '%s' failed with code %d, line %d\n", argv[0], res, linenum);
myfree(buf);
myfree(argv);
return(linenum); return(linenum);
} }
if(!res) break; if(!res) break;
@ -1771,6 +1809,8 @@ int readconfig(FILE * fp){
} }
if(res != 1)continue; if(res != 1)continue;
fprintf(stderr, "Unknown command: '%s' line %d\n", argv[0], linenum); fprintf(stderr, "Unknown command: '%s' line %d\n", argv[0], linenum);
myfree(buf);
myfree(argv);
return(linenum); return(linenum);
} }
myfree(buf); myfree(buf);
@ -1795,12 +1835,16 @@ void freeconf(struct extparam *confp){
struct connlim * cl; struct connlim * cl;
struct trafcount * tc; struct trafcount * tc;
struct passwords *pw; struct passwords *pw;
struct auth *authfuncs;
struct ace *acl; struct ace *acl;
struct filemon *fm; struct filemon *fm;
int counterd, archiverc; int counterd, archiverc;
unsigned char *logname, *logtarget; unsigned char *logname, *logtarget;
unsigned char **archiver; unsigned char **archiver;
unsigned char * logformat; unsigned char * logformat;
char * counterfile;
FILE *stdlog;
char* demanddialprog;
int i; int i;
@ -1835,12 +1879,10 @@ void freeconf(struct extparam *confp){
pthread_mutex_unlock(&pwl_mutex); pthread_mutex_unlock(&pwl_mutex);
/*
logtarget = confp->logtarget; logtarget = confp->logtarget;
confp->logtarget = NULL; confp->logtarget = NULL;
logname = confp->logname; logname = confp->logname;
confp->logname = NULL; confp->logname = NULL;
*/
confp->logfunc = lognone; confp->logfunc = lognone;
logformat = confp->logformat; logformat = confp->logformat;
confp->logformat = NULL; confp->logformat = NULL;
@ -1869,6 +1911,14 @@ void freeconf(struct extparam *confp){
numservers = 0; numservers = 0;
acl = confp->acl; acl = confp->acl;
confp->acl = NULL; confp->acl = NULL;
authfuncs = confp->authfuncs;
confp->authfuncs = NULL;
counterfile = confp->counterfile;
confp->counterfile = NULL;
stdlog = confp->stdlog;
confp->stdlog = NULL;
demanddialprog = confp->demanddialprog;
confp->demanddialprog = NULL;
usleep(SLEEPTIME); usleep(SLEEPTIME);
@ -1882,7 +1932,7 @@ void freeconf(struct extparam *confp){
freeacl(tc->ace); freeacl(tc->ace);
} }
freeauth(authfuncs);
freeacl(acl); freeacl(acl);
freepwl(pw); freepwl(pw);
for(; bl; bl = (struct bandlim *) itfree(bl, bl->next)) freeacl(bl->ace); for(; bl; bl = (struct bandlim *) itfree(bl, bl->next)) freeacl(bl->ace);
@ -1895,14 +1945,12 @@ void freeconf(struct extparam *confp){
for(; fm; fm = (struct filemon *)itfree(fm, fm->next)){ for(; fm; fm = (struct filemon *)itfree(fm, fm->next)){
if(fm->path) myfree(fm->path); if(fm->path) myfree(fm->path);
} }
/*
if(logtarget) { if(logtarget) {
myfree(logtarget); myfree(logtarget);
} }
if(logname) { if(logname) {
myfree(logname); myfree(logname);
} }
*/
if(logformat) { if(logformat) {
myfree(logformat); myfree(logformat);
} }
@ -1911,6 +1959,15 @@ void freeconf(struct extparam *confp){
myfree(archiver); myfree(archiver);
} }
havelog = 0; havelog = 0;
if(counterfile){
myfree(counterfile);
}
if(stdlog){
fclose(stdlog);
}
if(demanddialprog){
myfree(demanddialprog);
}
} }
int reload (void){ int reload (void){

View File

@ -203,6 +203,7 @@ int afdetect(unsigned char *name);
unsigned long myresolver(int, unsigned char *, unsigned char *); unsigned long myresolver(int, unsigned char *, unsigned char *);
unsigned long fakeresolver (int, unsigned char *, unsigned char*); unsigned long fakeresolver (int, unsigned char *, unsigned char*);
int inithashtable(struct hashtable *hashtable, unsigned nhashsize); int inithashtable(struct hashtable *hashtable, unsigned nhashsize);
void destroyhashtable(struct hashtable *ht);
void freeparam(struct clientparam * param); void freeparam(struct clientparam * param);
void clearstat(struct clientparam * param); void clearstat(struct clientparam * param);
void dumpcounters(struct trafcount *tl, int counterd); void dumpcounters(struct trafcount *tl, int counterd);

View File

@ -596,7 +596,6 @@ struct extparam {
struct sockaddr_in extsa; struct sockaddr_in extsa;
#endif #endif
struct passwords *pwl; struct passwords *pwl;
struct auth * authenticate;
AUTHFUNC authfunc; AUTHFUNC authfunc;
LOGFUNC logfunc; LOGFUNC logfunc;
BANDLIMFUNC bandlimfunc; BANDLIMFUNC bandlimfunc;