summaryrefslogtreecommitdiffstats
path: root/meta-oe/recipes-support
diff options
context:
space:
mode:
authorKai Kang <kai.kang@windriver.com>2017-08-30 09:59:27 +0800
committerMartin Jansa <Martin.Jansa@gmail.com>2017-08-31 10:18:33 +0200
commit860f01d1bd6fac6c299d4774c508092ee80dcedf (patch)
treeeb9f43b7870d7156be748dac0cf81fe651e9768e /meta-oe/recipes-support
parent7504f86374c15a57c19247c2b9c522d6a198e152 (diff)
downloadmeta-openembedded-860f01d1bd6fac6c299d4774c508092ee80dcedf.tar.gz
opencv: fix CVEs
Fix CVEs for opencv 3.3: * CVE-2017-12597 * CVE-2017-12598 * CVE-2017-12599 * CVE-2017-12600 * CVE-2017-12601 * CVE-2017-12602 * CVE-2017-12603 * CVE-2017-12604 * CVE-2017-12605 * CVE-2017-12606 * CVE-2017-12862 * CVE-2017-12863 * CVE-2017-12864 Refs: 1 https://github.com/opencv/opencv/pull/9376 2 https://security-tracker.debian.org/tracker/CVE-2017-12601 Signed-off-by: Kai Kang <kai.kang@windriver.com> Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Diffstat (limited to 'meta-oe/recipes-support')
-rw-r--r--meta-oe/recipes-support/opencv/opencv/0001-build-workaround-GCC-7.1.1-compilation-issue-with-sa.patch127
-rw-r--r--meta-oe/recipes-support/opencv/opencv/0002-imgcodecs-refactoring-improve-code-quality.patch656
-rw-r--r--meta-oe/recipes-support/opencv/opencv/0003-imgproc-test-add-checks-for-remove-call.patch186
-rw-r--r--meta-oe/recipes-support/opencv/opencv_3.3.bb3
4 files changed, 972 insertions, 0 deletions
diff --git a/meta-oe/recipes-support/opencv/opencv/0001-build-workaround-GCC-7.1.1-compilation-issue-with-sa.patch b/meta-oe/recipes-support/opencv/opencv/0001-build-workaround-GCC-7.1.1-compilation-issue-with-sa.patch
new file mode 100644
index 000000000..0140633db
--- /dev/null
+++ b/meta-oe/recipes-support/opencv/opencv/0001-build-workaround-GCC-7.1.1-compilation-issue-with-sa.patch
@@ -0,0 +1,127 @@
1Upstream-Status: Backport [https://github.com/opencv/opencv/pull/9376/commits/0d854db361106dfcb055231fd0112c5b85ef2287]
2
3Fix CVEs for opencv 3.3.
4
5* CVE-2017-12597
6* CVE-2017-12598
7* CVE-2017-12599
8* CVE-2017-12600
9* CVE-2017-12601
10* CVE-2017-12602
11* CVE-2017-12603
12* CVE-2017-12604
13* CVE-2017-12605
14* CVE-2017-12606
15* CVE-2017-12862
16* CVE-2017-12863
17* CVE-2017-12864
18
19Signed-off-by: Kai Kang <kai.kang@windriver.com>
20---
21From 0d854db361106dfcb055231fd0112c5b85ef2287 Mon Sep 17 00:00:00 2001
22From: Alexander Alekhin <alexander.a.alekhin@gmail.com>
23Date: Tue, 15 Aug 2017 21:45:05 +0000
24Subject: [PATCH 1/3] build: workaround GCC 7.1.1 compilation issue with
25 sanitize flags
26
27Version: gcc (GCC) 7.1.1 20170622 (Red Hat 7.1.1-3)
28Flags: -fsanitize=address,undefined
29---
30 modules/ts/src/cuda_test.cpp | 56 ++++++++++++++++++++++++++------------------
31 1 file changed, 33 insertions(+), 23 deletions(-)
32
33diff --git a/modules/ts/src/cuda_test.cpp b/modules/ts/src/cuda_test.cpp
34index a48e0a087..eb4cee136 100644
35--- a/modules/ts/src/cuda_test.cpp
36+++ b/modules/ts/src/cuda_test.cpp
37@@ -322,16 +322,20 @@ namespace cvtest
38
39 if (m1.size() != m2.size())
40 {
41- return AssertionFailure() << "Matrices \"" << expr1 << "\" and \"" << expr2 << "\" have different sizes : \""
42- << expr1 << "\" [" << PrintToString(m1.size()) << "] vs \""
43- << expr2 << "\" [" << PrintToString(m2.size()) << "]";
44+ std::stringstream msg;
45+ msg << "Matrices \"" << expr1 << "\" and \"" << expr2 << "\" have different sizes : \""
46+ << expr1 << "\" [" << PrintToString(m1.size()) << "] vs \""
47+ << expr2 << "\" [" << PrintToString(m2.size()) << "]";
48+ return AssertionFailure() << msg.str();
49 }
50
51 if (m1.type() != m2.type())
52 {
53- return AssertionFailure() << "Matrices \"" << expr1 << "\" and \"" << expr2 << "\" have different types : \""
54- << expr1 << "\" [" << PrintToString(MatType(m1.type())) << "] vs \""
55- << expr2 << "\" [" << PrintToString(MatType(m2.type())) << "]";
56+ std::stringstream msg;
57+ msg << "Matrices \"" << expr1 << "\" and \"" << expr2 << "\" have different types : \""
58+ << expr1 << "\" [" << PrintToString(MatType(m1.type())) << "] vs \""
59+ << expr2 << "\" [" << PrintToString(MatType(m2.type())) << "]";
60+ return AssertionFailure() << msg.str();
61 }
62
63 Mat diff;
64@@ -343,12 +347,14 @@ namespace cvtest
65
66 if (maxVal > eps)
67 {
68- return AssertionFailure() << "The max difference between matrices \"" << expr1 << "\" and \"" << expr2
69- << "\" is " << maxVal << " at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ")"
70- << ", which exceeds \"" << eps_expr << "\", where \""
71- << expr1 << "\" at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ") evaluates to " << printMatVal(m1, maxLoc) << ", \""
72- << expr2 << "\" at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ") evaluates to " << printMatVal(m2, maxLoc) << ", \""
73- << eps_expr << "\" evaluates to " << eps;
74+ std::stringstream msg;
75+ msg << "The max difference between matrices \"" << expr1 << "\" and \"" << expr2
76+ << "\" is " << maxVal << " at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ")"
77+ << ", which exceeds \"" << eps_expr << "\", where \""
78+ << expr1 << "\" at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ") evaluates to " << printMatVal(m1, maxLoc) << ", \""
79+ << expr2 << "\" at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ") evaluates to " << printMatVal(m2, maxLoc) << ", \""
80+ << eps_expr << "\" evaluates to " << eps;
81+ return AssertionFailure() << msg.str();
82 }
83
84 return AssertionSuccess();
85@@ -469,9 +475,11 @@ namespace cvtest
86 {
87 if (gold.size() != actual.size())
88 {
89- return testing::AssertionFailure() << "KeyPoints size mistmach\n"
90- << "\"" << gold_expr << "\" : " << gold.size() << "\n"
91- << "\"" << actual_expr << "\" : " << actual.size();
92+ std::stringstream msg;
93+ msg << "KeyPoints size mistmach\n"
94+ << "\"" << gold_expr << "\" : " << gold.size() << "\n"
95+ << "\"" << actual_expr << "\" : " << actual.size();
96+ return AssertionFailure() << msg.str();
97 }
98
99 std::sort(actual.begin(), actual.end(), KeyPointLess());
100@@ -484,14 +492,16 @@ namespace cvtest
101
102 if (!keyPointsEquals(p1, p2))
103 {
104- return testing::AssertionFailure() << "KeyPoints differ at " << i << "\n"
105- << "\"" << gold_expr << "\" vs \"" << actual_expr << "\" : \n"
106- << "pt : " << testing::PrintToString(p1.pt) << " vs " << testing::PrintToString(p2.pt) << "\n"
107- << "size : " << p1.size << " vs " << p2.size << "\n"
108- << "angle : " << p1.angle << " vs " << p2.angle << "\n"
109- << "response : " << p1.response << " vs " << p2.response << "\n"
110- << "octave : " << p1.octave << " vs " << p2.octave << "\n"
111- << "class_id : " << p1.class_id << " vs " << p2.class_id;
112+ std::stringstream msg;
113+ msg << "KeyPoints differ at " << i << "\n"
114+ << "\"" << gold_expr << "\" vs \"" << actual_expr << "\" : \n"
115+ << "pt : " << testing::PrintToString(p1.pt) << " vs " << testing::PrintToString(p2.pt) << "\n"
116+ << "size : " << p1.size << " vs " << p2.size << "\n"
117+ << "angle : " << p1.angle << " vs " << p2.angle << "\n"
118+ << "response : " << p1.response << " vs " << p2.response << "\n"
119+ << "octave : " << p1.octave << " vs " << p2.octave << "\n"
120+ << "class_id : " << p1.class_id << " vs " << p2.class_id;
121+ return AssertionFailure() << msg.str();
122 }
123 }
124
125--
1262.14.1
127
diff --git a/meta-oe/recipes-support/opencv/opencv/0002-imgcodecs-refactoring-improve-code-quality.patch b/meta-oe/recipes-support/opencv/opencv/0002-imgcodecs-refactoring-improve-code-quality.patch
new file mode 100644
index 000000000..39f33af9d
--- /dev/null
+++ b/meta-oe/recipes-support/opencv/opencv/0002-imgcodecs-refactoring-improve-code-quality.patch
@@ -0,0 +1,656 @@
1Upstream-Status: Backport [https://github.com/opencv/opencv/pull/9376/commits/999f41fb4f4aa94a0cb47256919ae8b5c29ca5f3]
2
3Fix CVEs for opencv 3.3:
4
5* CVE-2017-12597
6* CVE-2017-12598
7* CVE-2017-12599
8* CVE-2017-12600
9* CVE-2017-12601
10* CVE-2017-12602
11* CVE-2017-12603
12* CVE-2017-12604
13* CVE-2017-12605
14* CVE-2017-12606
15* CVE-2017-12862
16* CVE-2017-12863
17* CVE-2017-12864
18
19Signed-off-by: Kai Kang <kai.kang@windriver.com>
20---
21From 999f41fb4f4aa94a0cb47256919ae8b5c29ca5f3 Mon Sep 17 00:00:00 2001
22From: Alexander Alekhin <alexander.a.alekhin@gmail.com>
23Date: Tue, 15 Aug 2017 22:04:55 +0000
24Subject: [PATCH 2/3] imgcodecs: refactoring, improve code quality
25
26---
27 modules/imgcodecs/src/bitstrm.cpp | 2 +
28 modules/imgcodecs/src/bitstrm.hpp | 19 +++--
29 modules/imgcodecs/src/grfmt_bmp.cpp | 13 ++-
30 modules/imgcodecs/src/grfmt_pxm.cpp | 122 ++++++++++++++++-----------
31 modules/imgcodecs/src/loadsave.cpp | 164 +++++++++++++++++++++++++++++-------
32 5 files changed, 231 insertions(+), 89 deletions(-)
33
34diff --git a/modules/imgcodecs/src/bitstrm.cpp b/modules/imgcodecs/src/bitstrm.cpp
35index a7e187fa0..0a8941aec 100644
36--- a/modules/imgcodecs/src/bitstrm.cpp
37+++ b/modules/imgcodecs/src/bitstrm.cpp
38@@ -209,6 +209,8 @@ int RLByteStream::getByte()
39 current = m_current;
40 }
41
42+ CV_Assert(current < m_end);
43+
44 val = *((uchar*)current);
45 m_current = current + 1;
46 return val;
47diff --git a/modules/imgcodecs/src/bitstrm.hpp b/modules/imgcodecs/src/bitstrm.hpp
48index 465c0a847..26947971f 100644
49--- a/modules/imgcodecs/src/bitstrm.hpp
50+++ b/modules/imgcodecs/src/bitstrm.hpp
51@@ -48,13 +48,20 @@
52 namespace cv
53 {
54
55-enum
56-{
57- RBS_THROW_EOS=-123, // <end of stream> exception code
58- RBS_THROW_FORB=-124, // <forrbidden huffman code> exception code
59- RBS_HUFF_FORB=2047, // forrbidden huffman code "value"
60- RBS_BAD_HEADER=-125 // invalid header
61+#define DECLARE_RBS_EXCEPTION(name) \
62+class RBS_ ## name ## _Exception : public cv::Exception \
63+{ \
64+public: \
65+ RBS_ ## name ## _Exception(int code_, const String& err_, const String& func_, const String& file_, int line_) : \
66+ cv::Exception(code_, err_, func_, file_, line_) \
67+ {} \
68 };
69+DECLARE_RBS_EXCEPTION(THROW_EOS)
70+#define RBS_THROW_EOS RBS_THROW_EOS_Exception(cv::Error::StsError, "Unexpected end of input stream", CV_Func, __FILE__, __LINE__)
71+DECLARE_RBS_EXCEPTION(THROW_FORB)
72+#define RBS_THROW_FORB RBS_THROW_FORB_Exception(cv::Error::StsError, "Forrbidden huffman code", CV_Func, __FILE__, __LINE__)
73+DECLARE_RBS_EXCEPTION(BAD_HEADER)
74+#define RBS_BAD_HEADER RBS_BAD_HEADER_Exception(cv::Error::StsError, "Invalid header", CV_Func, __FILE__, __LINE__)
75
76 typedef unsigned long ulong;
77
78diff --git a/modules/imgcodecs/src/grfmt_bmp.cpp b/modules/imgcodecs/src/grfmt_bmp.cpp
79index 86cacd316..257f97c2d 100644
80--- a/modules/imgcodecs/src/grfmt_bmp.cpp
81+++ b/modules/imgcodecs/src/grfmt_bmp.cpp
82@@ -118,8 +118,9 @@ bool BmpDecoder::readHeader()
83
84 if( m_bpp <= 8 )
85 {
86- memset( m_palette, 0, sizeof(m_palette));
87- m_strm.getBytes( m_palette, (clrused == 0? 1<<m_bpp : clrused)*4 );
88+ CV_Assert(clrused < 256);
89+ memset(m_palette, 0, sizeof(m_palette));
90+ m_strm.getBytes(m_palette, (clrused == 0? 1<<m_bpp : clrused)*4 );
91 iscolor = IsColorPalette( m_palette, m_bpp );
92 }
93 else if( m_bpp == 16 && m_rle_code == BMP_BITFIELDS )
94@@ -290,7 +291,9 @@ bool BmpDecoder::readData( Mat& img )
95 else if( code > 2 ) // absolute mode
96 {
97 if( data + code*nch > line_end ) goto decode_rle4_bad;
98- m_strm.getBytes( src, (((code + 1)>>1) + 1) & -2 );
99+ int sz = (((code + 1)>>1) + 1) & (~1);
100+ CV_Assert((size_t)sz < _src.size());
101+ m_strm.getBytes(src, sz);
102 if( color )
103 data = FillColorRow4( data, src, code, m_palette );
104 else
105@@ -379,7 +382,9 @@ decode_rle4_bad: ;
106
107 if( data + code3 > line_end )
108 goto decode_rle8_bad;
109- m_strm.getBytes( src, (code + 1) & -2 );
110+ int sz = (code + 1) & (~1);
111+ CV_Assert((size_t)sz < _src.size());
112+ m_strm.getBytes(src, sz);
113 if( color )
114 data = FillColorRow8( data, src, code, m_palette );
115 else
116diff --git a/modules/imgcodecs/src/grfmt_pxm.cpp b/modules/imgcodecs/src/grfmt_pxm.cpp
117index 1750cb705..68bd8fd93 100644
118--- a/modules/imgcodecs/src/grfmt_pxm.cpp
119+++ b/modules/imgcodecs/src/grfmt_pxm.cpp
120@@ -43,50 +43,58 @@
121 #include "precomp.hpp"
122 #include "utils.hpp"
123 #include "grfmt_pxm.hpp"
124+#include <iostream>
125
126 namespace cv
127 {
128
129 ///////////////////////// P?M reader //////////////////////////////
130
131-static int ReadNumber( RLByteStream& strm, int maxdigits )
132+static int ReadNumber(RLByteStream& strm, int maxdigits = 0)
133 {
134 int code;
135- int val = 0;
136+ int64 val = 0;
137 int digits = 0;
138
139 code = strm.getByte();
140
141- if( !isdigit(code))
142+ while (!isdigit(code))
143 {
144- do
145+ if (code == '#' )
146 {
147- if( code == '#' )
148+ do
149 {
150- do
151- {
152- code = strm.getByte();
153- }
154- while( code != '\n' && code != '\r' );
155+ code = strm.getByte();
156 }
157-
158+ while (code != '\n' && code != '\r');
159 code = strm.getByte();
160-
161- while( isspace(code))
162+ }
163+ else if (isspace(code))
164+ {
165+ while (isspace(code))
166 code = strm.getByte();
167 }
168- while( !isdigit( code ));
169+ else
170+ {
171+#if 1
172+ CV_ErrorNoReturn_(Error::StsError, ("PXM: Unexpected code in ReadNumber(): 0x%x (%d)", code, code));
173+#else
174+ code = strm.getByte();
175+#endif
176+ }
177 }
178
179 do
180 {
181- val = val*10 + code - '0';
182- if( ++digits >= maxdigits ) break;
183+ val = val*10 + (code - '0');
184+ CV_Assert(val <= INT_MAX && "PXM: ReadNumber(): result is too large");
185+ digits++;
186+ if (maxdigits != 0 && digits >= maxdigits) break;
187 code = strm.getByte();
188 }
189- while( isdigit(code));
190+ while (isdigit(code));
191
192- return val;
193+ return (int)val;
194 }
195
196
197@@ -122,13 +130,13 @@ ImageDecoder PxMDecoder::newDecoder() const
198 return makePtr<PxMDecoder>();
199 }
200
201-void PxMDecoder::close()
202+void PxMDecoder::close()
203 {
204 m_strm.close();
205 }
206
207
208-bool PxMDecoder::readHeader()
209+bool PxMDecoder::readHeader()
210 {
211 bool result = false;
212
213@@ -158,10 +166,10 @@ bool PxMDecoder::readHeader()
214 m_binary = code >= '4';
215 m_type = m_bpp > 8 ? CV_8UC3 : CV_8UC1;
216
217- m_width = ReadNumber( m_strm, INT_MAX );
218- m_height = ReadNumber( m_strm, INT_MAX );
219+ m_width = ReadNumber(m_strm);
220+ m_height = ReadNumber(m_strm);
221
222- m_maxval = m_bpp == 1 ? 1 : ReadNumber( m_strm, INT_MAX );
223+ m_maxval = m_bpp == 1 ? 1 : ReadNumber(m_strm);
224 if( m_maxval > 65535 )
225 throw RBS_BAD_HEADER;
226
227@@ -175,8 +183,14 @@ bool PxMDecoder::readHeader()
228 result = true;
229 }
230 }
231- catch(...)
232+ catch (const cv::Exception&)
233+ {
234+ throw;
235+ }
236+ catch (...)
237 {
238+ std::cerr << "PXM::readHeader(): unknown C++ exception" << std::endl << std::flush;
239+ throw;
240 }
241
242 if( !result )
243@@ -189,33 +203,28 @@ bool PxMDecoder::readHeader()
244 }
245
246
247-bool PxMDecoder::readData( Mat& img )
248+bool PxMDecoder::readData( Mat& img )
249 {
250 int color = img.channels() > 1;
251 uchar* data = img.ptr();
252 PaletteEntry palette[256];
253 bool result = false;
254- int bit_depth = CV_ELEM_SIZE1(m_type)*8;
255- int src_pitch = (m_width*m_bpp*bit_depth/8 + 7)/8;
256+ const int bit_depth = CV_ELEM_SIZE1(m_type)*8;
257+ const int src_pitch = divUp(m_width*m_bpp*(bit_depth/8), 8);
258 int nch = CV_MAT_CN(m_type);
259 int width3 = m_width*nch;
260- int i, x, y;
261
262 if( m_offset < 0 || !m_strm.isOpened())
263 return false;
264
265- AutoBuffer<uchar> _src(src_pitch + 32);
266- uchar* src = _src;
267- AutoBuffer<uchar> _gray_palette;
268- uchar* gray_palette = _gray_palette;
269+ uchar gray_palette[256] = {0};
270
271 // create LUT for converting colors
272 if( bit_depth == 8 )
273 {
274- _gray_palette.allocate(m_maxval + 1);
275- gray_palette = _gray_palette;
276+ CV_Assert(m_maxval < 256);
277
278- for( i = 0; i <= m_maxval; i++ )
279+ for (int i = 0; i <= m_maxval; i++)
280 gray_palette[i] = (uchar)((i*255/m_maxval)^(m_bpp == 1 ? 255 : 0));
281
282 FillGrayPalette( palette, m_bpp==1 ? 1 : 8 , m_bpp == 1 );
283@@ -229,12 +238,16 @@ bool PxMDecoder::readData( Mat& img )
284 {
285 ////////////////////////// 1 BPP /////////////////////////
286 case 1:
287+ CV_Assert(CV_MAT_DEPTH(m_type) == CV_8U);
288 if( !m_binary )
289 {
290- for( y = 0; y < m_height; y++, data += img.step )
291+ AutoBuffer<uchar> _src(m_width);
292+ uchar* src = _src;
293+
294+ for (int y = 0; y < m_height; y++, data += img.step)
295 {
296- for( x = 0; x < m_width; x++ )
297- src[x] = ReadNumber( m_strm, 1 ) != 0;
298+ for (int x = 0; x < m_width; x++)
299+ src[x] = ReadNumber(m_strm, 1) != 0;
300
301 if( color )
302 FillColorRow8( data, src, m_width, palette );
303@@ -244,7 +257,10 @@ bool PxMDecoder::readData( Mat& img )
304 }
305 else
306 {
307- for( y = 0; y < m_height; y++, data += img.step )
308+ AutoBuffer<uchar> _src(src_pitch);
309+ uchar* src = _src;
310+
311+ for (int y = 0; y < m_height; y++, data += img.step)
312 {
313 m_strm.getBytes( src, src_pitch );
314
315@@ -260,13 +276,17 @@ bool PxMDecoder::readData( Mat& img )
316 ////////////////////////// 8 BPP /////////////////////////
317 case 8:
318 case 24:
319- for( y = 0; y < m_height; y++, data += img.step )
320+ {
321+ AutoBuffer<uchar> _src(std::max<size_t>(width3*2, src_pitch));
322+ uchar* src = _src;
323+
324+ for (int y = 0; y < m_height; y++, data += img.step)
325 {
326 if( !m_binary )
327 {
328- for( x = 0; x < width3; x++ )
329+ for (int x = 0; x < width3; x++)
330 {
331- int code = ReadNumber( m_strm, INT_MAX );
332+ int code = ReadNumber(m_strm);
333 if( (unsigned)code > (unsigned)m_maxval ) code = m_maxval;
334 if( bit_depth == 8 )
335 src[x] = gray_palette[code];
336@@ -279,7 +299,7 @@ bool PxMDecoder::readData( Mat& img )
337 m_strm.getBytes( src, src_pitch );
338 if( bit_depth == 16 && !isBigEndian() )
339 {
340- for( x = 0; x < width3; x++ )
341+ for (int x = 0; x < width3; x++)
342 {
343 uchar v = src[x * 2];
344 src[x * 2] = src[x * 2 + 1];
345@@ -290,7 +310,7 @@ bool PxMDecoder::readData( Mat& img )
346
347 if( img.depth() == CV_8U && bit_depth == 16 )
348 {
349- for( x = 0; x < width3; x++ )
350+ for (int x = 0; x < width3; x++)
351 {
352 int v = ((ushort *)src)[x];
353 src[x] = (uchar)(v >> 8);
354@@ -331,12 +351,19 @@ bool PxMDecoder::readData( Mat& img )
355 }
356 result = true;
357 break;
358+ }
359 default:
360- assert(0);
361+ CV_ErrorNoReturn(Error::StsError, "m_bpp is not supported");
362 }
363 }
364- catch(...)
365+ catch (const cv::Exception&)
366+ {
367+ throw;
368+ }
369+ catch (...)
370 {
371+ std::cerr << "PXM::readData(): unknown exception" << std::endl << std::flush;
372+ throw;
373 }
374
375 return result;
376@@ -412,8 +439,9 @@ bool PxMEncoder::write( const Mat& img, const std::vector<int>& params )
377 char* buffer = _buffer;
378
379 // write header;
380- sprintf( buffer, "P%c\n%d %d\n%d\n",
381+ sprintf( buffer, "P%c\n# Generated by OpenCV %s\n%d %d\n%d\n",
382 '2' + (channels > 1 ? 1 : 0) + (isBinary ? 3 : 0),
383+ CV_VERSION,
384 width, height, (1 << depth) - 1 );
385
386 strm.putBytes( buffer, (int)strlen(buffer) );
387diff --git a/modules/imgcodecs/src/loadsave.cpp b/modules/imgcodecs/src/loadsave.cpp
388index 3b2366217..5ee4ca354 100644
389--- a/modules/imgcodecs/src/loadsave.cpp
390+++ b/modules/imgcodecs/src/loadsave.cpp
391@@ -55,6 +55,27 @@
392 /****************************************************************************************\
393 * Image Codecs *
394 \****************************************************************************************/
395+
396+namespace cv {
397+
398+// TODO Add runtime configuration
399+#define CV_IO_MAX_IMAGE_PARAMS (50)
400+#define CV_IO_MAX_IMAGE_WIDTH (1<<20)
401+#define CV_IO_MAX_IMAGE_HEIGHT (1<<20)
402+#define CV_IO_MAX_IMAGE_PIXELS (1<<30) // 1 Gigapixel
403+
404+static Size validateInputImageSize(const Size& size)
405+{
406+ CV_Assert(size.width > 0);
407+ CV_Assert(size.width <= CV_IO_MAX_IMAGE_WIDTH);
408+ CV_Assert(size.height > 0);
409+ CV_Assert(size.height <= CV_IO_MAX_IMAGE_HEIGHT);
410+ uint64 pixels = (uint64)size.width * (uint64)size.height;
411+ CV_Assert(pixels <= CV_IO_MAX_IMAGE_PIXELS);
412+ return size;
413+}
414+
415+
416 namespace {
417
418 class ByteStreamBuffer: public std::streambuf
419@@ -94,9 +115,6 @@ protected:
420
421 }
422
423-namespace cv
424-{
425-
426 /**
427 * @struct ImageCodecInitializer
428 *
429@@ -408,14 +426,26 @@ imread_( const String& filename, int flags, int hdrtype, Mat* mat=0 )
430 /// set the filename in the driver
431 decoder->setSource( filename );
432
433- // read the header to make sure it succeeds
434- if( !decoder->readHeader() )
435+ try
436+ {
437+ // read the header to make sure it succeeds
438+ if( !decoder->readHeader() )
439+ return 0;
440+ }
441+ catch (const cv::Exception& e)
442+ {
443+ std::cerr << "imread_('" << filename << "'): can't read header: " << e.what() << std::endl << std::flush;
444 return 0;
445+ }
446+ catch (...)
447+ {
448+ std::cerr << "imread_('" << filename << "'): can't read header: unknown exception" << std::endl << std::flush;
449+ return 0;
450+ }
451+
452
453 // established the required input image size
454- CvSize size;
455- size.width = decoder->width();
456- size.height = decoder->height();
457+ Size size = validateInputImageSize(Size(decoder->width(), decoder->height()));
458
459 // grab the decoded type
460 int type = decoder->type();
461@@ -451,7 +481,21 @@ imread_( const String& filename, int flags, int hdrtype, Mat* mat=0 )
462 }
463
464 // read the image data
465- if( !decoder->readData( *data ))
466+ bool success = false;
467+ try
468+ {
469+ if (decoder->readData(*data))
470+ success = true;
471+ }
472+ catch (const cv::Exception& e)
473+ {
474+ std::cerr << "imread_('" << filename << "'): can't read data: " << e.what() << std::endl << std::flush;
475+ }
476+ catch (...)
477+ {
478+ std::cerr << "imread_('" << filename << "'): can't read data: unknown exception" << std::endl << std::flush;
479+ }
480+ if (!success)
481 {
482 cvReleaseImage( &image );
483 cvReleaseMat( &matrix );
484@@ -504,8 +548,22 @@ imreadmulti_(const String& filename, int flags, std::vector<Mat>& mats)
485 decoder->setSource(filename);
486
487 // read the header to make sure it succeeds
488- if (!decoder->readHeader())
489+ try
490+ {
491+ // read the header to make sure it succeeds
492+ if( !decoder->readHeader() )
493+ return 0;
494+ }
495+ catch (const cv::Exception& e)
496+ {
497+ std::cerr << "imreadmulti_('" << filename << "'): can't read header: " << e.what() << std::endl << std::flush;
498 return 0;
499+ }
500+ catch (...)
501+ {
502+ std::cerr << "imreadmulti_('" << filename << "'): can't read header: unknown exception" << std::endl << std::flush;
503+ return 0;
504+ }
505
506 for (;;)
507 {
508@@ -523,17 +581,32 @@ imreadmulti_(const String& filename, int flags, std::vector<Mat>& mats)
509 type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1);
510 }
511
512+ // established the required input image size
513+ Size size = validateInputImageSize(Size(decoder->width(), decoder->height()));
514+
515 // read the image data
516- Mat mat(decoder->height(), decoder->width(), type);
517- if (!decoder->readData(mat))
518+ Mat mat(size.height, size.width, type);
519+ bool success = false;
520+ try
521 {
522- // optionally rotate the data if EXIF' orientation flag says so
523- if( (flags & IMREAD_IGNORE_ORIENTATION) == 0 && flags != IMREAD_UNCHANGED )
524- {
525- ApplyExifOrientation(filename, mat);
526- }
527-
528+ if (decoder->readData(mat))
529+ success = true;
530+ }
531+ catch (const cv::Exception& e)
532+ {
533+ std::cerr << "imreadmulti_('" << filename << "'): can't read data: " << e.what() << std::endl << std::flush;
534+ }
535+ catch (...)
536+ {
537+ std::cerr << "imreadmulti_('" << filename << "'): can't read data: unknown exception" << std::endl << std::flush;
538+ }
539+ if (!success)
540 break;
541+
542+ // optionally rotate the data if EXIF' orientation flag says so
543+ if( (flags & IMREAD_IGNORE_ORIENTATION) == 0 && flags != IMREAD_UNCHANGED )
544+ {
545+ ApplyExifOrientation(filename, mat);
546 }
547
548 mats.push_back(mat);
549@@ -616,6 +689,7 @@ static bool imwrite_( const String& filename, const Mat& image,
550 }
551
552 encoder->setDestination( filename );
553+ CV_Assert(params.size() <= CV_IO_MAX_IMAGE_PARAMS*2);
554 bool code = encoder->write( *pimage, params );
555
556 // CV_Assert( code );
557@@ -663,22 +737,35 @@ imdecode_( const Mat& buf, int flags, int hdrtype, Mat* mat=0 )
558 decoder->setSource(filename);
559 }
560
561- if( !decoder->readHeader() )
562+ bool success = false;
563+ try
564+ {
565+ if (decoder->readHeader())
566+ success = true;
567+ }
568+ catch (const cv::Exception& e)
569+ {
570+ std::cerr << "imdecode_('" << filename << "'): can't read header: " << e.what() << std::endl << std::flush;
571+ }
572+ catch (...)
573+ {
574+ std::cerr << "imdecode_('" << filename << "'): can't read header: unknown exception" << std::endl << std::flush;
575+ }
576+ if (!success)
577 {
578 decoder.release();
579- if ( !filename.empty() )
580+ if (!filename.empty())
581 {
582- if ( remove(filename.c_str()) != 0 )
583+ if (0 != remove(filename.c_str()))
584 {
585- CV_Error( CV_StsError, "unable to remove temporary file" );
586+ std::cerr << "unable to remove temporary file:" << filename << std::endl << std::flush;
587 }
588 }
589 return 0;
590 }
591
592- CvSize size;
593- size.width = decoder->width();
594- size.height = decoder->height();
595+ // established the required input image size
596+ Size size = validateInputImageSize(Size(decoder->width(), decoder->height()));
597
598 int type = decoder->type();
599 if( (flags & IMREAD_LOAD_GDAL) != IMREAD_LOAD_GDAL && flags != IMREAD_UNCHANGED )
600@@ -712,17 +799,30 @@ imdecode_( const Mat& buf, int flags, int hdrtype, Mat* mat=0 )
601 temp = cvarrToMat(image);
602 }
603
604- bool code = decoder->readData( *data );
605+ success = false;
606+ try
607+ {
608+ if (decoder->readData(*data))
609+ success = true;
610+ }
611+ catch (const cv::Exception& e)
612+ {
613+ std::cerr << "imdecode_('" << filename << "'): can't read data: " << e.what() << std::endl << std::flush;
614+ }
615+ catch (...)
616+ {
617+ std::cerr << "imdecode_('" << filename << "'): can't read data: unknown exception" << std::endl << std::flush;
618+ }
619 decoder.release();
620- if ( !filename.empty() )
621+ if (!filename.empty())
622 {
623- if ( remove(filename.c_str()) != 0 )
624+ if (0 != remove(filename.c_str()))
625 {
626- CV_Error( CV_StsError, "unable to remove temporary file" );
627+ std::cerr << "unable to remove temporary file:" << filename << std::endl << std::flush;
628 }
629 }
630
631- if( !code )
632+ if (!success)
633 {
634 cvReleaseImage( &image );
635 cvReleaseMat( &matrix );
636@@ -859,7 +959,7 @@ cvSaveImage( const char* filename, const CvArr* arr, const int* _params )
637 if( _params )
638 {
639 for( ; _params[i] > 0; i += 2 )
640- ;
641+ CV_Assert(i < CV_IO_MAX_IMAGE_PARAMS*2); // Limit number of params for security reasons
642 }
643 return cv::imwrite_(filename, cv::cvarrToMat(arr),
644 i > 0 ? std::vector<int>(_params, _params+i) : std::vector<int>(),
645@@ -890,7 +990,7 @@ cvEncodeImage( const char* ext, const CvArr* arr, const int* _params )
646 if( _params )
647 {
648 for( ; _params[i] > 0; i += 2 )
649- ;
650+ CV_Assert(i < CV_IO_MAX_IMAGE_PARAMS*2); // Limit number of params for security reasons
651 }
652 cv::Mat img = cv::cvarrToMat(arr);
653 if( CV_IS_IMAGE(arr) && ((const IplImage*)arr)->origin == IPL_ORIGIN_BL )
654--
6552.14.1
656
diff --git a/meta-oe/recipes-support/opencv/opencv/0003-imgproc-test-add-checks-for-remove-call.patch b/meta-oe/recipes-support/opencv/opencv/0003-imgproc-test-add-checks-for-remove-call.patch
new file mode 100644
index 000000000..5f4a60c96
--- /dev/null
+++ b/meta-oe/recipes-support/opencv/opencv/0003-imgproc-test-add-checks-for-remove-call.patch
@@ -0,0 +1,186 @@
1Upstream-Status: Backport [https://github.com/opencv/opencv/pull/9376/commits/78a310630fb0a1f6d089576202343e672f27609d]
2
3Fix CVEs for opencv 3.3.
4
5* CVE-2017-12597
6* CVE-2017-12598
7* CVE-2017-12599
8* CVE-2017-12600
9* CVE-2017-12601
10* CVE-2017-12602
11* CVE-2017-12603
12* CVE-2017-12604
13* CVE-2017-12605
14* CVE-2017-12606
15* CVE-2017-12862
16* CVE-2017-12863
17* CVE-2017-12864
18
19Signed-off-by: Kai Kang <kai.kang@windriver.com>
20---
21From 78a310630fb0a1f6d089576202343e672f27609d Mon Sep 17 00:00:00 2001
22From: Alexander Alekhin <alexander.alekhin@intel.com>
23Date: Wed, 16 Aug 2017 13:53:12 +0300
24Subject: [PATCH 3/3] imgproc(test): add checks for remove() call
25
26---
27 modules/imgcodecs/test/test_grfmt.cpp | 2 +-
28 modules/imgcodecs/test/test_jpeg.cpp | 12 ++++++------
29 modules/imgcodecs/test/test_png.cpp | 2 +-
30 modules/imgcodecs/test/test_read_write.cpp | 4 ++--
31 modules/imgcodecs/test/test_tiff.cpp | 8 ++++----
32 modules/imgcodecs/test/test_webp.cpp | 6 +++---
33 6 files changed, 17 insertions(+), 17 deletions(-)
34
35diff --git a/modules/imgcodecs/test/test_grfmt.cpp b/modules/imgcodecs/test/test_grfmt.cpp
36index 64a0c1e3a..74b72c3b3 100644
37--- a/modules/imgcodecs/test/test_grfmt.cpp
38+++ b/modules/imgcodecs/test/test_grfmt.cpp
39@@ -175,7 +175,7 @@ TEST_P(Imgcodecs_ExtSize, write_imageseq)
40 EXPECT_LT(n, 1.);
41 EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), img, img_gt);
42 }
43- remove(filename.c_str());
44+ EXPECT_EQ(0, remove(filename.c_str()));
45 }
46 }
47
48diff --git a/modules/imgcodecs/test/test_jpeg.cpp b/modules/imgcodecs/test/test_jpeg.cpp
49index 5546f2d91..6ddb02840 100644
50--- a/modules/imgcodecs/test/test_jpeg.cpp
51+++ b/modules/imgcodecs/test/test_jpeg.cpp
52@@ -123,8 +123,8 @@ TEST(Imgcodecs_Jpeg, encode_decode_progressive_jpeg)
53
54 EXPECT_EQ(0, cvtest::norm(img_jpg_progressive, img_jpg_normal, NORM_INF));
55
56- remove(output_progressive.c_str());
57- remove(output_normal.c_str());
58+ EXPECT_EQ(0, remove(output_progressive.c_str()));
59+ EXPECT_EQ(0, remove(output_normal.c_str()));
60 }
61
62 TEST(Imgcodecs_Jpeg, encode_decode_optimize_jpeg)
63@@ -148,8 +148,8 @@ TEST(Imgcodecs_Jpeg, encode_decode_optimize_jpeg)
64
65 EXPECT_EQ(0, cvtest::norm(img_jpg_optimized, img_jpg_normal, NORM_INF));
66
67- remove(output_optimized.c_str());
68- remove(output_normal.c_str());
69+ EXPECT_EQ(0, remove(output_optimized.c_str()));
70+ EXPECT_EQ(0, remove(output_normal.c_str()));
71 }
72
73 TEST(Imgcodecs_Jpeg, encode_decode_rst_jpeg)
74@@ -173,8 +173,8 @@ TEST(Imgcodecs_Jpeg, encode_decode_rst_jpeg)
75
76 EXPECT_EQ(0, cvtest::norm(img_jpg_rst, img_jpg_normal, NORM_INF));
77
78- remove(output_rst.c_str());
79- remove(output_normal.c_str());
80+ EXPECT_EQ(0, remove(output_rst.c_str()));
81+ EXPECT_EQ(0, remove(output_normal.c_str()));
82 }
83
84 #endif // HAVE_JPEG
85diff --git a/modules/imgcodecs/test/test_png.cpp b/modules/imgcodecs/test/test_png.cpp
86index c46f90119..4e97043e1 100644
87--- a/modules/imgcodecs/test/test_png.cpp
88+++ b/modules/imgcodecs/test/test_png.cpp
89@@ -17,7 +17,7 @@ TEST(Imgcodecs_Png, write_big)
90 EXPECT_EQ(13043, img.cols);
91 EXPECT_EQ(13917, img.rows);
92 ASSERT_NO_THROW(imwrite(dst_file, img));
93- remove(dst_file.c_str());
94+ EXPECT_EQ(0, remove(dst_file.c_str()));
95 }
96
97 TEST(Imgcodecs_Png, encode)
98diff --git a/modules/imgcodecs/test/test_read_write.cpp b/modules/imgcodecs/test/test_read_write.cpp
99index 38f10225f..5119813bf 100644
100--- a/modules/imgcodecs/test/test_read_write.cpp
101+++ b/modules/imgcodecs/test/test_read_write.cpp
102@@ -50,7 +50,7 @@ TEST(Imgcodecs_Image, read_write_bmp)
103 psnr = cvtest::PSNR(buf_loaded, image);
104 EXPECT_GT(psnr, thresDbell);
105
106- remove(dst_name.c_str());
107+ EXPECT_EQ(0, remove(dst_name.c_str()));
108 }
109 }
110
111@@ -95,7 +95,7 @@ TEST_P(Imgcodecs_Image, read_write)
112 psnr = cvtest::PSNR(buf_loaded, image);
113 EXPECT_GT(psnr, thresDbell);
114
115- remove(full_name.c_str());
116+ EXPECT_EQ(0, remove(full_name.c_str()));
117 }
118
119 const string exts[] = {
120diff --git a/modules/imgcodecs/test/test_tiff.cpp b/modules/imgcodecs/test/test_tiff.cpp
121index 0264da4cd..6ef0c1748 100644
122--- a/modules/imgcodecs/test/test_tiff.cpp
123+++ b/modules/imgcodecs/test/test_tiff.cpp
124@@ -41,8 +41,8 @@ TEST(Imgcodecs_Tiff, decode_tile16384x16384)
125 // not enough memory
126 }
127
128- remove(file3.c_str());
129- remove(file4.c_str());
130+ EXPECT_EQ(0, remove(file3.c_str()));
131+ EXPECT_EQ(0, remove(file4.c_str()));
132 }
133
134 TEST(Imgcodecs_Tiff, write_read_16bit_big_little_endian)
135@@ -88,7 +88,7 @@ TEST(Imgcodecs_Tiff, write_read_16bit_big_little_endian)
136 EXPECT_EQ(0xDEAD, img.at<ushort>(0,0));
137 EXPECT_EQ(0xBEEF, img.at<ushort>(0,1));
138
139- remove(filename.c_str());
140+ EXPECT_EQ(0, remove(filename.c_str()));
141 }
142 }
143
144@@ -143,7 +143,7 @@ TEST(Imgcodecs_Tiff, decode_infinite_rowsperstrip)
145
146 EXPECT_NO_THROW(cv::imread(filename, IMREAD_UNCHANGED));
147
148- remove(filename.c_str());
149+ EXPECT_EQ(0, remove(filename.c_str()));
150 }
151
152 //==================================================================================================
153diff --git a/modules/imgcodecs/test/test_webp.cpp b/modules/imgcodecs/test/test_webp.cpp
154index 6d40ce21e..d82fdd289 100644
155--- a/modules/imgcodecs/test/test_webp.cpp
156+++ b/modules/imgcodecs/test/test_webp.cpp
157@@ -44,7 +44,7 @@ TEST(Imgcodecs_WebP, encode_decode_lossless_webp)
158 }
159 }
160
161- remove(output.c_str());
162+ EXPECT_EQ(0, remove(output.c_str()));
163
164 cv::Mat decode = cv::imdecode(buf, IMREAD_COLOR);
165 ASSERT_FALSE(decode.empty());
166@@ -71,7 +71,7 @@ TEST(Imgcodecs_WebP, encode_decode_lossy_webp)
167
168 EXPECT_NO_THROW(cv::imwrite(output, img, params));
169 cv::Mat img_webp = cv::imread(output);
170- remove(output.c_str());
171+ EXPECT_EQ(0, remove(output.c_str()));
172 EXPECT_FALSE(img_webp.empty());
173 EXPECT_EQ(3, img_webp.channels());
174 EXPECT_EQ(512, img_webp.cols);
175@@ -96,7 +96,7 @@ TEST(Imgcodecs_WebP, encode_decode_with_alpha_webp)
176
177 EXPECT_NO_THROW(cv::imwrite(output, img));
178 cv::Mat img_webp = cv::imread(output);
179- remove(output.c_str());
180+ EXPECT_EQ(0, remove(output.c_str()));
181 EXPECT_FALSE(img_webp.empty());
182 EXPECT_EQ(4, img_webp.channels());
183 EXPECT_EQ(512, img_webp.cols);
184--
1852.14.1
186
diff --git a/meta-oe/recipes-support/opencv/opencv_3.3.bb b/meta-oe/recipes-support/opencv/opencv_3.3.bb
index a6a130271..efbb2f52a 100644
--- a/meta-oe/recipes-support/opencv/opencv_3.3.bb
+++ b/meta-oe/recipes-support/opencv/opencv_3.3.bb
@@ -46,6 +46,9 @@ SRC_URI = "git://github.com/opencv/opencv.git;name=opencv \
46 file://uselocalxfeatures.patch;patchdir=../contrib/ \ 46 file://uselocalxfeatures.patch;patchdir=../contrib/ \
47 file://0002-Make-opencv-ts-create-share-library-intead-of-static.patch \ 47 file://0002-Make-opencv-ts-create-share-library-intead-of-static.patch \
48 file://0003-To-fix-errors-as-following.patch \ 48 file://0003-To-fix-errors-as-following.patch \
49 file://0001-build-workaround-GCC-7.1.1-compilation-issue-with-sa.patch \
50 file://0002-imgcodecs-refactoring-improve-code-quality.patch \
51 file://0003-imgproc-test-add-checks-for-remove-call.patch \
49" 52"
50 53
51PV = "3.3+git${SRCPV}" 54PV = "3.3+git${SRCPV}"