diff --git a/iis/moduleconfig.h b/iis/moduleconfig.h index 75ee71dca..5160205db 100644 --- a/iis/moduleconfig.h +++ b/iis/moduleconfig.h @@ -69,6 +69,9 @@ class MODSECURITY_STORED_CONTEXT : public IHttpStoredContext void* m_Config; + time_t configFailTime = 0; + bool configLoadingFailed = false; + private: HRESULT GetBooleanPropertyValue( diff --git a/iis/mymodule.cpp b/iis/mymodule.cpp index dfaee4b2c..f00cc2f57 100644 --- a/iis/mymodule.cpp +++ b/iis/mymodule.cpp @@ -17,6 +17,8 @@ #undef inline #define inline inline +#include + #include "winsock2.h" // IIS7 Server API header file @@ -726,6 +728,7 @@ CMyHttpModule::OnBeginRequest( UNREFERENCED_PARAMETER ( pProvider ); + time_t curr_time = time(NULL); EnterCriticalSection(&m_csLock); if ( pHttpContext == NULL ) @@ -746,9 +749,9 @@ CMyHttpModule::OnBeginRequest( if ( FAILED( hr ) ) { - //hr = E_UNEXPECTED; - hr = S_OK; - goto Finished; + pHttpContext->GetResponse()->SetStatus(500, "WAF internal error. Unable to get config."); + pHttpContext->SetRequestHandled(); + return RQ_NOTIFICATION_FINISH_REQUEST; } // If module is disabled, dont go any further @@ -758,6 +761,26 @@ CMyHttpModule::OnBeginRequest( goto Finished; } + auto reportConfigurationError = [pConfig, pHttpContext, this] { + pConfig->configLoadingFailed = true; + pHttpContext->GetResponse()->SetStatus(500, "WAF internal error. Invalid configuration."); + pHttpContext->SetRequestHandled(); + LeaveCriticalSection(&m_csLock); + return RQ_NOTIFICATION_FINISH_REQUEST; + }; + + // If we previously failed to load the config, try again if 10sec passed + if (pConfig->configLoadingFailed) + { + if (difftime(curr_time, pConfig->configFailTime) < 10) { + return reportConfigurationError(); + } + else { + WriteEventViewerLog("Recycling w3wp worker due to config load fail", EVENTLOG_ERROR_TYPE); + g_pHttpServer->RecycleProcess(L"ModSecurity config load failed"); + } + } + if(pConfig->m_Config == NULL) { char *path; @@ -767,8 +790,8 @@ CMyHttpModule::OnBeginRequest( if ( FAILED( hr ) ) { - hr = E_UNEXPECTED; - goto Finished; + pConfig->configFailTime = curr_time; + return reportConfigurationError(); } pConfig->m_Config = modsecGetDefaultConfig(); @@ -782,8 +805,8 @@ CMyHttpModule::OnBeginRequest( if ( FAILED( hr ) ) { delete path; - hr = E_UNEXPECTED; - goto Finished; + pConfig->configFailTime = curr_time; + return reportConfigurationError(); } if(path[0] != 0) @@ -793,9 +816,10 @@ CMyHttpModule::OnBeginRequest( if(err != NULL) { WriteEventViewerLog(err, EVENTLOG_ERROR_TYPE); + pConfig->configFailTime = curr_time; delete apppath; delete path; - goto Finished; + return reportConfigurationError(); } modsecReportRemoteLoadedRules();