Fix potential use-after-free on filters, add SSL_shutdown in SSLPlugin
Some checks are pending
C/C++ CI / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI / ${{ matrix.target }} (windows-2022) (push) Waiting to run

This commit is contained in:
Vladimir Dubrovin 2026-03-26 20:46:54 +03:00
parent be8fa4542c
commit a2edecfbad
3 changed files with 28 additions and 20 deletions

View File

@ -251,6 +251,7 @@ int
return shutdown(s, how);
}
int WINAPI def_closesocket(void* state, SOCKET s){
usleep(SLEEPTIME);
return closesocket(s);
}
#else

View File

@ -110,11 +110,13 @@ static void addSSL(
void delSSL(void *state, SOCKET s){
if(!state || s == INVALID_SOCKET) return;
if(STATE->cli.s == s) {
SSL_shutdown(STATE->cli.conn);
ssl_conn_free(STATE->cli.conn);
STATE->cli.conn = NULL;
STATE->cli.s = INVALID_SOCKET;
}
else if(STATE->srv.s == s) {
SSL_shutdown(STATE->srv.conn);
ssl_conn_free(STATE->srv.conn);
STATE->srv.conn = NULL;
STATE->srv.s = INVALID_SOCKET;
@ -630,8 +632,13 @@ static FILTER_ACTION ssl_filter_predata(void *fc, struct clientparam * param){
}
static void ssl_filter_clear(void *fc){
free(fc);
static void ssl_filter_clear(void *state){
struct clientparam *param;
if(!state) return;
param = STATE->param;
free(state);
param->sostate = NULL;
}
#define CONFIG ((SSL_CONFIG *)fo)

View File

@ -1072,24 +1072,6 @@ void srvfree(struct srvparam * srv){
void freeparam(struct clientparam * param) {
if(param->res == 2) return;
if(param->datfilterssrv) myfree(param->datfilterssrv);
#ifndef STDMAIN
if(param->reqfilters) myfree(param->reqfilters);
if(param->connectfilters) myfree(param->connectfilters);
if(param->afterauthfilters) myfree(param->afterauthfilters);
if(param->hdrfilterscli) myfree(param->hdrfilterscli);
if(param->hdrfilterssrv) myfree(param->hdrfilterssrv);
if(param->predatfilters) myfree(param->predatfilters);
if(param->datfilterscli) myfree(param->datfilterscli);
if(param->filters){
if(param->nfilters)while(param->nfilters--){
if(param->filters[param->nfilters].filter->filter_clear)
(*param->filters[param->nfilters].filter->filter_clear)(param->filters[param->nfilters].data);
}
myfree(param->filters);
}
if(param->connlim) stopconnlims(param);
#endif
if(param->clibuf) myfree(param->clibuf);
if(param->srvbuf) myfree(param->srvbuf);
if(param->ctrlsocksrv != INVALID_SOCKET && param->ctrlsocksrv != param->remsock) {
@ -1108,6 +1090,24 @@ void freeparam(struct clientparam * param) {
param->srv->so._shutdown(param->sostate, param->clisock, SHUT_RDWR);
param->srv->so._closesocket(param->sostate, param->clisock);
}
if(param->datfilterssrv) myfree(param->datfilterssrv);
#ifndef STDMAIN
if(param->reqfilters) myfree(param->reqfilters);
if(param->connectfilters) myfree(param->connectfilters);
if(param->afterauthfilters) myfree(param->afterauthfilters);
if(param->hdrfilterscli) myfree(param->hdrfilterscli);
if(param->hdrfilterssrv) myfree(param->hdrfilterssrv);
if(param->predatfilters) myfree(param->predatfilters);
if(param->datfilterscli) myfree(param->datfilterscli);
if(param->filters){
if(param->nfilters)while(param->nfilters--){
if(param->filters[param->nfilters].filter->filter_clear)
(*param->filters[param->nfilters].filter->filter_clear)(param->filters[param->nfilters].data);
}
myfree(param->filters);
}
if(param->connlim) stopconnlims(param);
#endif
if(param->srv){
if(param->srv->so.freefunc) param->srv->so.freefunc(param->sostate);
pthread_mutex_lock(&param->srv->counter_mutex);