mirror of
https://github.com/3proxy/3proxy.git
synced 2026-10-28 22:05:48 +08:00
Fix memory leaks found under AddressSanitizer
- readconfig() kept its line buffer and argument array on every error
return, so each refused reload leaked them.
- A filter refusing a connection in filter_client (TLS: a failed
handshake) was not kept, so its filter_clear never ran and the state
it made was lost. makefilters() now clears it, and empties the slot
first, which is not cleared when it is allocated.
- ssl_filter_close() freed the client CA paths but not the server ones,
for every TLS service set up.
(cherry picked from commit 796e9f8, without what 0.9 does not have:
compiled patterns in ACLs and httpsrv rules)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
86457c3024
commit
20302a67ff
17
src/conf.c
17
src/conf.c
@ -1936,6 +1936,7 @@ int readconfig(FILE * fp){
|
||||
|
||||
if( !(buf = malloc(bufsize)) || ! (argv = malloc((NPARAMS + 1) * sizeof(unsigned char *))) ) {
|
||||
fprintf(stderr, "No memory for configuration");
|
||||
if(buf) free(buf);
|
||||
return(10);
|
||||
}
|
||||
for (linenum = 1; fgets((char *)buf, STRINGBUF, fp); linenum++){
|
||||
@ -1945,7 +1946,8 @@ int readconfig(FILE * fp){
|
||||
argc = parsestr (buf, argv, NPARAMS-1, &buf, &inbuf, &bufsize);
|
||||
if(argc < 1) {
|
||||
fprintf(stderr, "Parse error line %d\n", linenum);
|
||||
return(11);
|
||||
res = 11;
|
||||
goto DONE;
|
||||
}
|
||||
argv[argc] = NULL;
|
||||
if(!strcmp((char *)argv[0], "end") && argc == 1) {
|
||||
@ -1967,23 +1969,28 @@ int readconfig(FILE * fp){
|
||||
if(!strcmp((char *)argv[0], (char *)cm->command)){
|
||||
if(argc < cm->minargs || (cm->maxargs && argc > cm->maxargs)){
|
||||
fprintf(stderr, "Command: '%s' wrong number of arguments , line %d\n", argv[0], linenum);
|
||||
return(linenum);
|
||||
res = linenum;
|
||||
goto DONE;
|
||||
}
|
||||
res = (*cm->handler)(argc, argv);
|
||||
if(res > 0){
|
||||
fprintf(stderr, "Command: '%s' failed with code %d, line %d\n", argv[0], res, linenum);
|
||||
return(linenum);
|
||||
res = linenum;
|
||||
goto DONE;
|
||||
}
|
||||
if(!res) break;
|
||||
}
|
||||
}
|
||||
if(res != 1)continue;
|
||||
fprintf(stderr, "Unknown command: '%s' line %d\n", argv[0], linenum);
|
||||
return(linenum);
|
||||
res = linenum;
|
||||
goto DONE;
|
||||
}
|
||||
res = 0;
|
||||
DONE:
|
||||
free(buf);
|
||||
free(argv);
|
||||
return 0;
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1694,9 +1694,17 @@ FILTER_ACTION makefilters (struct srvparam *srv, struct clientparam *param){
|
||||
|
||||
for(i=0; i<srv->nfilters; i++){
|
||||
if(!srv->filter[i].filter_client)continue;
|
||||
/* the slots are not cleared when they are allocated */
|
||||
param->filters[param->nfilters].data = NULL;
|
||||
action = (*srv->filter[i].filter_client)(srv->filter[i].data, param, ¶m->filters[param->nfilters].data);
|
||||
if(action == PASS) continue;
|
||||
if(action > CONTINUE) return action;
|
||||
if(action > CONTINUE) {
|
||||
/* a filter refusing the connection is not kept, but it may
|
||||
have made a state for it */
|
||||
if(srv->filter[i].filter_clear && param->filters[param->nfilters].data)
|
||||
(*srv->filter[i].filter_clear)(param->filters[param->nfilters].data);
|
||||
return action;
|
||||
}
|
||||
param->filters[param->nfilters].filter = srv->filter + i;
|
||||
if(srv->filter[i].filter_request)param->reqfilters[param->nreqfilters++] = param->filters + param->nfilters;
|
||||
if(srv->filter[i].filter_connect)param->connectfilters[param->nconnectfilters++] = param->filters + param->nfilters;
|
||||
|
||||
@ -867,6 +867,9 @@ static void ssl_filter_close(void *fo){
|
||||
free(CONFIG->client_ca_file);
|
||||
free(CONFIG->client_ca_dir);
|
||||
free(CONFIG->client_ca_store);
|
||||
free(CONFIG->server_ca_file);
|
||||
free(CONFIG->server_ca_dir);
|
||||
free(CONFIG->server_ca_store);
|
||||
free(CONFIG->client_sni);
|
||||
if(CONFIG->client_alpn_protos.protos_len){
|
||||
free(CONFIG->client_alpn_protos.protos);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user