From a65286eb9d47b16700edf24c80067606b4a66aa5 Mon Sep 17 00:00:00 2001 From: Daniel Winzen Date: Wed, 7 Dec 2022 00:01:52 +0100 Subject: [PATCH] Fix memory leaks related to configuration --- src/3proxy.c | 46 ++++++++++++++++------------- src/common.c | 1 - src/conf.c | 77 +++++++++++++++++++++++++++++++++++++++++------- src/proxy.h | 1 + src/structures.h | 1 - 5 files changed, 94 insertions(+), 32 deletions(-) diff --git a/src/3proxy.c b/src/3proxy.c index c83b372..da705ee 100644 --- a/src/3proxy.c +++ b/src/3proxy.c @@ -169,7 +169,7 @@ int timechanged (time_t oldtime, time_t newtime, ROTATION lt){ )return 1; break; default: - break; + break; } return 0; } @@ -204,12 +204,12 @@ void dumpcounters(struct trafcount *tlin, int counterd){ conf.time = time(0); if(cheader.updated && conf.countertype && timechanged(cheader.updated, conf.time, conf.countertype)){ FILE * cfp; - + cfp = fopen((char *)dologname(tmpbuf, (unsigned char *)conf.counterfile, NULL, conf.countertype, cheader.updated), "w"); if(cfp){ for(tl = tlin; cfp && tl; tl = tl->next){ 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); } @@ -218,10 +218,10 @@ void dumpcounters(struct trafcount *tlin, int counterd){ cheader.updated = conf.time; 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){ if(tl->number){ - lseek(counterd, + lseek(counterd, sizeof(struct counter_header) + (tl->number - 1) * sizeof(struct counter_record), SEEK_SET); crecord.traf64 = tl->traf64; @@ -245,7 +245,7 @@ void cyclestep(void){ minutecounter = time(0); for(;;){ usleep(SLEEPTIME*999); - + conf.time = time(0); if(conf.needreload) { doschedule(); @@ -266,7 +266,7 @@ void cyclestep(void){ } } } - + } if(timechanged(basetime, conf.time, DAILY)) { tm = localtime(&conf.time); @@ -336,7 +336,7 @@ void cyclestep(void){ usleep(SLEEPTIME*999); return; } - + } } @@ -392,11 +392,11 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int sprintf((char *)tmpbuf, "%s will be installed and started.\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]); if(MessageBox(NULL, (LPCSTR)tmpbuf, (LPCSTR)conf.stringtable[2], MB_YESNO|MB_ICONASTERISK) != IDYES) return 1; - + *tmpbuf = '\"'; if (!(res = SearchPath(NULL, argv[0], ".exe", 256, (char *)tmpbuf+1, (LPTSTR*)&arg))) { perror("Failed to find executable filename"); @@ -427,7 +427,7 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int else { HKEY runsrv; - if(RegOpenKeyEx( HKEY_LOCAL_MACHINE, + if(RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices", 0, KEY_ALL_ACCESS, @@ -468,7 +468,7 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int } else { HKEY runsrv; - if(RegOpenKeyEx( HKEY_LOCAL_MACHINE, + if(RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices", 0, KEY_ALL_ACCESS, @@ -530,22 +530,22 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int if(!writable)fclose(fp); #ifdef _WIN32 - + #ifndef _WINCE if(service){ - SERVICE_TABLE_ENTRY ste[] = + SERVICE_TABLE_ENTRY ste[] = { - { (LPSTR)conf.stringtable[1], (LPSERVICE_MAIN_FUNCTION)ServiceMain}, - { NULL, NULL } - }; - if(!StartServiceCtrlDispatcher( ste ))cyclestep(); + { (LPSTR)conf.stringtable[1], (LPSERVICE_MAIN_FUNCTION)ServiceMain}, + { NULL, NULL } + }; + if(!StartServiceCtrlDispatcher( ste ))cyclestep(); } - else + else #endif { cyclestep(); } - + #else signal(SIGCONT, mysigpause); @@ -558,6 +558,12 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int CLEARRETURN: + freeconf(&conf); + myfree(conf.conffile); + freeauth(conf.authfuncs); + destroyhashtable(&dns_table); + destroyhashtable(&dns6_table); + fprintf(stderr, "hi\n"); return 0; } diff --git a/src/common.c b/src/common.c index e8106e2..dd4b7f6 100644 --- a/src/common.c +++ b/src/common.c @@ -114,7 +114,6 @@ struct extparam conf = { #else {AF_INET},{AF_INET}, #endif - NULL, NULL, doconnect, lognone, diff --git a/src/conf.c b/src/conf.c index 3d7a545..11ecbfa 100644 --- a/src/conf.c +++ b/src/conf.c @@ -400,7 +400,7 @@ static int h_include(int argc, unsigned char **argv){ static int h_archiver(int argc, unsigned char **argv){ int j; - conf.archiver = myalloc(argc * sizeof(char *)); + conf.archiver = myalloc(argc * sizeof(unsigned char *)); if(conf.archiver) { conf.archiverc = argc; 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->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); pwl->next = conf.pwl; conf.pwl = pwl; @@ -715,7 +727,10 @@ static int h_monitor(int argc, unsigned char **argv){ } else { fm->path = mystrdup((char *)argv[1]); - if(!fm->path) return 21; + if(!fm->path){ + myfree(fm); + return 21; + } fm->next = conf.fmon; conf.fmon = fm; } @@ -743,6 +758,7 @@ static int h_parent(int argc, unsigned char **argv){ chains->weight = (unsigned)atoi((char *)argv[1]); if(chains->weight == 0 || chains->weight >1000) { fprintf(stderr, "Chaining error: bad chain weight %u line %d\n", chains->weight, linenum); + myfree(chains); return(3); } 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 { fprintf(stderr, "Chaining error: bad chain type (%s)\n", argv[2]); + myfree(chains); return(4); } cidr = strchr(argv[3], '/'); @@ -881,11 +898,15 @@ struct ace * make_ace (int argc, unsigned char ** argv){ } if(!userl) { fprintf(stderr, "No memory for ACL entry, line %d\n", linenum); + freeacl(acl); return(NULL); } memset(userl, 0, sizeof(struct userlist)); 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, ","))); } if(argc > 1 && strcmp("*", (char *)argv[1])) { @@ -900,11 +921,13 @@ struct ace * make_ace (int argc, unsigned char ** argv){ } if(!ipl) { fprintf(stderr, "No memory for ACL entry, line %d\n", linenum); + freeacl(acl); return(NULL); } memset(ipl, 0, sizeof(struct iplist)); if (scanipl(arg, ipl)) { fprintf(stderr, "Invalid IP, IP range or CIDR, line %d\n", linenum); + freeacl(acl); return(NULL); } } while((arg = (unsigned char *)strtok((char *)NULL, ","))); @@ -928,6 +951,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){ } if(!hostnamel){ fprintf(stderr, "No memory for ACL entry, line %d\n", linenum); + freeacl(acl); return(NULL); } 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); if(!hostnamel->name) { fprintf(stderr, "No memory for ACL entry, line %d\n", linenum); + freeacl(acl); return(NULL); } } @@ -960,6 +985,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){ } if(!ipl) { fprintf(stderr, "No memory for ACL entry, line %d\n", linenum); + freeacl(acl); return(NULL); } *ipl = tmpip; @@ -978,12 +1004,14 @@ struct ace * make_ace (int argc, unsigned char ** argv){ } if(!portl) { fprintf(stderr, "No memory for ACL entry, line %d\n", linenum); + freeacl(acl); return(NULL); } memset(portl, 0, sizeof(struct portlist)); res = sscanf((char *)arg, "%hu-%hu", &portl->startport, &portl->endport); if(res < 1) { fprintf(stderr, "Invalid port or port range, line %d\n", linenum); + freeacl(acl); return(NULL); } if (res == 1) portl->endport = portl->startport; @@ -1051,6 +1079,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){ } else { fprintf(stderr, "Unknown operation type: %s line %d\n", arg, linenum); + freeacl(acl); return(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->updated = crecord.updated; 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"); return(6); } @@ -1731,6 +1762,7 @@ int readconfig(FILE * fp){ int res = 0; if( !(buf = myalloc(bufsize)) || ! (argv = myalloc((NPARAMS + 1) * sizeof(unsigned char *))) ) { + if(buf) myfree(buf); fprintf(stderr, "No memory for configuration"); return(10); } @@ -1740,6 +1772,8 @@ int readconfig(FILE * fp){ inbuf = (int)(strlen((char *)buf) + 1); argc = parsestr (buf, argv, NPARAMS-1, &buf, &inbuf, &bufsize); if(argc < 1) { + myfree(buf); + myfree(argv); fprintf(stderr, "Parse error line %d\n", linenum); return(11); } @@ -1751,6 +1785,8 @@ int readconfig(FILE * fp){ if(!writable){ writable = freopen(curconf, "r+", fp); if(!writable){ + myfree(buf); + myfree(argv); fprintf(stderr, "Unable to reopen config for writing: %s\n", curconf); return 1; } @@ -1764,6 +1800,8 @@ int readconfig(FILE * fp){ res = (*cm->handler)(argc, argv); if(res > 0){ fprintf(stderr, "Command: '%s' failed with code %d, line %d\n", argv[0], res, linenum); + myfree(buf); + myfree(argv); return(linenum); } if(!res) break; @@ -1771,6 +1809,8 @@ int readconfig(FILE * fp){ } if(res != 1)continue; fprintf(stderr, "Unknown command: '%s' line %d\n", argv[0], linenum); + myfree(buf); + myfree(argv); return(linenum); } myfree(buf); @@ -1795,12 +1835,16 @@ void freeconf(struct extparam *confp){ struct connlim * cl; struct trafcount * tc; struct passwords *pw; + struct auth *authfuncs; struct ace *acl; struct filemon *fm; int counterd, archiverc; unsigned char *logname, *logtarget; unsigned char **archiver; unsigned char * logformat; + char * counterfile; + FILE *stdlog; + char* demanddialprog; int i; @@ -1835,12 +1879,10 @@ void freeconf(struct extparam *confp){ pthread_mutex_unlock(&pwl_mutex); -/* logtarget = confp->logtarget; confp->logtarget = NULL; logname = confp->logname; confp->logname = NULL; -*/ confp->logfunc = lognone; logformat = confp->logformat; confp->logformat = NULL; @@ -1869,6 +1911,14 @@ void freeconf(struct extparam *confp){ numservers = 0; acl = confp->acl; 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); @@ -1882,7 +1932,7 @@ void freeconf(struct extparam *confp){ freeacl(tc->ace); } - + freeauth(authfuncs); freeacl(acl); freepwl(pw); 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)){ if(fm->path) myfree(fm->path); } -/* if(logtarget) { myfree(logtarget); } if(logname) { myfree(logname); } -*/ if(logformat) { myfree(logformat); } @@ -1911,6 +1959,15 @@ void freeconf(struct extparam *confp){ myfree(archiver); } havelog = 0; + if(counterfile){ + myfree(counterfile); + } + if(stdlog){ + fclose(stdlog); + } + if(demanddialprog){ + myfree(demanddialprog); + } } int reload (void){ diff --git a/src/proxy.h b/src/proxy.h index f9be0b4..03a1517 100644 --- a/src/proxy.h +++ b/src/proxy.h @@ -203,6 +203,7 @@ int afdetect(unsigned char *name); unsigned long myresolver(int, unsigned char *, unsigned char *); unsigned long fakeresolver (int, unsigned char *, unsigned char*); int inithashtable(struct hashtable *hashtable, unsigned nhashsize); +void destroyhashtable(struct hashtable *ht); void freeparam(struct clientparam * param); void clearstat(struct clientparam * param); void dumpcounters(struct trafcount *tl, int counterd); diff --git a/src/structures.h b/src/structures.h index d41e8a8..db09675 100644 --- a/src/structures.h +++ b/src/structures.h @@ -596,7 +596,6 @@ struct extparam { struct sockaddr_in extsa; #endif struct passwords *pwl; - struct auth * authenticate; AUTHFUNC authfunc; LOGFUNC logfunc; BANDLIMFUNC bandlimfunc;