Skip to content

Commit beaa452

Browse files
committed
Fix memory leak of validateDTD's dtd object
1 parent a9edee3 commit beaa452

File tree

3 files changed

+35
-22
lines changed

3 files changed

+35
-22
lines changed

CHANGES

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
v3.x.y - YYYY-MMM-DD (to be released)
22
-------------------------------------
33

4+
- Fix memory leak of validateDTD's dtd object
5+
[Issue #3008 - @martinhsv, @zimmerle]
46
- Fix memory leaks in ValidateSchema
57
[Issue #3005 - @martinhsv, @zimmerle]
68
- Add support for expirevar action

src/operators/validate_dtd.cc

+15-16
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* ModSecurity, http://www.modsecurity.org/
3-
* Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)
3+
* Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)
44
*
55
* You may not use this file except in compliance with
66
* the License. You may obtain a copy of the License at
@@ -43,25 +43,24 @@ bool ValidateDTD::init(const std::string &file, std::string *error) {
4343
}
4444

4545

46-
bool ValidateDTD::evaluate(Transaction *t, const std::string &str) {
47-
xmlValidCtxtPtr cvp;
46+
bool ValidateDTD::evaluate(Transaction *transaction, const std::string &str) {
4847

49-
m_dtd = xmlParseDTD(NULL, (const xmlChar *)m_resource.c_str());
50-
if (m_dtd == NULL) {
48+
XmlDtdPtrManager dtd(xmlParseDTD(NULL, (const xmlChar *)m_resource.c_str()));
49+
if (dtd.get() == NULL) {
5150
std::string err = std::string("XML: Failed to load DTD: ") \
5251
+ m_resource;
53-
ms_dbg_a(t, 4, err);
52+
ms_dbg_a(transaction, 4, err);
5453
return true;
5554
}
5655

57-
if (t->m_xml->m_data.doc == NULL) {
58-
ms_dbg_a(t, 4, "XML document tree could not "\
56+
if (transaction->m_xml->m_data.doc == NULL) {
57+
ms_dbg_a(transaction, 4, "XML document tree could not "\
5958
"be found for DTD validation.");
6059
return true;
6160
}
6261

63-
if (t->m_xml->m_data.well_formed != 1) {
64-
ms_dbg_a(t, 4, "XML: DTD validation failed because " \
62+
if (transaction->m_xml->m_data.well_formed != 1) {
63+
ms_dbg_a(transaction, 4, "XML: DTD validation failed because " \
6564
"content is not well formed.");
6665
return true;
6766
}
@@ -76,24 +75,24 @@ bool ValidateDTD::evaluate(Transaction *t, const std::string &str) {
7675
}
7776
#endif
7877

79-
cvp = xmlNewValidCtxt();
78+
xmlValidCtxtPtr cvp = xmlNewValidCtxt();
8079
if (cvp == NULL) {
81-
ms_dbg_a(t, 4, "XML: Failed to create a validation context.");
80+
ms_dbg_a(transaction, 4, "XML: Failed to create a validation context.");
8281
return true;
8382
}
8483

8584
/* Send validator errors/warnings to msr_log */
8685
cvp->error = (xmlSchemaValidityErrorFunc)error_runtime;
8786
cvp->warning = (xmlSchemaValidityErrorFunc)warn_runtime;
88-
cvp->userData = t;
87+
cvp->userData = transaction;
8988

90-
if (!xmlValidateDtd(cvp, t->m_xml->m_data.doc, m_dtd)) {
91-
ms_dbg_a(t, 4, "XML: DTD validation failed.");
89+
if (!xmlValidateDtd(cvp, transaction->m_xml->m_data.doc, dtd.get())) {
90+
ms_dbg_a(transaction, 4, "XML: DTD validation failed.");
9291
xmlFreeValidCtxt(cvp);
9392
return true;
9493
}
9594

96-
ms_dbg_a(t, 4, std::string("XML: Successfully validated " \
95+
ms_dbg_a(transaction, 4, std::string("XML: Successfully validated " \
9796
"payload against DTD: ") + m_resource);
9897

9998
xmlFreeValidCtxt(cvp);

src/operators/validate_dtd.h

+18-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* ModSecurity, http://www.modsecurity.org/
3-
* Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)
3+
* Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)
44
*
55
* You may not use this file except in compliance with
66
* the License. You may obtain a copy of the License at
@@ -33,18 +33,31 @@
3333
namespace modsecurity {
3434
namespace operators {
3535

36-
class ValidateDTD : public Operator {
36+
class XmlDtdPtrManager {
3737
public:
3838
/** @ingroup ModSecurity_Operator */
39-
explicit ValidateDTD(std::unique_ptr<RunTimeString> param)
40-
: Operator("ValidateDTD", std::move(param)) { }
39+
explicit XmlDtdPtrManager(xmlDtdPtr dtd)
40+
: m_dtd(dtd) { }
41+
~XmlDtdPtrManager() {
4142
#ifdef WITH_LIBXML2
42-
~ValidateDTD() {
4343
if (m_dtd != NULL) {
4444
xmlFreeDtd(m_dtd);
4545
m_dtd = NULL;
4646
}
47+
#endif
4748
}
49+
xmlDtdPtr get() const {return m_dtd;}
50+
private:
51+
xmlDtdPtr m_dtd; // The resource being managed
52+
};
53+
54+
class ValidateDTD : public Operator {
55+
public:
56+
/** @ingroup ModSecurity_Operator */
57+
explicit ValidateDTD(std::unique_ptr<RunTimeString> param)
58+
: Operator("ValidateDTD", std::move(param)) { }
59+
#ifdef WITH_LIBXML2
60+
~ValidateDTD() { }
4861

4962
bool evaluate(Transaction *transaction, const std::string &str) override;
5063
bool init(const std::string &file, std::string *error) override;
@@ -89,7 +102,6 @@ class ValidateDTD : public Operator {
89102

90103
private:
91104
std::string m_resource;
92-
xmlDtdPtr m_dtd = NULL;
93105
#endif
94106
};
95107

0 commit comments

Comments
 (0)