diff options
| author | Neetika Singh <Neetika.Singh@kpit.com> | 2021-03-09 16:53:36 +0530 |
|---|---|---|
| committer | Armin Kuster <akuster808@gmail.com> | 2021-03-16 08:40:07 -0700 |
| commit | 389757a7494221fea1d8437e9a01c6e4fb4700af (patch) | |
| tree | a5ba4856aeb7ae62a7dc4b3300902bb81fc6923c | |
| parent | 1ad4455f2830c408f9c2e7a4b094c5e555db0cf2 (diff) | |
| download | meta-openembedded-389757a7494221fea1d8437e9a01c6e4fb4700af.tar.gz | |
opencv: Security fixes
Added patches to fix below CVE's:
1. CVE-2019-14491, CVE-2019-14492
Link: https://github.com/opencv/opencv/commit/ac425f67e4c1d0da9afb9203f0918d8d57c067ed
2. CVE-2019-14493
Link: https://github.com/opencv/opencv/commit/5691d998ead1d9b0542bcfced36c2dceb3a59023
3. CVE-2019-15939
Link: https://github.com/opencv/opencv/commit/5a497077f109d543ab86dfdf8add1c76c0e47d29
4. CVE-2019-19624
Link: https://github.com/opencv/opencv/commit/d1615ba11a93062b1429fce9f0f638d1572d3418
Signed-off-by: Neetika.Singh <Neetika.Singh@kpit.com>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
5 files changed, 619 insertions, 0 deletions
diff --git a/meta-oe/recipes-support/opencv/opencv/CVE-2019-14491.patch b/meta-oe/recipes-support/opencv/opencv/CVE-2019-14491.patch new file mode 100644 index 0000000000..656000a8e1 --- /dev/null +++ b/meta-oe/recipes-support/opencv/opencv/CVE-2019-14491.patch | |||
| @@ -0,0 +1,148 @@ | |||
| 1 | From 321c74ccd6077bdea1d47450ca4fe955cb5b6330 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Alexander Alekhin <alexander.alekhin@intel.com> | ||
| 3 | Date: Thu, 25 Jul 2019 17:15:59 +0300 | ||
| 4 | Subject: [PATCH] objdetect: validate feature rectangle on reading | ||
| 5 | |||
| 6 | CVE: CVE-2019-14491 | ||
| 7 | CVE: CVE-2019-14492 | ||
| 8 | Upstream-Status: Backport [https://github.com/opencv/opencv/commit/ac425f67e4c1d0da9afb9203f0918d8d57c067ed.patch] | ||
| 9 | Comment: No changes in any hunk | ||
| 10 | |||
| 11 | Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com> | ||
| 12 | --- | ||
| 13 | modules/objdetect/src/cascadedetect.cpp | 43 +++++++++++++++++++++---- | ||
| 14 | modules/objdetect/src/cascadedetect.hpp | 6 ++-- | ||
| 15 | 2 files changed, 40 insertions(+), 9 deletions(-) | ||
| 16 | |||
| 17 | diff --git a/modules/objdetect/src/cascadedetect.cpp b/modules/objdetect/src/cascadedetect.cpp | ||
| 18 | index 4b2078306fe..bd62cd21a1b 100644 | ||
| 19 | --- a/modules/objdetect/src/cascadedetect.cpp | ||
| 20 | +++ b/modules/objdetect/src/cascadedetect.cpp | ||
| 21 | @@ -47,6 +47,10 @@ | ||
| 22 | #include "opencv2/objdetect/objdetect_c.h" | ||
| 23 | #include "opencl_kernels_objdetect.hpp" | ||
| 24 | |||
| 25 | +#if defined(_MSC_VER) | ||
| 26 | +# pragma warning(disable:4458) // declaration of 'origWinSize' hides class member | ||
| 27 | +#endif | ||
| 28 | + | ||
| 29 | namespace cv | ||
| 30 | { | ||
| 31 | |||
| 32 | @@ -537,7 +541,7 @@ bool FeatureEvaluator::setImage( InputArray _image, const std::vector<float>& _s | ||
| 33 | |||
| 34 | //---------------------------------------------- HaarEvaluator --------------------------------------- | ||
| 35 | |||
| 36 | -bool HaarEvaluator::Feature :: read( const FileNode& node ) | ||
| 37 | +bool HaarEvaluator::Feature::read(const FileNode& node, const Size& origWinSize) | ||
| 38 | { | ||
| 39 | FileNode rnode = node[CC_RECTS]; | ||
| 40 | FileNodeIterator it = rnode.begin(), it_end = rnode.end(); | ||
| 41 | @@ -549,11 +553,23 @@ bool HaarEvaluator::Feature :: read( const FileNode& node ) | ||
| 42 | rect[ri].weight = 0.f; | ||
| 43 | } | ||
| 44 | |||
| 45 | + const int W = origWinSize.width; | ||
| 46 | + const int H = origWinSize.height; | ||
| 47 | + | ||
| 48 | for(ri = 0; it != it_end; ++it, ri++) | ||
| 49 | { | ||
| 50 | FileNodeIterator it2 = (*it).begin(); | ||
| 51 | - it2 >> rect[ri].r.x >> rect[ri].r.y >> | ||
| 52 | - rect[ri].r.width >> rect[ri].r.height >> rect[ri].weight; | ||
| 53 | + Feature::RectWeigth& rw = rect[ri]; | ||
| 54 | + it2 >> rw.r.x >> rw.r.y >> rw.r.width >> rw.r.height >> rw.weight; | ||
| 55 | + // input validation | ||
| 56 | + { | ||
| 57 | + CV_CheckGE(rw.r.x, 0, "Invalid HAAR feature"); | ||
| 58 | + CV_CheckGE(rw.r.y, 0, "Invalid HAAR feature"); | ||
| 59 | + CV_CheckLT(rw.r.x, W, "Invalid HAAR feature"); // necessary for overflow checks | ||
| 60 | + CV_CheckLT(rw.r.y, H, "Invalid HAAR feature"); // necessary for overflow checks | ||
| 61 | + CV_CheckLE(rw.r.x + rw.r.width, W, "Invalid HAAR feature"); | ||
| 62 | + CV_CheckLE(rw.r.y + rw.r.height, H, "Invalid HAAR feature"); | ||
| 63 | + } | ||
| 64 | } | ||
| 65 | |||
| 66 | tilted = (int)node[CC_TILTED] != 0; | ||
| 67 | @@ -598,7 +614,7 @@ bool HaarEvaluator::read(const FileNode& node, Size _origWinSize) | ||
| 68 | |||
| 69 | for(i = 0; i < n; i++, ++it) | ||
| 70 | { | ||
| 71 | - if(!ff[i].read(*it)) | ||
| 72 | + if(!ff[i].read(*it, _origWinSize)) | ||
| 73 | return false; | ||
| 74 | if( ff[i].tilted ) | ||
| 75 | hasTiltedFeatures = true; | ||
| 76 | @@ -759,11 +775,24 @@ int HaarEvaluator::getSquaresOffset() const | ||
| 77 | } | ||
| 78 | |||
| 79 | //---------------------------------------------- LBPEvaluator ------------------------------------- | ||
| 80 | -bool LBPEvaluator::Feature :: read(const FileNode& node ) | ||
| 81 | +bool LBPEvaluator::Feature::read(const FileNode& node, const Size& origWinSize) | ||
| 82 | { | ||
| 83 | FileNode rnode = node[CC_RECT]; | ||
| 84 | FileNodeIterator it = rnode.begin(); | ||
| 85 | it >> rect.x >> rect.y >> rect.width >> rect.height; | ||
| 86 | + | ||
| 87 | + const int W = origWinSize.width; | ||
| 88 | + const int H = origWinSize.height; | ||
| 89 | + // input validation | ||
| 90 | + { | ||
| 91 | + CV_CheckGE(rect.x, 0, "Invalid LBP feature"); | ||
| 92 | + CV_CheckGE(rect.y, 0, "Invalid LBP feature"); | ||
| 93 | + CV_CheckLT(rect.x, W, "Invalid LBP feature"); | ||
| 94 | + CV_CheckLT(rect.y, H, "Invalid LBP feature"); | ||
| 95 | + CV_CheckLE(rect.x + rect.width, W, "Invalid LBP feature"); | ||
| 96 | + CV_CheckLE(rect.y + rect.height, H, "Invalid LBP feature"); | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | return true; | ||
| 100 | } | ||
| 101 | |||
| 102 | @@ -797,7 +826,7 @@ bool LBPEvaluator::read( const FileNode& node, Size _origWinSize ) | ||
| 103 | std::vector<Feature>& ff = *features; | ||
| 104 | for(int i = 0; it != it_end; ++it, i++) | ||
| 105 | { | ||
| 106 | - if(!ff[i].read(*it)) | ||
| 107 | + if(!ff[i].read(*it, _origWinSize)) | ||
| 108 | return false; | ||
| 109 | } | ||
| 110 | nchannels = 1; | ||
| 111 | @@ -1477,6 +1506,8 @@ bool CascadeClassifierImpl::Data::read(const FileNode &root) | ||
| 112 | origWinSize.width = (int)root[CC_WIDTH]; | ||
| 113 | origWinSize.height = (int)root[CC_HEIGHT]; | ||
| 114 | CV_Assert( origWinSize.height > 0 && origWinSize.width > 0 ); | ||
| 115 | + CV_CheckLE(origWinSize.width, 1000000, "Invalid window size (too large)"); | ||
| 116 | + CV_CheckLE(origWinSize.height, 1000000, "Invalid window size (too large)"); | ||
| 117 | |||
| 118 | // load feature params | ||
| 119 | FileNode fn = root[CC_FEATURE_PARAMS]; | ||
| 120 | diff --git a/modules/objdetect/src/cascadedetect.hpp b/modules/objdetect/src/cascadedetect.hpp | ||
| 121 | index f9910530b94..d9a288fcdda 100644 | ||
| 122 | --- a/modules/objdetect/src/cascadedetect.hpp | ||
| 123 | +++ b/modules/objdetect/src/cascadedetect.hpp | ||
| 124 | @@ -317,12 +317,12 @@ class HaarEvaluator CV_FINAL : public FeatureEvaluator | ||
| 125 | struct Feature | ||
| 126 | { | ||
| 127 | Feature(); | ||
| 128 | - bool read( const FileNode& node ); | ||
| 129 | + bool read(const FileNode& node, const Size& origWinSize); | ||
| 130 | |||
| 131 | bool tilted; | ||
| 132 | |||
| 133 | enum { RECT_NUM = 3 }; | ||
| 134 | - struct | ||
| 135 | + struct RectWeigth | ||
| 136 | { | ||
| 137 | Rect r; | ||
| 138 | float weight; | ||
| 139 | @@ -412,7 +412,7 @@ class LBPEvaluator CV_FINAL : public FeatureEvaluator | ||
| 140 | Feature( int x, int y, int _block_w, int _block_h ) : | ||
| 141 | rect(x, y, _block_w, _block_h) {} | ||
| 142 | |||
| 143 | - bool read(const FileNode& node ); | ||
| 144 | + bool read(const FileNode& node, const Size& origWinSize); | ||
| 145 | |||
| 146 | Rect rect; // weight and height for block | ||
| 147 | }; | ||
| 148 | |||
diff --git a/meta-oe/recipes-support/opencv/opencv/CVE-2019-14493.patch b/meta-oe/recipes-support/opencv/opencv/CVE-2019-14493.patch new file mode 100644 index 0000000000..2b5e06f23f --- /dev/null +++ b/meta-oe/recipes-support/opencv/opencv/CVE-2019-14493.patch | |||
| @@ -0,0 +1,237 @@ | |||
| 1 | From 5691d998ead1d9b0542bcfced36c2dceb3a59023 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Alexander Alekhin <alexander.alekhin@intel.com> | ||
| 3 | Date: Thu, 25 Jul 2019 15:14:22 +0300 | ||
| 4 | Subject: [PATCH] core(persistence): added null ptr checks | ||
| 5 | |||
| 6 | CVE: CVE-2019-14493 | ||
| 7 | Upstream-Status: Backport [https://github.com/opencv/opencv/commit/5691d998ead1d9b0542bcfced36c2dceb3a59023.patch] | ||
| 8 | Comment: No changes in any hunk | ||
| 9 | |||
| 10 | Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com> | ||
| 11 | --- | ||
| 12 | modules/core/src/persistence_json.cpp | 12 ++++++++++++ | ||
| 13 | modules/core/src/persistence_xml.cpp | 21 +++++++++++++++++++++ | ||
| 14 | modules/core/src/persistence_yml.cpp | 21 +++++++++++++++++++++ | ||
| 15 | 3 files changed, 54 insertions(+) | ||
| 16 | |||
| 17 | diff --git a/modules/core/src/persistence_json.cpp b/modules/core/src/persistence_json.cpp | ||
| 18 | index ae678e1b8b1..89914e6534f 100644 | ||
| 19 | --- a/modules/core/src/persistence_json.cpp | ||
| 20 | +++ b/modules/core/src/persistence_json.cpp | ||
| 21 | @@ -296,6 +296,8 @@ class JSONParser : public FileStorageParser | ||
| 22 | |||
| 23 | while ( is_eof == false && is_completed == false ) | ||
| 24 | { | ||
| 25 | + if (!ptr) | ||
| 26 | + CV_PARSE_ERROR_CPP("Invalid input"); | ||
| 27 | switch ( *ptr ) | ||
| 28 | { | ||
| 29 | /* comment */ | ||
| 30 | @@ -381,6 +383,7 @@ class JSONParser : public FileStorageParser | ||
| 31 | if ( is_eof || !is_completed ) | ||
| 32 | { | ||
| 33 | ptr = fs->bufferStart(); | ||
| 34 | + CV_Assert(ptr); | ||
| 35 | *ptr = '\0'; | ||
| 36 | fs->setEof(); | ||
| 37 | if( !is_completed ) | ||
| 38 | @@ -392,6 +395,9 @@ class JSONParser : public FileStorageParser | ||
| 39 | |||
| 40 | char* parseKey( char* ptr, FileNode& collection, FileNode& value_placeholder ) | ||
| 41 | { | ||
| 42 | + if (!ptr) | ||
| 43 | + CV_PARSE_ERROR_CPP("Invalid input"); | ||
| 44 | + | ||
| 45 | if( *ptr != '"' ) | ||
| 46 | CV_PARSE_ERROR_CPP( "Key must start with \'\"\'" ); | ||
| 47 | |||
| 48 | @@ -430,6 +436,9 @@ class JSONParser : public FileStorageParser | ||
| 49 | |||
| 50 | char* parseValue( char* ptr, FileNode& node ) | ||
| 51 | { | ||
| 52 | + if (!ptr) | ||
| 53 | + CV_PARSE_ERROR_CPP("Invalid value input"); | ||
| 54 | + | ||
| 55 | ptr = skipSpaces( ptr ); | ||
| 56 | if( !ptr || !*ptr ) | ||
| 57 | CV_PARSE_ERROR_CPP( "Unexpected End-Of-File" ); | ||
| 58 | @@ -817,6 +826,9 @@ class JSONParser : public FileStorageParser | ||
| 59 | |||
| 60 | bool parse( char* ptr ) | ||
| 61 | { | ||
| 62 | + if (!ptr) | ||
| 63 | + CV_PARSE_ERROR_CPP("Invalid input"); | ||
| 64 | + | ||
| 65 | ptr = skipSpaces( ptr ); | ||
| 66 | if ( !ptr || !*ptr ) | ||
| 67 | return false; | ||
| 68 | diff --git a/modules/core/src/persistence_xml.cpp b/modules/core/src/persistence_xml.cpp | ||
| 69 | index fb30d90896e..89876dd3da8 100644 | ||
| 70 | --- a/modules/core/src/persistence_xml.cpp | ||
| 71 | +++ b/modules/core/src/persistence_xml.cpp | ||
| 72 | @@ -360,6 +360,9 @@ class XMLParser : public FileStorageParser | ||
| 73 | |||
| 74 | char* skipSpaces( char* ptr, int mode ) | ||
| 75 | { | ||
| 76 | + if (!ptr) | ||
| 77 | + CV_PARSE_ERROR_CPP("Invalid input"); | ||
| 78 | + | ||
| 79 | int level = 0; | ||
| 80 | |||
| 81 | for(;;) | ||
| 82 | @@ -441,6 +444,9 @@ class XMLParser : public FileStorageParser | ||
| 83 | |||
| 84 | char* parseValue( char* ptr, FileNode& node ) | ||
| 85 | { | ||
| 86 | + if (!ptr) | ||
| 87 | + CV_PARSE_ERROR_CPP("Invalid input"); | ||
| 88 | + | ||
| 89 | FileNode new_elem; | ||
| 90 | bool have_space = true; | ||
| 91 | int value_type = node.type(); | ||
| 92 | @@ -456,6 +462,8 @@ class XMLParser : public FileStorageParser | ||
| 93 | (c == '<' && ptr[1] == '!' && ptr[2] == '-') ) | ||
| 94 | { | ||
| 95 | ptr = skipSpaces( ptr, 0 ); | ||
| 96 | + if (!ptr) | ||
| 97 | + CV_PARSE_ERROR_CPP("Invalid input"); | ||
| 98 | have_space = true; | ||
| 99 | c = *ptr; | ||
| 100 | } | ||
| 101 | @@ -502,6 +510,8 @@ class XMLParser : public FileStorageParser | ||
| 102 | { | ||
| 103 | ptr = fs->parseBase64( ptr, 0, new_elem); | ||
| 104 | ptr = skipSpaces( ptr, 0 ); | ||
| 105 | + if (!ptr) | ||
| 106 | + CV_PARSE_ERROR_CPP("Invalid input"); | ||
| 107 | } | ||
| 108 | |||
| 109 | ptr = parseTag( ptr, key2, type_name, tag_type ); | ||
| 110 | @@ -645,6 +655,9 @@ class XMLParser : public FileStorageParser | ||
| 111 | char* parseTag( char* ptr, std::string& tag_name, | ||
| 112 | std::string& type_name, int& tag_type ) | ||
| 113 | { | ||
| 114 | + if (!ptr) | ||
| 115 | + CV_PARSE_ERROR_CPP("Invalid tag input"); | ||
| 116 | + | ||
| 117 | if( *ptr == '\0' ) | ||
| 118 | CV_PARSE_ERROR_CPP( "Unexpected end of the stream" ); | ||
| 119 | |||
| 120 | @@ -702,6 +715,8 @@ class XMLParser : public FileStorageParser | ||
| 121 | if( *ptr != '=' ) | ||
| 122 | { | ||
| 123 | ptr = skipSpaces( ptr, CV_XML_INSIDE_TAG ); | ||
| 124 | + if (!ptr) | ||
| 125 | + CV_PARSE_ERROR_CPP("Invalid attribute"); | ||
| 126 | if( *ptr != '=' ) | ||
| 127 | CV_PARSE_ERROR_CPP( "Attribute name should be followed by \'=\'" ); | ||
| 128 | } | ||
| 129 | @@ -740,6 +755,8 @@ class XMLParser : public FileStorageParser | ||
| 130 | if( c != '>' ) | ||
| 131 | { | ||
| 132 | ptr = skipSpaces( ptr, CV_XML_INSIDE_TAG ); | ||
| 133 | + if (!ptr) | ||
| 134 | + CV_PARSE_ERROR_CPP("Invalid input"); | ||
| 135 | c = *ptr; | ||
| 136 | } | ||
| 137 | |||
| 138 | @@ -781,6 +798,8 @@ class XMLParser : public FileStorageParser | ||
| 139 | |||
| 140 | // CV_XML_INSIDE_TAG is used to prohibit leading comments | ||
| 141 | ptr = skipSpaces( ptr, CV_XML_INSIDE_TAG ); | ||
| 142 | + if (!ptr) | ||
| 143 | + CV_PARSE_ERROR_CPP("Invalid input"); | ||
| 144 | |||
| 145 | if( memcmp( ptr, "<?xml", 5 ) != 0 ) // FIXIT ptr[1..] - out of bounds read without check | ||
| 146 | CV_PARSE_ERROR_CPP( "Valid XML should start with \'<?xml ...?>\'" ); | ||
| 147 | @@ -791,6 +810,8 @@ class XMLParser : public FileStorageParser | ||
| 148 | while( ptr && *ptr != '\0' ) | ||
| 149 | { | ||
| 150 | ptr = skipSpaces( ptr, 0 ); | ||
| 151 | + if (!ptr) | ||
| 152 | + CV_PARSE_ERROR_CPP("Invalid input"); | ||
| 153 | |||
| 154 | if( *ptr != '\0' ) | ||
| 155 | { | ||
| 156 | diff --git a/modules/core/src/persistence_yml.cpp b/modules/core/src/persistence_yml.cpp | ||
| 157 | index 4129ca1dc57..7742e827701 100644 | ||
| 158 | --- a/modules/core/src/persistence_yml.cpp | ||
| 159 | +++ b/modules/core/src/persistence_yml.cpp | ||
| 160 | @@ -330,6 +330,9 @@ class YAMLParser : public FileStorageParser | ||
| 161 | |||
| 162 | char* skipSpaces( char* ptr, int min_indent, int max_comment_indent ) | ||
| 163 | { | ||
| 164 | + if (!ptr) | ||
| 165 | + CV_PARSE_ERROR_CPP("Invalid input"); | ||
| 166 | + | ||
| 167 | for(;;) | ||
| 168 | { | ||
| 169 | while( *ptr == ' ' ) | ||
| 170 | @@ -374,6 +377,9 @@ class YAMLParser : public FileStorageParser | ||
| 171 | |||
| 172 | bool getBase64Row(char* ptr, int indent, char* &beg, char* &end) | ||
| 173 | { | ||
| 174 | + if (!ptr) | ||
| 175 | + CV_PARSE_ERROR_CPP("Invalid input"); | ||
| 176 | + | ||
| 177 | beg = end = ptr = skipSpaces(ptr, 0, INT_MAX); | ||
| 178 | if (!ptr || !*ptr) | ||
| 179 | return false; // end of file | ||
| 180 | @@ -394,6 +400,9 @@ class YAMLParser : public FileStorageParser | ||
| 181 | |||
| 182 | char* parseKey( char* ptr, FileNode& map_node, FileNode& value_placeholder ) | ||
| 183 | { | ||
| 184 | + if (!ptr) | ||
| 185 | + CV_PARSE_ERROR_CPP("Invalid input"); | ||
| 186 | + | ||
| 187 | char c; | ||
| 188 | char *endptr = ptr - 1, *saveptr; | ||
| 189 | |||
| 190 | @@ -422,6 +431,9 @@ class YAMLParser : public FileStorageParser | ||
| 191 | |||
| 192 | char* parseValue( char* ptr, FileNode& node, int min_indent, bool is_parent_flow ) | ||
| 193 | { | ||
| 194 | + if (!ptr) | ||
| 195 | + CV_PARSE_ERROR_CPP("Invalid input"); | ||
| 196 | + | ||
| 197 | char* endptr = 0; | ||
| 198 | char c = ptr[0], d = ptr[1]; | ||
| 199 | int value_type = FileNode::NONE; | ||
| 200 | @@ -508,6 +520,8 @@ class YAMLParser : public FileStorageParser | ||
| 201 | |||
| 202 | *endptr = d; | ||
| 203 | ptr = skipSpaces( endptr, min_indent, INT_MAX ); | ||
| 204 | + if (!ptr) | ||
| 205 | + CV_PARSE_ERROR_CPP("Invalid input"); | ||
| 206 | |||
| 207 | c = *ptr; | ||
| 208 | |||
| 209 | @@ -634,6 +648,8 @@ class YAMLParser : public FileStorageParser | ||
| 210 | FileNode elem; | ||
| 211 | |||
| 212 | ptr = skipSpaces( ptr, new_min_indent, INT_MAX ); | ||
| 213 | + if (!ptr) | ||
| 214 | + CV_PARSE_ERROR_CPP("Invalid input"); | ||
| 215 | if( *ptr == '}' || *ptr == ']' ) | ||
| 216 | { | ||
| 217 | if( *ptr != d ) | ||
| 218 | @@ -647,6 +663,8 @@ class YAMLParser : public FileStorageParser | ||
| 219 | if( *ptr != ',' ) | ||
| 220 | CV_PARSE_ERROR_CPP( "Missing , between the elements" ); | ||
| 221 | ptr = skipSpaces( ptr + 1, new_min_indent, INT_MAX ); | ||
| 222 | + if (!ptr) | ||
| 223 | + CV_PARSE_ERROR_CPP("Invalid input"); | ||
| 224 | } | ||
| 225 | |||
| 226 | if( struct_type == FileNode::MAP ) | ||
| 227 | @@ -746,6 +764,9 @@ class YAMLParser : public FileStorageParser | ||
| 228 | |||
| 229 | bool parse( char* ptr ) | ||
| 230 | { | ||
| 231 | + if (!ptr) | ||
| 232 | + CV_PARSE_ERROR_CPP("Invalid input"); | ||
| 233 | + | ||
| 234 | bool first = true; | ||
| 235 | bool ok = true; | ||
| 236 | FileNode root_collection(fs->getFS(), 0, 0); | ||
| 237 | |||
diff --git a/meta-oe/recipes-support/opencv/opencv/CVE-2019-15939.patch b/meta-oe/recipes-support/opencv/opencv/CVE-2019-15939.patch new file mode 100644 index 0000000000..e9f8514cbe --- /dev/null +++ b/meta-oe/recipes-support/opencv/opencv/CVE-2019-15939.patch | |||
| @@ -0,0 +1,73 @@ | |||
| 1 | From 5a497077f109d543ab86dfdf8add1c76c0e47d29 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Alexander Alekhin <alexander.alekhin@intel.com> | ||
| 3 | Date: Fri, 23 Aug 2019 16:14:53 +0300 | ||
| 4 | Subject: [PATCH] objdetect: add input check in HOG detector | ||
| 5 | |||
| 6 | CVE: CVE-2019-15939 | ||
| 7 | Upstream-Status: Backport [https://github.com/opencv/opencv/commit/5a497077f109d543ab86dfdf8add1c76c0e47d29.patch] | ||
| 8 | Comment: No changes in any hunk | ||
| 9 | |||
| 10 | Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com> | ||
| 11 | --- | ||
| 12 | modules/objdetect/src/hog.cpp | 19 ++++++++++++------- | ||
| 13 | 1 file changed, 12 insertions(+), 7 deletions(-) | ||
| 14 | |||
| 15 | diff --git a/modules/objdetect/src/hog.cpp b/modules/objdetect/src/hog.cpp | ||
| 16 | index 9524851eebb..378bab30876 100644 | ||
| 17 | --- a/modules/objdetect/src/hog.cpp | ||
| 18 | +++ b/modules/objdetect/src/hog.cpp | ||
| 19 | @@ -68,6 +68,7 @@ enum {DESCR_FORMAT_COL_BY_COL, DESCR_FORMAT_ROW_BY_ROW}; | ||
| 20 | |||
| 21 | static int numPartsWithin(int size, int part_size, int stride) | ||
| 22 | { | ||
| 23 | + CV_Assert(stride != 0); | ||
| 24 | return (size - part_size + stride) / stride; | ||
| 25 | } | ||
| 26 | |||
| 27 | @@ -80,13 +81,17 @@ static Size numPartsWithin(cv::Size size, cv::Size part_size, | ||
| 28 | |||
| 29 | static size_t getBlockHistogramSize(Size block_size, Size cell_size, int nbins) | ||
| 30 | { | ||
| 31 | + CV_Assert(!cell_size.empty()); | ||
| 32 | Size cells_per_block = Size(block_size.width / cell_size.width, | ||
| 33 | - block_size.height / cell_size.height); | ||
| 34 | + block_size.height / cell_size.height); | ||
| 35 | return (size_t)(nbins * cells_per_block.area()); | ||
| 36 | } | ||
| 37 | |||
| 38 | size_t HOGDescriptor::getDescriptorSize() const | ||
| 39 | { | ||
| 40 | + CV_Assert(!cellSize.empty()); | ||
| 41 | + CV_Assert(!blockStride.empty()); | ||
| 42 | + | ||
| 43 | CV_Assert(blockSize.width % cellSize.width == 0 && | ||
| 44 | blockSize.height % cellSize.height == 0); | ||
| 45 | CV_Assert((winSize.width - blockSize.width) % blockStride.width == 0 && | ||
| 46 | @@ -144,20 +149,20 @@ bool HOGDescriptor::read(FileNode& obj) | ||
| 47 | if( !obj.isMap() ) | ||
| 48 | return false; | ||
| 49 | FileNodeIterator it = obj["winSize"].begin(); | ||
| 50 | - it >> winSize.width >> winSize.height; | ||
| 51 | + it >> winSize.width >> winSize.height; CV_Assert(!winSize.empty()); | ||
| 52 | it = obj["blockSize"].begin(); | ||
| 53 | - it >> blockSize.width >> blockSize.height; | ||
| 54 | + it >> blockSize.width >> blockSize.height; CV_Assert(!blockSize.empty()); | ||
| 55 | it = obj["blockStride"].begin(); | ||
| 56 | - it >> blockStride.width >> blockStride.height; | ||
| 57 | + it >> blockStride.width >> blockStride.height; CV_Assert(!blockStride.empty()); | ||
| 58 | it = obj["cellSize"].begin(); | ||
| 59 | - it >> cellSize.width >> cellSize.height; | ||
| 60 | - obj["nbins"] >> nbins; | ||
| 61 | + it >> cellSize.width >> cellSize.height; CV_Assert(!cellSize.empty()); | ||
| 62 | + obj["nbins"] >> nbins; CV_Assert(nbins > 0); | ||
| 63 | obj["derivAperture"] >> derivAperture; | ||
| 64 | obj["winSigma"] >> winSigma; | ||
| 65 | obj["histogramNormType"] >> histogramNormType; | ||
| 66 | obj["L2HysThreshold"] >> L2HysThreshold; | ||
| 67 | obj["gammaCorrection"] >> gammaCorrection; | ||
| 68 | - obj["nlevels"] >> nlevels; | ||
| 69 | + obj["nlevels"] >> nlevels; CV_Assert(nlevels > 0); | ||
| 70 | if (obj["signedGradient"].empty()) | ||
| 71 | signedGradient = false; | ||
| 72 | else | ||
| 73 | |||
diff --git a/meta-oe/recipes-support/opencv/opencv/CVE-2019-19624.patch b/meta-oe/recipes-support/opencv/opencv/CVE-2019-19624.patch new file mode 100644 index 0000000000..79f8514bdd --- /dev/null +++ b/meta-oe/recipes-support/opencv/opencv/CVE-2019-19624.patch | |||
| @@ -0,0 +1,157 @@ | |||
| 1 | From d1615ba11a93062b1429fce9f0f638d1572d3418 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Thang Tran <TranKimThang279@gmail.com> | ||
| 3 | Date: Mon, 27 May 2019 08:18:26 +0200 | ||
| 4 | Subject: [PATCH] video:fixed DISOpticalFlow segfault from small img | ||
| 5 | |||
| 6 | CVE: CVE-2019-19624 | ||
| 7 | Upstream-Status: Backport [https://github.com/opencv/opencv/commit/d1615ba11a93062b1429fce9f0f638d1572d3418.patch] | ||
| 8 | Comment: No changes in any hunk | ||
| 9 | |||
| 10 | Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com> | ||
| 11 | --- | ||
| 12 | modules/video/src/dis_flow.cpp | 67 ++++++++++++++++++++++++- | ||
| 13 | modules/video/test/test_OF_accuracy.cpp | 28 +++++++++++ | ||
| 14 | 2 files changed, 93 insertions(+), 2 deletions(-) | ||
| 15 | |||
| 16 | diff --git a/modules/video/src/dis_flow.cpp b/modules/video/src/dis_flow.cpp | ||
| 17 | index a453d8b2b51..806d6f1ddaf 100644 | ||
| 18 | --- a/modules/video/src/dis_flow.cpp | ||
| 19 | +++ b/modules/video/src/dis_flow.cpp | ||
| 20 | @@ -140,6 +140,8 @@ class DISOpticalFlowImpl CV_FINAL : public DISOpticalFlow | ||
| 21 | void prepareBuffers(Mat &I0, Mat &I1, Mat &flow, bool use_flow); | ||
| 22 | void precomputeStructureTensor(Mat &dst_I0xx, Mat &dst_I0yy, Mat &dst_I0xy, Mat &dst_I0x, Mat &dst_I0y, Mat &I0x, | ||
| 23 | Mat &I0y); | ||
| 24 | + int autoSelectCoarsestScale(int img_width); | ||
| 25 | + void autoSelectPatchSizeAndScales(int img_width); | ||
| 26 | |||
| 27 | struct PatchInverseSearch_ParBody : public ParallelLoopBody | ||
| 28 | { | ||
| 29 | @@ -435,6 +437,44 @@ void DISOpticalFlowImpl::precomputeStructureTensor(Mat &dst_I0xx, Mat &dst_I0yy, | ||
| 30 | } | ||
| 31 | } | ||
| 32 | |||
| 33 | +int DISOpticalFlowImpl::autoSelectCoarsestScale(int img_width) | ||
| 34 | +{ | ||
| 35 | + const int fratio = 5; | ||
| 36 | + return std::max(0, (int)std::floor(log2((2.0f*(float)img_width) / ((float)fratio * (float)patch_size)))); | ||
| 37 | +} | ||
| 38 | + | ||
| 39 | +void DISOpticalFlowImpl::autoSelectPatchSizeAndScales(int img_width) | ||
| 40 | +{ | ||
| 41 | + switch (finest_scale) | ||
| 42 | + { | ||
| 43 | + case 1: | ||
| 44 | + patch_size = 8; | ||
| 45 | + coarsest_scale = autoSelectCoarsestScale(img_width); | ||
| 46 | + finest_scale = std::max(coarsest_scale-2, 0); | ||
| 47 | + break; | ||
| 48 | + | ||
| 49 | + case 3: | ||
| 50 | + patch_size = 12; | ||
| 51 | + coarsest_scale = autoSelectCoarsestScale(img_width); | ||
| 52 | + finest_scale = std::max(coarsest_scale-4, 0); | ||
| 53 | + break; | ||
| 54 | + | ||
| 55 | + case 4: | ||
| 56 | + patch_size = 12; | ||
| 57 | + coarsest_scale = autoSelectCoarsestScale(img_width); | ||
| 58 | + finest_scale = std::max(coarsest_scale-5, 0); | ||
| 59 | + break; | ||
| 60 | + | ||
| 61 | + // default case, fall-through. | ||
| 62 | + case 2: | ||
| 63 | + default: | ||
| 64 | + patch_size = 8; | ||
| 65 | + coarsest_scale = autoSelectCoarsestScale(img_width); | ||
| 66 | + finest_scale = std::max(coarsest_scale-2, 0); | ||
| 67 | + break; | ||
| 68 | + } | ||
| 69 | +} | ||
| 70 | + | ||
| 71 | DISOpticalFlowImpl::PatchInverseSearch_ParBody::PatchInverseSearch_ParBody(DISOpticalFlowImpl &_dis, int _nstripes, | ||
| 72 | int _hs, Mat &dst_Sx, Mat &dst_Sy, | ||
| 73 | Mat &src_Ux, Mat &src_Uy, Mat &_I0, Mat &_I1, | ||
| 74 | @@ -1318,9 +1358,20 @@ bool DISOpticalFlowImpl::ocl_calc(InputArray I0, InputArray I1, InputOutputArray | ||
| 75 | else | ||
| 76 | flow.create(I1Mat.size(), CV_32FC2); | ||
| 77 | UMat &u_flowMat = flow.getUMatRef(); | ||
| 78 | - coarsest_scale = min((int)(log(max(I0Mat.cols, I0Mat.rows) / (4.0 * patch_size)) / log(2.0) + 0.5), /* Original code serach for maximal movement of width/4 */ | ||
| 79 | + coarsest_scale = min((int)(log(max(I0Mat.cols, I0Mat.rows) / (4.0 * patch_size)) / log(2.0) + 0.5), /* Original code search for maximal movement of width/4 */ | ||
| 80 | (int)(log(min(I0Mat.cols, I0Mat.rows) / patch_size) / log(2.0))); /* Deepest pyramid level greater or equal than patch*/ | ||
| 81 | |||
| 82 | + if (coarsest_scale<0) | ||
| 83 | + CV_Error(cv::Error::StsBadSize, "The input image must have either width or height >= 12"); | ||
| 84 | + | ||
| 85 | + if (coarsest_scale<finest_scale) | ||
| 86 | + { | ||
| 87 | + // choose the finest level based on coarsest level. | ||
| 88 | + // Refs: https://github.com/tikroeger/OF_DIS/blob/2c9f2a674f3128d3a41c10e41cc9f3a35bb1b523/run_dense.cpp#L239 | ||
| 89 | + int original_img_width = I0.size().width; | ||
| 90 | + autoSelectPatchSizeAndScales(original_img_width); | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | ocl_prepareBuffers(I0Mat, I1Mat, u_flowMat, use_input_flow); | ||
| 94 | u_Ux[coarsest_scale].setTo(0.0f); | ||
| 95 | u_Uy[coarsest_scale].setTo(0.0f); | ||
| 96 | @@ -1385,8 +1436,20 @@ void DISOpticalFlowImpl::calc(InputArray I0, InputArray I1, InputOutputArray flo | ||
| 97 | else | ||
| 98 | flow.create(I1Mat.size(), CV_32FC2); | ||
| 99 | Mat flowMat = flow.getMat(); | ||
| 100 | - coarsest_scale = min((int)(log(max(I0Mat.cols, I0Mat.rows) / (4.0 * patch_size)) / log(2.0) + 0.5), /* Original code serach for maximal movement of width/4 */ | ||
| 101 | + coarsest_scale = min((int)(log(max(I0Mat.cols, I0Mat.rows) / (4.0 * patch_size)) / log(2.0) + 0.5), /* Original code search for maximal movement of width/4 */ | ||
| 102 | (int)(log(min(I0Mat.cols, I0Mat.rows) / patch_size) / log(2.0))); /* Deepest pyramid level greater or equal than patch*/ | ||
| 103 | + | ||
| 104 | + if (coarsest_scale<0) | ||
| 105 | + CV_Error(cv::Error::StsBadSize, "The input image must have either width or height >= 12"); | ||
| 106 | + | ||
| 107 | + if (coarsest_scale<finest_scale) | ||
| 108 | + { | ||
| 109 | + // choose the finest level based on coarsest level. | ||
| 110 | + // Refs: https://github.com/tikroeger/OF_DIS/blob/2c9f2a674f3128d3a41c10e41cc9f3a35bb1b523/run_dense.cpp#L239 | ||
| 111 | + int original_img_width = I0.size().width; | ||
| 112 | + autoSelectPatchSizeAndScales(original_img_width); | ||
| 113 | + } | ||
| 114 | + | ||
| 115 | int num_stripes = getNumThreads(); | ||
| 116 | |||
| 117 | prepareBuffers(I0Mat, I1Mat, flowMat, use_input_flow); | ||
| 118 | diff --git a/modules/video/test/test_OF_accuracy.cpp b/modules/video/test/test_OF_accuracy.cpp | ||
| 119 | index affbab65866..b99ffce2a8b 100644 | ||
| 120 | --- a/modules/video/test/test_OF_accuracy.cpp | ||
| 121 | +++ b/modules/video/test/test_OF_accuracy.cpp | ||
| 122 | @@ -121,6 +121,34 @@ TEST(DenseOpticalFlow_DIS, ReferenceAccuracy) | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | +TEST(DenseOpticalFlow_DIS, InvalidImgSize_CoarsestLevelLessThanZero) | ||
| 127 | +{ | ||
| 128 | + cv::Ptr<cv::DISOpticalFlow> of = cv::DISOpticalFlow::create(); | ||
| 129 | + const int mat_size = 10; | ||
| 130 | + | ||
| 131 | + cv::Mat x(mat_size, mat_size, CV_8UC1, 42); | ||
| 132 | + cv::Mat y(mat_size, mat_size, CV_8UC1, 42); | ||
| 133 | + cv::Mat flow; | ||
| 134 | + | ||
| 135 | + ASSERT_THROW(of->calc(x, y, flow), cv::Exception); | ||
| 136 | +} | ||
| 137 | + | ||
| 138 | +// make sure that autoSelectPatchSizeAndScales() works properly. | ||
| 139 | +TEST(DenseOpticalFlow_DIS, InvalidImgSize_CoarsestLevelLessThanFinestLevel) | ||
| 140 | +{ | ||
| 141 | + cv::Ptr<cv::DISOpticalFlow> of = cv::DISOpticalFlow::create(); | ||
| 142 | + const int mat_size = 80; | ||
| 143 | + | ||
| 144 | + cv::Mat x(mat_size, mat_size, CV_8UC1, 42); | ||
| 145 | + cv::Mat y(mat_size, mat_size, CV_8UC1, 42); | ||
| 146 | + cv::Mat flow; | ||
| 147 | + | ||
| 148 | + of->calc(x, y, flow); | ||
| 149 | + | ||
| 150 | + ASSERT_EQ(flow.rows, mat_size); | ||
| 151 | + ASSERT_EQ(flow.cols, mat_size); | ||
| 152 | +} | ||
| 153 | + | ||
| 154 | TEST(DenseOpticalFlow_VariationalRefinement, ReferenceAccuracy) | ||
| 155 | { | ||
| 156 | Mat frame1, frame2, GT; | ||
| 157 | |||
diff --git a/meta-oe/recipes-support/opencv/opencv_4.1.0.bb b/meta-oe/recipes-support/opencv/opencv_4.1.0.bb index d781da6005..de708fd06d 100644 --- a/meta-oe/recipes-support/opencv/opencv_4.1.0.bb +++ b/meta-oe/recipes-support/opencv/opencv_4.1.0.bb | |||
| @@ -50,6 +50,10 @@ SRC_URI = "git://github.com/opencv/opencv.git;name=opencv \ | |||
| 50 | file://0001-Dont-use-isystem.patch \ | 50 | file://0001-Dont-use-isystem.patch \ |
| 51 | file://0001-carotene-Replace-ipcp-unit-growth-with-ipa-cp-unit-g.patch \ | 51 | file://0001-carotene-Replace-ipcp-unit-growth-with-ipa-cp-unit-g.patch \ |
| 52 | file://download.patch \ | 52 | file://download.patch \ |
| 53 | file://CVE-2019-14491.patch \ | ||
| 54 | file://CVE-2019-14493.patch \ | ||
| 55 | file://CVE-2019-15939.patch \ | ||
| 56 | file://CVE-2019-19624.patch \ | ||
| 53 | " | 57 | " |
| 54 | PV = "4.1.0" | 58 | PV = "4.1.0" |
| 55 | 59 | ||
