-
Notifications
You must be signed in to change notification settings - Fork 723
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added patches to fix below CVE's: 1. CVE-2019-14491, CVE-2019-14492 Link: opencv/opencv@ac425f6 2. CVE-2019-14493 Link: opencv/opencv@5691d99 3. CVE-2019-15939 Link: opencv/opencv@5a49707 4. CVE-2019-19624 Link: opencv/opencv@d1615ba Signed-off-by: Neetika.Singh <[email protected]> Signed-off-by: Armin Kuster <[email protected]>
- Loading branch information
Showing
5 changed files
with
619 additions
and
0 deletions.
There are no files selected for viewing
148 changes: 148 additions & 0 deletions
148
meta-oe/recipes-support/opencv/opencv/CVE-2019-14491.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
From 321c74ccd6077bdea1d47450ca4fe955cb5b6330 Mon Sep 17 00:00:00 2001 | ||
From: Alexander Alekhin <[email protected]> | ||
Date: Thu, 25 Jul 2019 17:15:59 +0300 | ||
Subject: [PATCH] objdetect: validate feature rectangle on reading | ||
|
||
CVE: CVE-2019-14491 | ||
CVE: CVE-2019-14492 | ||
Upstream-Status: Backport [https://github.com/opencv/opencv/commit/ac425f67e4c1d0da9afb9203f0918d8d57c067ed.patch] | ||
Comment: No changes in any hunk | ||
|
||
Signed-off-by: Neetika Singh <[email protected]> | ||
--- | ||
modules/objdetect/src/cascadedetect.cpp | 43 +++++++++++++++++++++---- | ||
modules/objdetect/src/cascadedetect.hpp | 6 ++-- | ||
2 files changed, 40 insertions(+), 9 deletions(-) | ||
|
||
diff --git a/modules/objdetect/src/cascadedetect.cpp b/modules/objdetect/src/cascadedetect.cpp | ||
index 4b2078306fe..bd62cd21a1b 100644 | ||
--- a/modules/objdetect/src/cascadedetect.cpp | ||
+++ b/modules/objdetect/src/cascadedetect.cpp | ||
@@ -47,6 +47,10 @@ | ||
#include "opencv2/objdetect/objdetect_c.h" | ||
#include "opencl_kernels_objdetect.hpp" | ||
|
||
+#if defined(_MSC_VER) | ||
+# pragma warning(disable:4458) // declaration of 'origWinSize' hides class member | ||
+#endif | ||
+ | ||
namespace cv | ||
{ | ||
|
||
@@ -537,7 +541,7 @@ bool FeatureEvaluator::setImage( InputArray _image, const std::vector<float>& _s | ||
|
||
//---------------------------------------------- HaarEvaluator --------------------------------------- | ||
|
||
-bool HaarEvaluator::Feature :: read( const FileNode& node ) | ||
+bool HaarEvaluator::Feature::read(const FileNode& node, const Size& origWinSize) | ||
{ | ||
FileNode rnode = node[CC_RECTS]; | ||
FileNodeIterator it = rnode.begin(), it_end = rnode.end(); | ||
@@ -549,11 +553,23 @@ bool HaarEvaluator::Feature :: read( const FileNode& node ) | ||
rect[ri].weight = 0.f; | ||
} | ||
|
||
+ const int W = origWinSize.width; | ||
+ const int H = origWinSize.height; | ||
+ | ||
for(ri = 0; it != it_end; ++it, ri++) | ||
{ | ||
FileNodeIterator it2 = (*it).begin(); | ||
- it2 >> rect[ri].r.x >> rect[ri].r.y >> | ||
- rect[ri].r.width >> rect[ri].r.height >> rect[ri].weight; | ||
+ Feature::RectWeigth& rw = rect[ri]; | ||
+ it2 >> rw.r.x >> rw.r.y >> rw.r.width >> rw.r.height >> rw.weight; | ||
+ // input validation | ||
+ { | ||
+ CV_CheckGE(rw.r.x, 0, "Invalid HAAR feature"); | ||
+ CV_CheckGE(rw.r.y, 0, "Invalid HAAR feature"); | ||
+ CV_CheckLT(rw.r.x, W, "Invalid HAAR feature"); // necessary for overflow checks | ||
+ CV_CheckLT(rw.r.y, H, "Invalid HAAR feature"); // necessary for overflow checks | ||
+ CV_CheckLE(rw.r.x + rw.r.width, W, "Invalid HAAR feature"); | ||
+ CV_CheckLE(rw.r.y + rw.r.height, H, "Invalid HAAR feature"); | ||
+ } | ||
} | ||
|
||
tilted = (int)node[CC_TILTED] != 0; | ||
@@ -598,7 +614,7 @@ bool HaarEvaluator::read(const FileNode& node, Size _origWinSize) | ||
|
||
for(i = 0; i < n; i++, ++it) | ||
{ | ||
- if(!ff[i].read(*it)) | ||
+ if(!ff[i].read(*it, _origWinSize)) | ||
return false; | ||
if( ff[i].tilted ) | ||
hasTiltedFeatures = true; | ||
@@ -759,11 +775,24 @@ int HaarEvaluator::getSquaresOffset() const | ||
} | ||
|
||
//---------------------------------------------- LBPEvaluator ------------------------------------- | ||
-bool LBPEvaluator::Feature :: read(const FileNode& node ) | ||
+bool LBPEvaluator::Feature::read(const FileNode& node, const Size& origWinSize) | ||
{ | ||
FileNode rnode = node[CC_RECT]; | ||
FileNodeIterator it = rnode.begin(); | ||
it >> rect.x >> rect.y >> rect.width >> rect.height; | ||
+ | ||
+ const int W = origWinSize.width; | ||
+ const int H = origWinSize.height; | ||
+ // input validation | ||
+ { | ||
+ CV_CheckGE(rect.x, 0, "Invalid LBP feature"); | ||
+ CV_CheckGE(rect.y, 0, "Invalid LBP feature"); | ||
+ CV_CheckLT(rect.x, W, "Invalid LBP feature"); | ||
+ CV_CheckLT(rect.y, H, "Invalid LBP feature"); | ||
+ CV_CheckLE(rect.x + rect.width, W, "Invalid LBP feature"); | ||
+ CV_CheckLE(rect.y + rect.height, H, "Invalid LBP feature"); | ||
+ } | ||
+ | ||
return true; | ||
} | ||
|
||
@@ -797,7 +826,7 @@ bool LBPEvaluator::read( const FileNode& node, Size _origWinSize ) | ||
std::vector<Feature>& ff = *features; | ||
for(int i = 0; it != it_end; ++it, i++) | ||
{ | ||
- if(!ff[i].read(*it)) | ||
+ if(!ff[i].read(*it, _origWinSize)) | ||
return false; | ||
} | ||
nchannels = 1; | ||
@@ -1477,6 +1506,8 @@ bool CascadeClassifierImpl::Data::read(const FileNode &root) | ||
origWinSize.width = (int)root[CC_WIDTH]; | ||
origWinSize.height = (int)root[CC_HEIGHT]; | ||
CV_Assert( origWinSize.height > 0 && origWinSize.width > 0 ); | ||
+ CV_CheckLE(origWinSize.width, 1000000, "Invalid window size (too large)"); | ||
+ CV_CheckLE(origWinSize.height, 1000000, "Invalid window size (too large)"); | ||
|
||
// load feature params | ||
FileNode fn = root[CC_FEATURE_PARAMS]; | ||
diff --git a/modules/objdetect/src/cascadedetect.hpp b/modules/objdetect/src/cascadedetect.hpp | ||
index f9910530b94..d9a288fcdda 100644 | ||
--- a/modules/objdetect/src/cascadedetect.hpp | ||
+++ b/modules/objdetect/src/cascadedetect.hpp | ||
@@ -317,12 +317,12 @@ class HaarEvaluator CV_FINAL : public FeatureEvaluator | ||
struct Feature | ||
{ | ||
Feature(); | ||
- bool read( const FileNode& node ); | ||
+ bool read(const FileNode& node, const Size& origWinSize); | ||
|
||
bool tilted; | ||
|
||
enum { RECT_NUM = 3 }; | ||
- struct | ||
+ struct RectWeigth | ||
{ | ||
Rect r; | ||
float weight; | ||
@@ -412,7 +412,7 @@ class LBPEvaluator CV_FINAL : public FeatureEvaluator | ||
Feature( int x, int y, int _block_w, int _block_h ) : | ||
rect(x, y, _block_w, _block_h) {} | ||
|
||
- bool read(const FileNode& node ); | ||
+ bool read(const FileNode& node, const Size& origWinSize); | ||
|
||
Rect rect; // weight and height for block | ||
}; | ||
|
237 changes: 237 additions & 0 deletions
237
meta-oe/recipes-support/opencv/opencv/CVE-2019-14493.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
From 5691d998ead1d9b0542bcfced36c2dceb3a59023 Mon Sep 17 00:00:00 2001 | ||
From: Alexander Alekhin <[email protected]> | ||
Date: Thu, 25 Jul 2019 15:14:22 +0300 | ||
Subject: [PATCH] core(persistence): added null ptr checks | ||
|
||
CVE: CVE-2019-14493 | ||
Upstream-Status: Backport [https://github.com/opencv/opencv/commit/5691d998ead1d9b0542bcfced36c2dceb3a59023.patch] | ||
Comment: No changes in any hunk | ||
|
||
Signed-off-by: Neetika Singh <[email protected]> | ||
--- | ||
modules/core/src/persistence_json.cpp | 12 ++++++++++++ | ||
modules/core/src/persistence_xml.cpp | 21 +++++++++++++++++++++ | ||
modules/core/src/persistence_yml.cpp | 21 +++++++++++++++++++++ | ||
3 files changed, 54 insertions(+) | ||
|
||
diff --git a/modules/core/src/persistence_json.cpp b/modules/core/src/persistence_json.cpp | ||
index ae678e1b8b1..89914e6534f 100644 | ||
--- a/modules/core/src/persistence_json.cpp | ||
+++ b/modules/core/src/persistence_json.cpp | ||
@@ -296,6 +296,8 @@ class JSONParser : public FileStorageParser | ||
|
||
while ( is_eof == false && is_completed == false ) | ||
{ | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid input"); | ||
switch ( *ptr ) | ||
{ | ||
/* comment */ | ||
@@ -381,6 +383,7 @@ class JSONParser : public FileStorageParser | ||
if ( is_eof || !is_completed ) | ||
{ | ||
ptr = fs->bufferStart(); | ||
+ CV_Assert(ptr); | ||
*ptr = '\0'; | ||
fs->setEof(); | ||
if( !is_completed ) | ||
@@ -392,6 +395,9 @@ class JSONParser : public FileStorageParser | ||
|
||
char* parseKey( char* ptr, FileNode& collection, FileNode& value_placeholder ) | ||
{ | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid input"); | ||
+ | ||
if( *ptr != '"' ) | ||
CV_PARSE_ERROR_CPP( "Key must start with \'\"\'" ); | ||
|
||
@@ -430,6 +436,9 @@ class JSONParser : public FileStorageParser | ||
|
||
char* parseValue( char* ptr, FileNode& node ) | ||
{ | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid value input"); | ||
+ | ||
ptr = skipSpaces( ptr ); | ||
if( !ptr || !*ptr ) | ||
CV_PARSE_ERROR_CPP( "Unexpected End-Of-File" ); | ||
@@ -817,6 +826,9 @@ class JSONParser : public FileStorageParser | ||
|
||
bool parse( char* ptr ) | ||
{ | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid input"); | ||
+ | ||
ptr = skipSpaces( ptr ); | ||
if ( !ptr || !*ptr ) | ||
return false; | ||
diff --git a/modules/core/src/persistence_xml.cpp b/modules/core/src/persistence_xml.cpp | ||
index fb30d90896e..89876dd3da8 100644 | ||
--- a/modules/core/src/persistence_xml.cpp | ||
+++ b/modules/core/src/persistence_xml.cpp | ||
@@ -360,6 +360,9 @@ class XMLParser : public FileStorageParser | ||
|
||
char* skipSpaces( char* ptr, int mode ) | ||
{ | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid input"); | ||
+ | ||
int level = 0; | ||
|
||
for(;;) | ||
@@ -441,6 +444,9 @@ class XMLParser : public FileStorageParser | ||
|
||
char* parseValue( char* ptr, FileNode& node ) | ||
{ | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid input"); | ||
+ | ||
FileNode new_elem; | ||
bool have_space = true; | ||
int value_type = node.type(); | ||
@@ -456,6 +462,8 @@ class XMLParser : public FileStorageParser | ||
(c == '<' && ptr[1] == '!' && ptr[2] == '-') ) | ||
{ | ||
ptr = skipSpaces( ptr, 0 ); | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid input"); | ||
have_space = true; | ||
c = *ptr; | ||
} | ||
@@ -502,6 +510,8 @@ class XMLParser : public FileStorageParser | ||
{ | ||
ptr = fs->parseBase64( ptr, 0, new_elem); | ||
ptr = skipSpaces( ptr, 0 ); | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid input"); | ||
} | ||
|
||
ptr = parseTag( ptr, key2, type_name, tag_type ); | ||
@@ -645,6 +655,9 @@ class XMLParser : public FileStorageParser | ||
char* parseTag( char* ptr, std::string& tag_name, | ||
std::string& type_name, int& tag_type ) | ||
{ | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid tag input"); | ||
+ | ||
if( *ptr == '\0' ) | ||
CV_PARSE_ERROR_CPP( "Unexpected end of the stream" ); | ||
|
||
@@ -702,6 +715,8 @@ class XMLParser : public FileStorageParser | ||
if( *ptr != '=' ) | ||
{ | ||
ptr = skipSpaces( ptr, CV_XML_INSIDE_TAG ); | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid attribute"); | ||
if( *ptr != '=' ) | ||
CV_PARSE_ERROR_CPP( "Attribute name should be followed by \'=\'" ); | ||
} | ||
@@ -740,6 +755,8 @@ class XMLParser : public FileStorageParser | ||
if( c != '>' ) | ||
{ | ||
ptr = skipSpaces( ptr, CV_XML_INSIDE_TAG ); | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid input"); | ||
c = *ptr; | ||
} | ||
|
||
@@ -781,6 +798,8 @@ class XMLParser : public FileStorageParser | ||
|
||
// CV_XML_INSIDE_TAG is used to prohibit leading comments | ||
ptr = skipSpaces( ptr, CV_XML_INSIDE_TAG ); | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid input"); | ||
|
||
if( memcmp( ptr, "<?xml", 5 ) != 0 ) // FIXIT ptr[1..] - out of bounds read without check | ||
CV_PARSE_ERROR_CPP( "Valid XML should start with \'<?xml ...?>\'" ); | ||
@@ -791,6 +810,8 @@ class XMLParser : public FileStorageParser | ||
while( ptr && *ptr != '\0' ) | ||
{ | ||
ptr = skipSpaces( ptr, 0 ); | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid input"); | ||
|
||
if( *ptr != '\0' ) | ||
{ | ||
diff --git a/modules/core/src/persistence_yml.cpp b/modules/core/src/persistence_yml.cpp | ||
index 4129ca1dc57..7742e827701 100644 | ||
--- a/modules/core/src/persistence_yml.cpp | ||
+++ b/modules/core/src/persistence_yml.cpp | ||
@@ -330,6 +330,9 @@ class YAMLParser : public FileStorageParser | ||
|
||
char* skipSpaces( char* ptr, int min_indent, int max_comment_indent ) | ||
{ | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid input"); | ||
+ | ||
for(;;) | ||
{ | ||
while( *ptr == ' ' ) | ||
@@ -374,6 +377,9 @@ class YAMLParser : public FileStorageParser | ||
|
||
bool getBase64Row(char* ptr, int indent, char* &beg, char* &end) | ||
{ | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid input"); | ||
+ | ||
beg = end = ptr = skipSpaces(ptr, 0, INT_MAX); | ||
if (!ptr || !*ptr) | ||
return false; // end of file | ||
@@ -394,6 +400,9 @@ class YAMLParser : public FileStorageParser | ||
|
||
char* parseKey( char* ptr, FileNode& map_node, FileNode& value_placeholder ) | ||
{ | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid input"); | ||
+ | ||
char c; | ||
char *endptr = ptr - 1, *saveptr; | ||
|
||
@@ -422,6 +431,9 @@ class YAMLParser : public FileStorageParser | ||
|
||
char* parseValue( char* ptr, FileNode& node, int min_indent, bool is_parent_flow ) | ||
{ | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid input"); | ||
+ | ||
char* endptr = 0; | ||
char c = ptr[0], d = ptr[1]; | ||
int value_type = FileNode::NONE; | ||
@@ -508,6 +520,8 @@ class YAMLParser : public FileStorageParser | ||
|
||
*endptr = d; | ||
ptr = skipSpaces( endptr, min_indent, INT_MAX ); | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid input"); | ||
|
||
c = *ptr; | ||
|
||
@@ -634,6 +648,8 @@ class YAMLParser : public FileStorageParser | ||
FileNode elem; | ||
|
||
ptr = skipSpaces( ptr, new_min_indent, INT_MAX ); | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid input"); | ||
if( *ptr == '}' || *ptr == ']' ) | ||
{ | ||
if( *ptr != d ) | ||
@@ -647,6 +663,8 @@ class YAMLParser : public FileStorageParser | ||
if( *ptr != ',' ) | ||
CV_PARSE_ERROR_CPP( "Missing , between the elements" ); | ||
ptr = skipSpaces( ptr + 1, new_min_indent, INT_MAX ); | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid input"); | ||
} | ||
|
||
if( struct_type == FileNode::MAP ) | ||
@@ -746,6 +764,9 @@ class YAMLParser : public FileStorageParser | ||
|
||
bool parse( char* ptr ) | ||
{ | ||
+ if (!ptr) | ||
+ CV_PARSE_ERROR_CPP("Invalid input"); | ||
+ | ||
bool first = true; | ||
bool ok = true; | ||
FileNode root_collection(fs->getFS(), 0, 0); | ||
|
Oops, something went wrong.