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 000000000..656000a8e --- /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 000000000..2b5e06f23 --- /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 000000000..e9f8514cb --- /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 000000000..79f8514bd --- /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 d781da600..de708fd06 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 | ||