Handles better the memory utilization

- Added reference counts to Rule and AuditLog;
- Some memory leaks were removed, including GeoLookup;
- Deal better with parser errors;
- Overriding the AutlogLogWritter destructor.
This commit is contained in:
Felipe Zimmerle 2015-07-26 22:40:51 -03:00
parent 0e7c13e3c0
commit e016b72a8e
31 changed files with 385 additions and 169 deletions

View File

@ -157,7 +157,7 @@ class Assay {
int processLogging(int status_code);
ModSecurityIntervention *intervention();
bool intervention(ModSecurityIntervention *it);
void cleanup();
@ -281,7 +281,7 @@ int msc_get_response_body_length(Assay *assay);
void msc_assay_cleanup(Assay *assay);
/** @ingroup ModSecurity_C_API */
ModSecurityIntervention *msc_intervention(Assay *assay);
int msc_intervention(Assay *assay, ModSecurityIntervention *it);
/** @ingroup ModSecurity_C_API */
int msc_process_logging(Assay *assay, int code);

View File

@ -42,7 +42,8 @@ class DebugLog : public std::ofstream {
*/
DebugLog()
: m_is_configured(false),
m_debug_level(0) { }
m_debug_level(0),
m_referenceCount(0) { }
bool setOutputFile(const std::string& file);
virtual bool write_log(int level, const std::string& data);
@ -53,6 +54,9 @@ class DebugLog : public std::ofstream {
virtual DebugLog *new_instance();
void refCountDecreaseAndCheck(void);
void refCountIncrease(void);
private:
/*
ModSecurityDebugLog(ModSecurityDebugLog const&);
@ -60,6 +64,7 @@ class DebugLog : public std::ofstream {
*/
int m_debug_level;
bool m_is_configured;
int m_referenceCount;
};
} // namespace ModSecurity

View File

@ -49,7 +49,7 @@ class Rules : public RulesProperties {
Rules()
: RulesProperties(NULL) { }
Rules(DebugLog *customLog)
explicit Rules(DebugLog *customLog)
: RulesProperties(customLog) { }
~Rules();
@ -75,6 +75,7 @@ class Rules : public RulesProperties {
std::ostringstream parserError;
DebugLog *debugLog;
private:
int m_referenceCount;
};

View File

@ -27,7 +27,6 @@
#include "modsecurity/modsecurity.h"
#include "modsecurity/assay.h"
#include "modsecurity/assay.h"
#ifdef __cplusplus
@ -61,7 +60,7 @@ class RulesProperties {
responseBodyLimitAction(ProcessPartialBodyLimitAction),
secRuleEngine(DetectionOnlyRuleEngine) { }
~RulesProperties() { };
~RulesProperties() { }
std::vector<Rule *> rules[7]; // ModSecurity::Phases::NUMBER_OF_PHASES
@ -174,10 +173,7 @@ class RulesProperties {
AuditLog *audit_log;
OnFailedRemoteRulesAction remoteRulesActionOnFailed;
};
#endif
#ifdef __cplusplus

View File

@ -55,7 +55,7 @@ bool Action::evaluate(Rule *rule) {
void Action::fill_intervention(ModSecurityIntervention *i) {
}
Action *Action::instantiate(std::string name) {
Action *Action::instantiate(const std::string& name) {
std::string status("status:");
std::string redirect("redirect:");
std::string block("block");

View File

@ -14,6 +14,7 @@
*/
#include <string>
#include <iostream>
#include "modsecurity/intervention.h"
@ -31,13 +32,16 @@ namespace actions {
class Action {
public:
explicit Action(std::string _action)
explicit Action(const std::string& _action)
: action_kind(2),
action(_action) { }
explicit Action(std::string _action, int kind)
action(_action),
temporaryAction(false) { }
explicit Action(const std::string& _action, int kind)
: action_kind(kind),
action(_action) { }
action(_action),
temporaryAction(false) { }
virtual ~Action() { }
/**
*
* Define the action kind regarding to the execution time.
@ -79,9 +83,10 @@ class Action {
virtual bool evaluate(Assay *assay);
virtual bool evaluate(Rule *rule);
static Action *instantiate(std::string action);
static Action *instantiate(const std::string& name);
virtual void fill_intervention(ModSecurityIntervention *intervention);
bool temporaryAction;
};

View File

@ -23,12 +23,13 @@
namespace ModSecurity {
namespace actions {
Redirect::Redirect(std::string action)
: Action(action) {
this->url = action;
this->url.erase(0, 9);
this->action = action;
this->action_kind = 2;
Redirect::~Redirect() {
}
Redirect::Redirect(const std::string& action)
: Action(action, RunTimeOnlyIfMatchKind),
url(action) {
this->url = this->url.erase(0, 9);
this->status = 302;
}

View File

@ -30,7 +30,8 @@ namespace actions {
class Redirect : public Action {
public:
explicit Redirect(std::string action);
explicit Redirect(const std::string &action);
~Redirect() override;
bool evaluate(Assay *assay) override;
int status;

View File

@ -128,6 +128,12 @@ Assay::Assay(ModSecurity *ms, Rules *rules)
Assay::~Assay() {
m_responseBody.str(std::string());
m_responseBody.clear();
m_requestBody.str(std::string());
m_requestBody.clear();
m_rules->decrementReferenceCount();
}
@ -637,6 +643,7 @@ int Assay::appendRequestBody(const unsigned char *buf, size_t len) {
debug(5, "Request body limit is marked to reject the " \
"request");
Action *a = new actions::Block("block");
a->temporaryAction = true;
actions.push_back(a);
}
return true;
@ -833,6 +840,7 @@ int Assay::appendResponseBody(const unsigned char *buf, size_t len) {
debug(5, "Response body limit is marked to reject the " \
"request");
Action *a = new actions::Block("block");
a->temporaryAction = true;
actions.push_back(a);
}
return true;
@ -930,12 +938,6 @@ int Assay::processLogging(int returned_code) {
*
*/
void Assay::cleanup() {
m_responseBody.str("");
m_responseBody.clear();
m_requestBody.str("");
m_requestBody.clear();
delete this;
}
@ -946,32 +948,25 @@ void Assay::cleanup() {
*
* Intervention can generate a log event and/or perform a disruptive action.
*
* @return Pointer to ModSecurityIntervention structure
* @retval >0 A intervention should be made.
* @retval NULL Nothing to be done.
* @param Pointer ModSecurityIntervention structure
* @retval true A intervention should be made.
* @retval false Nothing to be done.
*
*/
ModSecurityIntervention *Assay::intervention() {
ModSecurityIntervention *ret = NULL;
/**
* FIXME: Implement this.
*
*/
bool Assay::intervention(ModSecurityIntervention *it) {
bool ret = false;
if (actions.size() > 0) {
for (Action *a : actions) {
if (a->action_kind == Action::Kind::RunTimeOnlyIfMatchKind) {
if (ret == NULL) {
ret = static_cast<ModSecurityIntervention *>(calloc( \
1, sizeof(struct ModSecurityIntervention_t)));
ret->status = 200;
}
a->fill_intervention(ret);
a->fill_intervention(it);
}
if (a->temporaryAction) {
delete a;
}
}
actions.clear();
ret = true;
}
return ret;
}
@ -1684,8 +1679,8 @@ extern "C" void msc_assay_cleanup(Assay *assay) {
* @retval NULL Nothing to be done.
*
*/
extern "C" ModSecurityIntervention *msc_intervention(Assay *assay) {
return assay->intervention();
extern "C" int msc_intervention(Assay *assay, ModSecurityIntervention *it) {
return assay->intervention(it);
}

View File

@ -112,6 +112,7 @@ bool AuditLog::init() {
if (m_type == SerialAuditLogType) {
m_writer = new AuditLogWriterSerial(this);
}
m_writer->refCountIncrease();
if (m_writer == NULL || m_writer->init() == false) {
std::cout << "not able to open the log for write." << std::endl;

View File

@ -44,7 +44,7 @@ class AuditLog {
m_relevant(""),
filePermission(0600),
directoryPermission(0600),
m_refereceCount(1)
m_refereceCount(0)
{ }
~AuditLog();

View File

@ -33,9 +33,9 @@ class AuditLogWriter {
public:
explicit AuditLogWriter(AuditLog *audit)
: m_audit(audit),
m_refereceCount(1) { }
m_refereceCount(0) { }
~AuditLogWriter() { }
virtual ~AuditLogWriter() { }
virtual void refCountIncrease() = 0;
virtual void refCountDecreaseAndCheck() = 0;

View File

@ -31,7 +31,7 @@ class AuditLogWriterParallel : public AuditLogWriter {
explicit AuditLogWriterParallel(AuditLog *audit)
: AuditLogWriter(audit) { }
~AuditLogWriterParallel();
~AuditLogWriterParallel() override;
bool init() override;
bool write(Assay *assay, int parts) override;

View File

@ -37,7 +37,7 @@ class AuditLogWriterSerial : public AuditLogWriter {
explicit AuditLogWriterSerial(AuditLog *audit)
: AuditLogWriter(audit) { }
~AuditLogWriterSerial();
~AuditLogWriterSerial() override;
void refCountIncrease() override {
m_refereceCount++;

View File

@ -123,4 +123,17 @@ bool DebugLog::isConfigured() {
}
void DebugLog::refCountDecreaseAndCheck(void) {
this->m_referenceCount--;
if (this->m_referenceCount == 0) {
delete this;
}
}
void DebugLog::refCountIncrease(void) {
this->m_referenceCount++;
}
} // namespace ModSecurity

View File

@ -24,6 +24,8 @@
#include <curl/curl.h>
#endif
#include "utils/geo_lookup.h"
namespace ModSecurity {
/**
@ -52,6 +54,10 @@ ModSecurity::ModSecurity()
ModSecurity::~ModSecurity() {
#ifdef MSC_WITH_CURL
curl_global_cleanup();
#endif
Utils::GeoLookup::getInstance().cleanUp();
}

View File

@ -32,6 +32,7 @@ Driver::Driver()
Driver::~Driver() {
delete loc.back();
}
@ -70,7 +71,7 @@ int Driver::addSecRule(Rule *rule) {
int Driver::parse(const std::string &f, const std::string &ref) {
loc.push_back(*(new yy::location()));
loc.push_back(new yy::location());
if (ref.empty()) {
this->ref.push_back("<<reference missing or not informed>>");
} else {

View File

@ -75,7 +75,7 @@ class Driver : public RulesProperties {
void error(const yy::location& l, const std::string& m,
const std::string& c);
std::list<yy::location> loc;
std::list<yy::location *> loc;
std::list<std::string> ref;
std::string buffer;

View File

@ -58,6 +58,21 @@ using ModSecurity::Variables::TimeWDay;
using ModSecurity::Variables::TimeYear;
using ModSecurity::Variables::Variable;
/**
* %destructor { code } THING
*
* %destructor is not working as expected. Apparently it was fixed on a most recent,
* version of Bison. We are not interested to limit the usage to this newest version,
* thus, we have to deal with memory leak when rules failed to load. Not that big
* problem, as we don't really continue when it fails (only for SecRemoteRules).
*
* Information about destructor:
* http://www.gnu.org/software/bison/manual/html_node/Destructor-Decl.html
*
* Patch:
* https://www.mail-archive.com/search?l=bug-bison@gnu.org&q=subject:%22Destructor+miscompilation+with+C%2B%2B+variants%3F%22&o=newest&f=1
*/
}
// The parsing context.
%param { ModSecurity::Parser::Driver& driver }
@ -154,6 +169,7 @@ using ModSecurity::Variables::Variable;
%type <std::vector<Action *> *> actions
%type <std::vector<Variable *> *> variables
%printer { yyoutput << $$; } <*>;
%%
%start secrule;

View File

@ -112,96 +112,98 @@ FREE_TEXT_NEW_LINE [^\"|\n]+
%{
// Code run each time a pattern is matched.
# define YY_USER_ACTION driver.loc.back().columns (yyleng);
# define YY_USER_ACTION driver.loc.back()->columns (yyleng);
%}
%%
%{
// Code run each time yylex is called.
driver.loc.back().step();
driver.loc.back()->step();
%}
{DIRECTIVE} { return yy::seclang_parser::make_DIRECTIVE(yytext, driver.loc.back()); }
{TRANSFORMATION} { return yy::seclang_parser::make_TRANSFORMATION(yytext, driver.loc.back()); }
{CONFIG_DIR_RULE_ENG} { return yy::seclang_parser::make_CONFIG_DIR_RULE_ENG(yytext, driver.loc.back()); }
{CONFIG_DIR_RES_BODY} { return yy::seclang_parser::make_CONFIG_DIR_RES_BODY(yytext, driver.loc.back()); }
{CONFIG_DIR_REQ_BODY} { return yy::seclang_parser::make_CONFIG_DIR_REQ_BODY(yytext, driver.loc.back()); }
{DIRECTIVE} { return yy::seclang_parser::make_DIRECTIVE(yytext, *driver.loc.back()); }
{TRANSFORMATION} { return yy::seclang_parser::make_TRANSFORMATION(yytext, *driver.loc.back()); }
{CONFIG_DIR_RULE_ENG} { return yy::seclang_parser::make_CONFIG_DIR_RULE_ENG(yytext, *driver.loc.back()); }
{CONFIG_DIR_RES_BODY} { return yy::seclang_parser::make_CONFIG_DIR_RES_BODY(yytext, *driver.loc.back()); }
{CONFIG_DIR_REQ_BODY} { return yy::seclang_parser::make_CONFIG_DIR_REQ_BODY(yytext, *driver.loc.back()); }
%{ /* Audit log entries */ %}
{CONFIG_DIR_AUDIT_DIR}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_DIR(strchr(yytext, ' ') + 1, driver.loc.back()); }
{CONFIG_DIR_AUDIT_DIR_MOD}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_DIR_MOD(strchr(yytext, ' ') + 1, driver.loc.back()); }
{CONFIG_DIR_AUDIT_ENG} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_ENG(yytext, driver.loc.back()); }
{CONFIG_DIR_AUDIT_FLE_MOD}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_FLE_MOD(strchr(yytext, ' ') + 1, driver.loc.back()); }
{CONFIG_DIR_AUDIT_LOG2}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_LOG2(strchr(yytext, ' ') + 1, driver.loc.back()); }
{CONFIG_DIR_AUDIT_LOG}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_LOG(strchr(yytext, ' ') + 1, driver.loc.back()); }
{CONFIG_DIR_AUDIT_LOG_P}[ ]{AUDIT_PARTS} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_LOG_P(strchr(yytext, ' ') + 1, driver.loc.back()); }
{CONFIG_DIR_AUDIT_STS}[ ]["]{FREE_TEXT}["] { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_STS(strchr(yytext, ' ') + 1, driver.loc.back()); }
{CONFIG_DIR_AUDIT_TPE} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_TPE(yytext, driver.loc.back()); }
{CONFIG_DIR_AUDIT_DIR}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_DIR(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_AUDIT_DIR_MOD}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_DIR_MOD(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_AUDIT_ENG} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_ENG(yytext, *driver.loc.back()); }
{CONFIG_DIR_AUDIT_FLE_MOD}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_FLE_MOD(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_AUDIT_LOG2}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_LOG2(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_AUDIT_LOG}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_LOG(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_AUDIT_LOG_P}[ ]{AUDIT_PARTS} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_LOG_P(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_AUDIT_STS}[ ]["]{FREE_TEXT}["] { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_STS(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_AUDIT_TPE} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_TPE(yytext, *driver.loc.back()); }
%{ /* Debug log entries */ %}
{CONFIG_DIR_DEBUG_LOG}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONFIG_DIR_DEBUG_LOG(strchr(yytext, ' ') + 1, driver.loc.back()); }
{CONFIG_DIR_DEBUG_LVL}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_DEBUG_LVL(strchr(yytext, ' ') + 1, driver.loc.back()); }
{CONFIG_DIR_DEBUG_LOG}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONFIG_DIR_DEBUG_LOG(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_DEBUG_LVL}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_DEBUG_LVL(strchr(yytext, ' ') + 1, *driver.loc.back()); }
%{ /* Variables */ %}
{VARIABLE}:?{DICT_ELEMENT}? { return yy::seclang_parser::make_VARIABLE(yytext, driver.loc.back()); }
{RUN_TIME_VAR_DUR} { return yy::seclang_parser::make_RUN_TIME_VAR_DUR(yytext, driver.loc.back()); }
{RUN_TIME_VAR_ENV}:?{DICT_ELEMENT}? { return yy::seclang_parser::make_RUN_TIME_VAR_ENV(yytext, driver.loc.back()); }
{RUN_TIME_VAR_BLD} { return yy::seclang_parser::make_RUN_TIME_VAR_BLD(yytext, driver.loc.back()); }
{RUN_TIME_VAR_HSV} { return yy::seclang_parser::make_RUN_TIME_VAR_HSV(yytext, driver.loc.back()); }
{VARIABLE}:?{DICT_ELEMENT}? { return yy::seclang_parser::make_VARIABLE(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_DUR} { return yy::seclang_parser::make_RUN_TIME_VAR_DUR(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_ENV}:?{DICT_ELEMENT}? { return yy::seclang_parser::make_RUN_TIME_VAR_ENV(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_BLD} { return yy::seclang_parser::make_RUN_TIME_VAR_BLD(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_HSV} { return yy::seclang_parser::make_RUN_TIME_VAR_HSV(yytext, *driver.loc.back()); }
%{ /* Variables: TIME */ %}
{RUN_TIME_VAR_TIME} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME(yytext, driver.loc.back()); }
{RUN_TIME_VAR_TIME_DAY} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_DAY(yytext, driver.loc.back()); }
{RUN_TIME_VAR_TIME_EPOCH} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_EPOCH(yytext, driver.loc.back()); }
{RUN_TIME_VAR_TIME_HOUR} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_HOUR(yytext, driver.loc.back()); }
{RUN_TIME_VAR_TIME_MIN} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_MIN(yytext, driver.loc.back()); }
{RUN_TIME_VAR_TIME_MON} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_MON(yytext, driver.loc.back()); }
{RUN_TIME_VAR_TIME_SEC} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_SEC(yytext, driver.loc.back()); }
{RUN_TIME_VAR_TIME_WDAY} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_WDAY(yytext, driver.loc.back()); }
{RUN_TIME_VAR_TIME_YEAR} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_YEAR(yytext, driver.loc.back()); }
{RUN_TIME_VAR_TIME} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_TIME_DAY} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_DAY(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_TIME_EPOCH} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_EPOCH(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_TIME_HOUR} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_HOUR(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_TIME_MIN} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_MIN(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_TIME_MON} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_MON(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_TIME_SEC} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_SEC(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_TIME_WDAY} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_WDAY(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_TIME_YEAR} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_YEAR(yytext, *driver.loc.back()); }
%{ /* Geo DB loopkup */ %}
{CONFIG_DIR_GEO_DB}[ ]{FREE_TEXT_NEW_LINE} { return yy::seclang_parser::make_CONFIG_DIR_GEO_DB(strchr(yytext, ' ') + 1, driver.loc.back()); }
{CONFIG_DIR_GEO_DB}[ ]{FREE_TEXT_NEW_LINE} { return yy::seclang_parser::make_CONFIG_DIR_GEO_DB(strchr(yytext, ' ') + 1, *driver.loc.back()); }
%{ /* Request body limit */ %}
{CONFIG_DIR_REQ_BODY_LIMIT}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_REQ_BODY_LIMIT(strchr(yytext, ' ') + 1, driver.loc.back()); }
{CONFIG_DIR_REQ_BODY_LIMIT_ACTION} { return yy::seclang_parser::make_CONFIG_DIR_REQ_BODY_LIMIT_ACTION(yytext, driver.loc.back()); }
{CONFIG_DIR_REQ_BODY_LIMIT}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_REQ_BODY_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_REQ_BODY_LIMIT_ACTION} { return yy::seclang_parser::make_CONFIG_DIR_REQ_BODY_LIMIT_ACTION(yytext, *driver.loc.back()); }
%{ /* Reponse body limit */ %}
{CONFIG_DIR_RES_BODY_LIMIT}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_RES_BODY_LIMIT(strchr(yytext, ' ') + 1, driver.loc.back()); }
{CONFIG_DIR_RES_BODY_LIMIT_ACTION} { return yy::seclang_parser::make_CONFIG_DIR_RES_BODY_LIMIT_ACTION(yytext, driver.loc.back()); }
{CONFIG_DIR_RES_BODY_LIMIT}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_RES_BODY_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_RES_BODY_LIMIT_ACTION} { return yy::seclang_parser::make_CONFIG_DIR_RES_BODY_LIMIT_ACTION(yytext, *driver.loc.back()); }
{CONFIG_COMPONENT_SIG}[ ]["]{FREE_TEXT}["] { return yy::seclang_parser::make_CONFIG_COMPONENT_SIG(strchr(yytext, ' ') + 2, driver.loc.back()); }
{CONFIG_COMPONENT_SIG}[ ]["]{FREE_TEXT}["] { return yy::seclang_parser::make_CONFIG_COMPONENT_SIG(strchr(yytext, ' ') + 2, *driver.loc.back()); }
{CONFIG_VALUE_WARN} { return yy::seclang_parser::make_CONFIG_VALUE_WARN(yytext, driver.loc.back()); }
{CONFIG_VALUE_ABORT} { return yy::seclang_parser::make_CONFIG_VALUE_ABORT(yytext, driver.loc.back()); }
{CONFIG_VALUE_ON} { return yy::seclang_parser::make_CONFIG_VALUE_ON(yytext, driver.loc.back()); }
{CONFIG_VALUE_OFF} { return yy::seclang_parser::make_CONFIG_VALUE_OFF(yytext, driver.loc.back()); }
{CONFIG_VALUE_SERIAL} { return yy::seclang_parser::make_CONFIG_VALUE_SERIAL(yytext, driver.loc.back()); }
{CONFIG_VALUE_PARALLEL} { return yy::seclang_parser::make_CONFIG_VALUE_PARALLEL(yytext, driver.loc.back()); }
{CONFIG_VALUE_DETC} { return yy::seclang_parser::make_CONFIG_VALUE_DETC(yytext, driver.loc.back()); }
{CONFIG_VALUE_RELEVANT_ONLY} { return yy::seclang_parser::make_CONFIG_VALUE_RELEVANT_ONLY(yytext, driver.loc.back()); }
{CONFIG_VALUE_PROCESS_PARTIAL} { return yy::seclang_parser::make_CONFIG_VALUE_PROCESS_PARTIAL(yytext, driver.loc.back()); }
{CONFIG_VALUE_REJECT} { return yy::seclang_parser::make_CONFIG_VALUE_REJECT(yytext, driver.loc.back()); }
{CONFIG_VALUE_WARN} { return yy::seclang_parser::make_CONFIG_VALUE_WARN(yytext, *driver.loc.back()); }
{CONFIG_VALUE_ABORT} { return yy::seclang_parser::make_CONFIG_VALUE_ABORT(yytext, *driver.loc.back()); }
{CONFIG_VALUE_ON} { return yy::seclang_parser::make_CONFIG_VALUE_ON(yytext, *driver.loc.back()); }
{CONFIG_VALUE_OFF} { return yy::seclang_parser::make_CONFIG_VALUE_OFF(yytext, *driver.loc.back()); }
{CONFIG_VALUE_SERIAL} { return yy::seclang_parser::make_CONFIG_VALUE_SERIAL(yytext, *driver.loc.back()); }
{CONFIG_VALUE_PARALLEL} { return yy::seclang_parser::make_CONFIG_VALUE_PARALLEL(yytext, *driver.loc.back()); }
{CONFIG_VALUE_DETC} { return yy::seclang_parser::make_CONFIG_VALUE_DETC(yytext, *driver.loc.back()); }
{CONFIG_VALUE_RELEVANT_ONLY} { return yy::seclang_parser::make_CONFIG_VALUE_RELEVANT_ONLY(yytext, *driver.loc.back()); }
{CONFIG_VALUE_PROCESS_PARTIAL} { return yy::seclang_parser::make_CONFIG_VALUE_PROCESS_PARTIAL(yytext, *driver.loc.back()); }
{CONFIG_VALUE_REJECT} { return yy::seclang_parser::make_CONFIG_VALUE_REJECT(yytext, *driver.loc.back()); }
["]{OPERATOR}[ ]{FREE_TEXT}["] { return yy::seclang_parser::make_OPERATOR(yytext, driver.loc.back()); }
["]{OPERATORNOARG}["] { return yy::seclang_parser::make_OPERATOR(yytext, driver.loc.back()); }
{ACTION} { return yy::seclang_parser::make_ACTION(yytext, driver.loc.back()); }
{ACTION_SEVERITY} { return yy::seclang_parser::make_ACTION_SEVERITY(yytext, driver.loc.back()); }
["] { return yy::seclang_parser::make_QUOTATION_MARK(driver.loc.back()); }
[,] { return yy::seclang_parser::make_COMMA(driver.loc.back()); }
[|] { return yy::seclang_parser::make_PIPE(driver.loc.back()); }
{VARIABLENOCOLON} { return yy::seclang_parser::make_VARIABLE(yytext, driver.loc.back()); }
[ \t]+ { return yy::seclang_parser::make_SPACE(driver.loc.back()); }
[\n]+ { driver.loc.back().lines(yyleng); driver.loc.back().step(); }
. { driver.error (driver.loc.back(), "invalid character", yytext); }
["]{OPERATOR}[ ]{FREE_TEXT}["] { return yy::seclang_parser::make_OPERATOR(yytext, *driver.loc.back()); }
["]{OPERATORNOARG}["] { return yy::seclang_parser::make_OPERATOR(yytext, *driver.loc.back()); }
{ACTION} { return yy::seclang_parser::make_ACTION(yytext, *driver.loc.back()); }
{ACTION_SEVERITY} { return yy::seclang_parser::make_ACTION_SEVERITY(yytext, *driver.loc.back()); }
["] { return yy::seclang_parser::make_QUOTATION_MARK(*driver.loc.back()); }
[,] { return yy::seclang_parser::make_COMMA(*driver.loc.back()); }
[|] { return yy::seclang_parser::make_PIPE(*driver.loc.back()); }
{VARIABLENOCOLON} { return yy::seclang_parser::make_VARIABLE(yytext, *driver.loc.back()); }
[ \t]+ { return yy::seclang_parser::make_SPACE(*driver.loc.back()); }
[\n]+ { driver.loc.back()->lines(yyleng); driver.loc.back()->step(); }
. { driver.error (*driver.loc.back(), "invalid character", yytext); }
<<EOF>> {
if (driver.ref.size() > 0) {
driver.ref.pop_back();
}
if (driver.loc.size() > 1) {
yy::location *l = driver.loc.back();
driver.loc.pop_back();
delete l;
}
if (yyin) {
@ -211,7 +213,7 @@ FREE_TEXT_NEW_LINE [^\"|\n]+
yypop_buffer_state();
if (!YY_CURRENT_BUFFER)
{
return yy::seclang_parser::make_END(driver.loc.back());
return yy::seclang_parser::make_END(*driver.loc.back());
}
}
@ -220,11 +222,11 @@ FREE_TEXT_NEW_LINE [^\"|\n]+
const char *file = strchr(yytext, ' ') + 1;
yyin = fopen(file, "r" );
if (!yyin) {
driver.error (driver.loc.back(), "", yytext + std::string(": Not able to open file."));
throw yy::seclang_parser::syntax_error(driver.loc.back(), "");
driver.error (*driver.loc.back(), "", yytext + std::string(": Not able to open file."));
throw yy::seclang_parser::syntax_error(*driver.loc.back(), "");
}
driver.ref.push_back(file);
driver.loc.push_back(*(new yy::location()));
driver.loc.push_back(new yy::location());
yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE ));
}
@ -238,7 +240,7 @@ FREE_TEXT_NEW_LINE [^\"|\n]+
url = conf[2];
driver.ref.push_back(url);
driver.loc.push_back(*(new yy::location()));
driver.loc.push_back(new yy::location());
YY_BUFFER_STATE temp = YY_CURRENT_BUFFER;
yypush_buffer_state(temp);
@ -249,15 +251,15 @@ FREE_TEXT_NEW_LINE [^\"|\n]+
/** TODO: Implement the server logging mechanism. */
}
if (driver.remoteRulesActionOnFailed == Rules::OnFailedRemoteRulesAction::AbortOnFailedRemoteRulesAction) {
driver.error (driver.loc.back(), "", yytext + std::string(" - Failed to download: ") + c.error);
throw yy::seclang_parser::syntax_error(driver.loc.back(), "");
driver.error (*driver.loc.back(), "", yytext + std::string(" - Failed to download: ") + c.error);
throw yy::seclang_parser::syntax_error(*driver.loc.back(), "");
}
}
yy_scan_string(c.content.c_str());
}
{CONFIG_SEC_REMOTE_RULES_FAIL_ACTION} { return yy::seclang_parser::make_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION(yytext, driver.loc.back()); }
{CONFIG_SEC_REMOTE_RULES_FAIL_ACTION} { return yy::seclang_parser::make_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION(yytext, *driver.loc.back()); }
%%

View File

@ -30,6 +30,7 @@ Multipart::Multipart(std:: string header)
containsDataBefore(false),
lf(false),
missingSemicolon(false),
invalidQuote(false),
boundaryStartsWithWhiteSpace(false),
boundaryIsQuoted(false),
m_header(header) {

View File

@ -34,27 +34,55 @@ using operators::Operator;
using actions::Action;
using Variables::Variable;
Rule::~Rule() {
delete op;
while (actions_conf.empty() == false) {
auto *a = actions_conf.back();
actions_conf.pop_back();
delete a;
}
while (actions_runtime_pre.empty() == false) {
auto *a = actions_runtime_pre.back();
actions_runtime_pre.pop_back();
delete a;
}
while (actions_runtime_pos.empty() == false) {
auto *a = actions_runtime_pos.back();
actions_runtime_pos.pop_back();
delete a;
}
while (variables->empty() == false) {
auto *a = variables->back();
variables->pop_back();
delete a;
}
delete variables;
}
Rule::Rule(Operator *_op,
std::vector<Variable *> *_variables,
std::vector<Action *> *_actions)
std::vector<Action *> *actions)
: chained(false),
chainedRule(NULL),
variables(_variables),
op(_op),
rule_id(0),
phase(-1) {
for (Action *a : *_actions) {
phase(-1),
m_referenceCount(0) {
for (Action *a : *actions) {
if (a->action_kind == Action::ConfigurationKind) {
actions_conf.push_back(a);
a->evaluate(this);
}
if (a->action_kind == Action::RunTimeBeforeMatchAttemptKind) {
} else if (a->action_kind == Action::RunTimeBeforeMatchAttemptKind) {
actions_runtime_pre.push_back(a);
}
if (a->action_kind == Action::RunTimeOnlyIfMatchKind) {
} else if (a->action_kind == Action::RunTimeOnlyIfMatchKind) {
actions_runtime_pos.push_back(a);
} else {
std::cout << "General failure, action: " << a->name;
std::cout << " has an unknown type." << std::endl;
delete a;
}
}
/**
@ -64,6 +92,8 @@ Rule::Rule(Operator *_op,
if (phase == -1) {
phase = ModSecurity::Phases::RequestHeadersPhase;
}
delete actions;
}
bool Rule::evaluate(Assay *assay) {
@ -115,7 +145,8 @@ bool Rule::evaluate(Assay *assay) {
a->evaluate(assay);
}
if (this->chained && this->chainedRule == NULL) {
assay->debug(4, "Rule is marked as chained but there isn't a subsequent rule.");
assay->debug(4, "Rule is marked as chained but there " \
"isn't a subsequent rule.");
}
if (this->chained && this->chainedRule != NULL) {
assay->debug(4, "Executing chained rule.");

View File

@ -34,6 +34,7 @@ class Rule {
std::vector<Variables::Variable *> *_variables,
std::vector<actions::Action *> *_actions);
~Rule();
bool evaluate(Assay *assay);
operators::Operator *op;
@ -47,6 +48,20 @@ class Rule {
Rule *chainedRule;
bool chained;
void refCountDecreaseAndCheck() {
this->m_referenceCount--;
if (this->m_referenceCount == 0) {
delete this;
}
}
void refCountIncrease() {
this->m_referenceCount++;
}
private:
int m_referenceCount;
};
} // namespace ModSecurity

View File

@ -78,7 +78,19 @@ void Rules::decrementReferenceCount(void) {
Rules::~Rules() {
// audit_log->refCountDecreaseAndCheck();
/** Cleanup the rules */
for (int i = 0; i < ModSecurity::Phases::NUMBER_OF_PHASES; i++) {
std::vector<Rule *> rules = this->rules[i];
while (rules.empty() == false) {
Rule *rule = rules.back();
rule->refCountDecreaseAndCheck();
rules.pop_back();
}
}
/** Cleanup audit log */
audit_log->refCountDecreaseAndCheck();
/** Cleanup debug log */
debugLog->refCountDecreaseAndCheck();
}
@ -171,6 +183,7 @@ int Rules::merge(Driver *from) {
for (int j = 0; j < rules.size(); j++) {
Rule *rule = rules[j];
this->rules[i].push_back(rule);
rule->refCountIncrease();
}
}
@ -192,8 +205,10 @@ int Rules::merge(Driver *from) {
} else {
this->debugLog = new DebugLog();
}
this->debugLog->refCountIncrease();
this->audit_log = from->audit_log;
this->audit_log->refCountIncrease();
this->debugLog->setDebugLevel(this->debug_level);
this->debugLog->setOutputFile(this->debug_log_path);
@ -208,6 +223,7 @@ int Rules::merge(Rules *from) {
for (int j = 0; j < rules.size(); j++) {
Rule *rule = rules[j];
this->rules[i].push_back(rule);
rule->refCountIncrease();
}
}
@ -227,8 +243,10 @@ int Rules::merge(Rules *from) {
} else {
this->debugLog = new DebugLog();
}
this->debugLog->refCountIncrease();
this->audit_log = from->audit_log;
this->audit_log->refCountIncrease();
this->debugLog->setDebugLevel(this->debug_level);
this->debugLog->setOutputFile(this->debug_log_path);

View File

@ -30,8 +30,20 @@ namespace ModSecurity {
namespace Utils {
bool GeoLookup::setDataBase(std::string file_path) {
m_gi = GeoIP_open(file_path.c_str(), GEOIP_INDEX_CACHE);
GeoLookup::~GeoLookup() {
cleanUp();
}
void GeoLookup::cleanUp() {
if (m_gi != NULL) {
GeoIP_delete(m_gi);
m_gi = NULL;
}
}
bool GeoLookup::setDataBase(const std::string& filePath) {
m_gi = GeoIP_open(filePath.c_str(), GEOIP_INDEX_CACHE);
if (m_gi == NULL) {
return false;

View File

@ -36,13 +36,15 @@ class GeoLookup {
return instance;
}
bool setDataBase(std::string file_path);
bool setDataBase(const std::string& filePath);
bool lookup(const std::string& target, GeoIPRecord **georec,
std::function<bool(int, std::string)> callback);
void cleanUp();
private:
GeoLookup() : m_gi(NULL) {}
GeoLookup()
: m_gi(NULL) { }
~GeoLookup();
GeoLookup(GeoLookup const&);
void operator=(GeoLookup const&);

View File

@ -40,12 +40,17 @@ std::list<std::pair<std::string, std::string>>
std::map<std::string, std::string> envs;
for (char **current = environ; *current; current++) {
std::string env = std::string(*current);
std::vector<std::string> key_value = split(env, '=');
envs.insert(std::pair<std::string, std::string>("ENV:" + key_value[0],
key_value[1]));
if ("env:" + key_value[0] == name) {
size_t pos = env.find_first_of("=");
if (pos == std::string::npos) {
continue;
}
std::string key = std::string(env, 0, pos);
std::string value = std::string(env, pos+1, env.length() - (pos + 1));
envs.insert(std::pair<std::string, std::string>("ENV:" + key, value));
if ("env:" + key == name) {
std::pair<std::string, std::string> pair;
pair = std::make_pair(name, key_value[1]);
pair = std::make_pair(name, value);
resl.push_back(pair);
return resl;
}

View File

@ -72,6 +72,7 @@ int main(int argc, char *argv[]) {
int i = 0;
ModSecurity::ModSecurity *modsec;
ModSecurity::Rules *rules;
ModSecurity::ModSecurityIntervention it;
modsec = new ModSecurity::ModSecurity();
modsec->setConnectorInformation("ModSecurity-benchmark v0.0.1-alpha" \
@ -86,12 +87,12 @@ int main(int argc, char *argv[]) {
Assay *modsecAssay = new Assay(modsec, rules);
modsecAssay->processConnection(ip, 12345, "127.0.0.1", 80);
if (modsecAssay->intervention()) {
if (modsecAssay->intervention(&it)) {
std::cout << "There is an intervention" << std::endl;
continue;
}
modsecAssay->processURI(request_uri, "GET", "1.1");
if (modsecAssay->intervention()) {
if (modsecAssay->intervention(&it)) {
std::cout << "There is an intervention" << std::endl;
continue;
}
@ -122,7 +123,7 @@ int main(int argc, char *argv[]) {
"no-cache");
modsecAssay->processRequestHeaders();
if (modsecAssay->intervention()) {
if (modsecAssay->intervention(&it)) {
std::cout << "There is an intervention" << std::endl;
continue;
}
@ -130,7 +131,7 @@ int main(int argc, char *argv[]) {
modsecAssay->processRequestBody();
if (modsecAssay->intervention()) {
if (modsecAssay->intervention(&it)) {
std::cout << "There is an intervention" << std::endl;
continue;
}
@ -144,7 +145,7 @@ int main(int argc, char *argv[]) {
modsecAssay->processResponseHeaders();
if (modsecAssay->intervention()) {
if (modsecAssay->intervention(&it)) {
std::cout << "There is an intervention" << std::endl;
continue;
}
@ -154,7 +155,7 @@ int main(int argc, char *argv[]) {
strlen((const char*)response_body));
modsecAssay->processResponseBody();
if (modsecAssay->intervention()) {
if (modsecAssay->intervention(&it)) {
std::cout << "There is an intervention" << std::endl;
continue;
}

View File

@ -85,11 +85,13 @@ bool ModSecurityTest<T>::load_test_json(std::string file) {
vec->push_back(u);
}
}
yajl_tree_free(node);
return true;
}
template <class T>
std::pair<std::string, std::vector<T *>>* ModSecurityTest<T>::load_tests() {
DIR *dir;

View File

@ -44,16 +44,19 @@ void print_help() {
void actions(ModSecurityTestResults<RegressionTest> *r,
ModSecurity::ModSecurityIntervention *it) {
if (it != NULL) {
if (it->pause != 0) {
ModSecurity::Assay *a) {
ModSecurity::ModSecurityIntervention it;
memset(&it, '\0', sizeof(ModSecurity::ModSecurityIntervention));
it.status = 200;
if (a->intervention(&it) == true) {
if (it.pause != 0) {
// FIXME:
}
if (it->status != 0) {
r->status = it->status;
if (it.status != 0) {
r->status = it.status;
}
if (it->url != NULL) {
r->location = it->url;
if (it.url != NULL) {
r->location = it.url;
}
}
}
@ -61,13 +64,13 @@ void actions(ModSecurityTestResults<RegressionTest> *r,
void perform_unit_test(std::vector<RegressionTest *> *tests,
ModSecurityTestResults<RegressionTest> *res, int *count) {
ModSecurity::ModSecurity *modsec;
ModSecurity::Rules *modsec_rules;
ModSecurity::Assay *modsec_assay;
CustomDebugLog *debug_log = new CustomDebugLog();
for (RegressionTest *t : *tests) {
ModSecurity::ModSecurity *modsec = NULL;
ModSecurity::Rules *modsec_rules = NULL;
ModSecurity::Assay *modsec_assay = NULL;
ModSecurityTestResults<RegressionTest> r;
r.status = 200;
(*count)++;
@ -123,7 +126,7 @@ void perform_unit_test(std::vector<RegressionTest *> *tests,
modsec_assay->processConnection(t->clientIp.c_str(),
t->clientPort, t->serverIp.c_str(), t->serverPort);
actions(&r, modsec_assay->intervention());
actions(&r, modsec_assay);
if (r.status != 200) {
goto end;
}
@ -131,7 +134,7 @@ void perform_unit_test(std::vector<RegressionTest *> *tests,
modsec_assay->processURI(t->uri.c_str(), t->protocol.c_str(),
t->httpVersion.c_str());
actions(&r, modsec_assay->intervention());
actions(&r, modsec_assay);
if (r.status != 200) {
goto end;
}
@ -143,7 +146,7 @@ void perform_unit_test(std::vector<RegressionTest *> *tests,
}
modsec_assay->processRequestHeaders();
actions(&r, modsec_assay->intervention());
actions(&r, modsec_assay);
if (r.status != 200) {
goto end;
}
@ -152,7 +155,7 @@ void perform_unit_test(std::vector<RegressionTest *> *tests,
(unsigned char *)t->request_body.c_str(),
t->request_body.size());
modsec_assay->processRequestBody();
actions(&r, modsec_assay->intervention());
actions(&r, modsec_assay);
if (r.status != 200) {
goto end;
}
@ -164,7 +167,7 @@ void perform_unit_test(std::vector<RegressionTest *> *tests,
}
modsec_assay->processResponseHeaders();
actions(&r, modsec_assay->intervention());
actions(&r, modsec_assay);
if (r.status != 200) {
goto end;
}
@ -173,7 +176,7 @@ void perform_unit_test(std::vector<RegressionTest *> *tests,
(unsigned char *)t->response_body.c_str(),
t->response_body.size());
modsec_assay->processResponseBody();
actions(&r, modsec_assay->intervention());
actions(&r, modsec_assay);
if (r.status != 200) {
goto end;
}
@ -208,6 +211,8 @@ after_debug_log:
res->insert(res->end(), r.begin(), r.end());
}
delete debug_log;
}
@ -241,7 +246,7 @@ int main(int argc, char **argv) {
}
keyList.sort();
for (std::string a : keyList) {
for (std::string &a : keyList) {
std::vector<RegressionTest *> *tests = test[a];
ModSecurityTestResults<RegressionTest> res;
@ -251,8 +256,13 @@ int main(int argc, char **argv) {
}
test_log.close();
for (std::pair<std::string, std::vector<RegressionTest *> *> a : test) {
std::vector<RegressionTest *> *vec = a.second;
for (int i = 0; i < vec->size(); i++) {
delete vec->at(i);
}
delete vec;
}
return 0;
}

View File

@ -0,0 +1,76 @@
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:_Znwm
fun:_ZN2yy14seclang_parser5parseEv
fun:_ZN11ModSecurity6Parser6Driver5parseERKSsS3_
fun:_ZN11ModSecurity5Rules4loadEPKcRKSs
fun:_Z17perform_unit_testPSt6vectorIPN16modsecurity_test14RegressionTestESaIS2_EEPNS0_22ModSecurityTestResultsIS1_EEPi
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:yyalloc
fun:_Z14yy_scan_bufferPcm
fun:_Z13yy_scan_bytesPKcm
fun:_ZN11ModSecurity6Parser6Driver10scan_beginEv
fun:_ZN11ModSecurity6Parser6Driver5parseERKSsS3_
fun:_ZN11ModSecurity5Rules4loadEPKcRKSs
fun:_Z17perform_unit_testPSt6vectorIPN16modsecurity_test14RegressionTestESaIS2_EEPNS0_22ModSecurityTestResultsIS1_EEPi
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:_Znwm
fun:_Z17perform_unit_testPSt6vectorIPN16modsecurity_test14RegressionTestESaIS2_EEPNS0_22ModSecurityTestResultsIS1_EEPi
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:_Znwm
fun:_Z17perform_unit_testPSt6vectorIPN16modsecurity_test14RegressionTestESaIS2_EEPNS0_22ModSecurityTestResultsIS1_EEPi
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:_Znwm
fun:_ZN11ModSecurity5Rules4loadEPKcRKSs
fun:_Z17perform_unit_testPSt6vectorIPN16modsecurity_test14RegressionTestESaIS2_EEPNS0_22ModSecurityTestResultsIS1_EEPi
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:yyalloc
fun:_Z16yy_create_bufferP8_IO_FILEi
fun:_Z5yylexRN11ModSecurity6Parser6DriverE
fun:_ZN2yy14seclang_parser5parseEv
fun:_ZN11ModSecurity6Parser6Driver5parseERKSsS3_
fun:_ZN11ModSecurity5Rules4loadEPKcRKSs
fun:_Z17perform_unit_testPSt6vectorIPN16modsecurity_test14RegressionTestESaIS2_EEPNS0_22ModSecurityTestResultsIS1_EEPi
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:_Znwm
fun:_ZN11ModSecurity8AuditLog4initEv
fun:_ZN11ModSecurity6Parser6Driver5parseERKSsS3_
fun:_ZN11ModSecurity5Rules4loadEPKcRKSs
fun:_Z17perform_unit_testPSt6vectorIPN16modsecurity_test14RegressionTestESaIS2_EEPNS0_22ModSecurityTestResultsIS1_EEPi
fun:main
}