aboutsummaryrefslogtreecommitdiffstats
path: root/meta-oe/recipes-support
diff options
context:
space:
mode:
authorNeetika Singh <Neetika.Singh@kpit.com>2021-03-09 16:53:36 +0530
committerArmin Kuster <akuster808@gmail.com>2021-03-16 08:40:07 -0700
commit389757a7494221fea1d8437e9a01c6e4fb4700af (patch)
treea5ba4856aeb7ae62a7dc4b3300902bb81fc6923c /meta-oe/recipes-support
parent1ad4455f2830c408f9c2e7a4b094c5e555db0cf2 (diff)
downloadmeta-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>
Diffstat (limited to 'meta-oe/recipes-support')
-rw-r--r--meta-oe/recipes-support/opencv/opencv/CVE-2019-14491.patch148
-rw-r--r--meta-oe/recipes-support/opencv/opencv/CVE-2019-14493.patch237
-rw-r--r--meta-oe/recipes-support/opencv/opencv/CVE-2019-15939.patch73
-rw-r--r--meta-oe/recipes-support/opencv/opencv/CVE-2019-19624.patch157
-rw-r--r--meta-oe/recipes-support/opencv/opencv_4.1.0.bb4
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 @@
+From 321c74ccd6077bdea1d47450ca4fe955cb5b6330 Mon Sep 17 00:00:00 2001
+From: Alexander Alekhin <alexander.alekhin@intel.com>
+Date: Thu, 25 Jul 2019 17:15:59 +0300
+Subject: [PATCH] objdetect: validate feature rectangle on reading
+
+CVE: CVE-2019-14491
+CVE: CVE-2019-14492
+Upstream-Status: Backport [https://github.com/opencv/opencv/commit/ac425f67e4c1d0da9afb9203f0918d8d57c067ed.patch]
+Comment: No changes in any hunk
+
+Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
+---
+ modules/objdetect/src/cascadedetect.cpp | 43 +++++++++++++++++++++----
+ modules/objdetect/src/cascadedetect.hpp | 6 ++--
+ 2 files changed, 40 insertions(+), 9 deletions(-)
+
+diff --git a/modules/objdetect/src/cascadedetect.cpp b/modules/objdetect/src/cascadedetect.cpp
+index 4b2078306fe..bd62cd21a1b 100644
+--- a/modules/objdetect/src/cascadedetect.cpp
++++ b/modules/objdetect/src/cascadedetect.cpp
+@@ -47,6 +47,10 @@
+ #include "opencv2/objdetect/objdetect_c.h"
+ #include "opencl_kernels_objdetect.hpp"
+
++#if defined(_MSC_VER)
++# pragma warning(disable:4458) // declaration of 'origWinSize' hides class member
++#endif
++
+ namespace cv
+ {
+
+@@ -537,7 +541,7 @@ bool FeatureEvaluator::setImage( InputArray _image, const std::vector<float>& _s
+
+ //---------------------------------------------- HaarEvaluator ---------------------------------------
+
+-bool HaarEvaluator::Feature :: read( const FileNode& node )
++bool HaarEvaluator::Feature::read(const FileNode& node, const Size& origWinSize)
+ {
+ FileNode rnode = node[CC_RECTS];
+ FileNodeIterator it = rnode.begin(), it_end = rnode.end();
+@@ -549,11 +553,23 @@ bool HaarEvaluator::Feature :: read( const FileNode& node )
+ rect[ri].weight = 0.f;
+ }
+
++ const int W = origWinSize.width;
++ const int H = origWinSize.height;
++
+ for(ri = 0; it != it_end; ++it, ri++)
+ {
+ FileNodeIterator it2 = (*it).begin();
+- it2 >> rect[ri].r.x >> rect[ri].r.y >>
+- rect[ri].r.width >> rect[ri].r.height >> rect[ri].weight;
++ Feature::RectWeigth& rw = rect[ri];
++ it2 >> rw.r.x >> rw.r.y >> rw.r.width >> rw.r.height >> rw.weight;
++ // input validation
++ {
++ CV_CheckGE(rw.r.x, 0, "Invalid HAAR feature");
++ CV_CheckGE(rw.r.y, 0, "Invalid HAAR feature");
++ CV_CheckLT(rw.r.x, W, "Invalid HAAR feature"); // necessary for overflow checks
++ CV_CheckLT(rw.r.y, H, "Invalid HAAR feature"); // necessary for overflow checks
++ CV_CheckLE(rw.r.x + rw.r.width, W, "Invalid HAAR feature");
++ CV_CheckLE(rw.r.y + rw.r.height, H, "Invalid HAAR feature");
++ }
+ }
+
+ tilted = (int)node[CC_TILTED] != 0;
+@@ -598,7 +614,7 @@ bool HaarEvaluator::read(const FileNode& node, Size _origWinSize)
+
+ for(i = 0; i < n; i++, ++it)
+ {
+- if(!ff[i].read(*it))
++ if(!ff[i].read(*it, _origWinSize))
+ return false;
+ if( ff[i].tilted )
+ hasTiltedFeatures = true;
+@@ -759,11 +775,24 @@ int HaarEvaluator::getSquaresOffset() const
+ }
+
+ //---------------------------------------------- LBPEvaluator -------------------------------------
+-bool LBPEvaluator::Feature :: read(const FileNode& node )
++bool LBPEvaluator::Feature::read(const FileNode& node, const Size& origWinSize)
+ {
+ FileNode rnode = node[CC_RECT];
+ FileNodeIterator it = rnode.begin();
+ it >> rect.x >> rect.y >> rect.width >> rect.height;
++
++ const int W = origWinSize.width;
++ const int H = origWinSize.height;
++ // input validation
++ {
++ CV_CheckGE(rect.x, 0, "Invalid LBP feature");
++ CV_CheckGE(rect.y, 0, "Invalid LBP feature");
++ CV_CheckLT(rect.x, W, "Invalid LBP feature");
++ CV_CheckLT(rect.y, H, "Invalid LBP feature");
++ CV_CheckLE(rect.x + rect.width, W, "Invalid LBP feature");
++ CV_CheckLE(rect.y + rect.height, H, "Invalid LBP feature");
++ }
++
+ return true;
+ }
+
+@@ -797,7 +826,7 @@ bool LBPEvaluator::read( const FileNode& node, Size _origWinSize )
+ std::vector<Feature>& ff = *features;
+ for(int i = 0; it != it_end; ++it, i++)
+ {
+- if(!ff[i].read(*it))
++ if(!ff[i].read(*it, _origWinSize))
+ return false;
+ }
+ nchannels = 1;
+@@ -1477,6 +1506,8 @@ bool CascadeClassifierImpl::Data::read(const FileNode &root)
+ origWinSize.width = (int)root[CC_WIDTH];
+ origWinSize.height = (int)root[CC_HEIGHT];
+ CV_Assert( origWinSize.height > 0 && origWinSize.width > 0 );
++ CV_CheckLE(origWinSize.width, 1000000, "Invalid window size (too large)");
++ CV_CheckLE(origWinSize.height, 1000000, "Invalid window size (too large)");
+
+ // load feature params
+ FileNode fn = root[CC_FEATURE_PARAMS];
+diff --git a/modules/objdetect/src/cascadedetect.hpp b/modules/objdetect/src/cascadedetect.hpp
+index f9910530b94..d9a288fcdda 100644
+--- a/modules/objdetect/src/cascadedetect.hpp
++++ b/modules/objdetect/src/cascadedetect.hpp
+@@ -317,12 +317,12 @@ class HaarEvaluator CV_FINAL : public FeatureEvaluator
+ struct Feature
+ {
+ Feature();
+- bool read( const FileNode& node );
++ bool read(const FileNode& node, const Size& origWinSize);
+
+ bool tilted;
+
+ enum { RECT_NUM = 3 };
+- struct
++ struct RectWeigth
+ {
+ Rect r;
+ float weight;
+@@ -412,7 +412,7 @@ class LBPEvaluator CV_FINAL : public FeatureEvaluator
+ Feature( int x, int y, int _block_w, int _block_h ) :
+ rect(x, y, _block_w, _block_h) {}
+
+- bool read(const FileNode& node );
++ bool read(const FileNode& node, const Size& origWinSize);
+
+ Rect rect; // weight and height for block
+ };
+
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 @@
+From 5691d998ead1d9b0542bcfced36c2dceb3a59023 Mon Sep 17 00:00:00 2001
+From: Alexander Alekhin <alexander.alekhin@intel.com>
+Date: Thu, 25 Jul 2019 15:14:22 +0300
+Subject: [PATCH] core(persistence): added null ptr checks
+
+CVE: CVE-2019-14493
+Upstream-Status: Backport [https://github.com/opencv/opencv/commit/5691d998ead1d9b0542bcfced36c2dceb3a59023.patch]
+Comment: No changes in any hunk
+
+Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
+---
+ modules/core/src/persistence_json.cpp | 12 ++++++++++++
+ modules/core/src/persistence_xml.cpp | 21 +++++++++++++++++++++
+ modules/core/src/persistence_yml.cpp | 21 +++++++++++++++++++++
+ 3 files changed, 54 insertions(+)
+
+diff --git a/modules/core/src/persistence_json.cpp b/modules/core/src/persistence_json.cpp
+index ae678e1b8b1..89914e6534f 100644
+--- a/modules/core/src/persistence_json.cpp
++++ b/modules/core/src/persistence_json.cpp
+@@ -296,6 +296,8 @@ class JSONParser : public FileStorageParser
+
+ while ( is_eof == false && is_completed == false )
+ {
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid input");
+ switch ( *ptr )
+ {
+ /* comment */
+@@ -381,6 +383,7 @@ class JSONParser : public FileStorageParser
+ if ( is_eof || !is_completed )
+ {
+ ptr = fs->bufferStart();
++ CV_Assert(ptr);
+ *ptr = '\0';
+ fs->setEof();
+ if( !is_completed )
+@@ -392,6 +395,9 @@ class JSONParser : public FileStorageParser
+
+ char* parseKey( char* ptr, FileNode& collection, FileNode& value_placeholder )
+ {
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid input");
++
+ if( *ptr != '"' )
+ CV_PARSE_ERROR_CPP( "Key must start with \'\"\'" );
+
+@@ -430,6 +436,9 @@ class JSONParser : public FileStorageParser
+
+ char* parseValue( char* ptr, FileNode& node )
+ {
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid value input");
++
+ ptr = skipSpaces( ptr );
+ if( !ptr || !*ptr )
+ CV_PARSE_ERROR_CPP( "Unexpected End-Of-File" );
+@@ -817,6 +826,9 @@ class JSONParser : public FileStorageParser
+
+ bool parse( char* ptr )
+ {
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid input");
++
+ ptr = skipSpaces( ptr );
+ if ( !ptr || !*ptr )
+ return false;
+diff --git a/modules/core/src/persistence_xml.cpp b/modules/core/src/persistence_xml.cpp
+index fb30d90896e..89876dd3da8 100644
+--- a/modules/core/src/persistence_xml.cpp
++++ b/modules/core/src/persistence_xml.cpp
+@@ -360,6 +360,9 @@ class XMLParser : public FileStorageParser
+
+ char* skipSpaces( char* ptr, int mode )
+ {
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid input");
++
+ int level = 0;
+
+ for(;;)
+@@ -441,6 +444,9 @@ class XMLParser : public FileStorageParser
+
+ char* parseValue( char* ptr, FileNode& node )
+ {
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid input");
++
+ FileNode new_elem;
+ bool have_space = true;
+ int value_type = node.type();
+@@ -456,6 +462,8 @@ class XMLParser : public FileStorageParser
+ (c == '<' && ptr[1] == '!' && ptr[2] == '-') )
+ {
+ ptr = skipSpaces( ptr, 0 );
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid input");
+ have_space = true;
+ c = *ptr;
+ }
+@@ -502,6 +510,8 @@ class XMLParser : public FileStorageParser
+ {
+ ptr = fs->parseBase64( ptr, 0, new_elem);
+ ptr = skipSpaces( ptr, 0 );
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid input");
+ }
+
+ ptr = parseTag( ptr, key2, type_name, tag_type );
+@@ -645,6 +655,9 @@ class XMLParser : public FileStorageParser
+ char* parseTag( char* ptr, std::string& tag_name,
+ std::string& type_name, int& tag_type )
+ {
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid tag input");
++
+ if( *ptr == '\0' )
+ CV_PARSE_ERROR_CPP( "Unexpected end of the stream" );
+
+@@ -702,6 +715,8 @@ class XMLParser : public FileStorageParser
+ if( *ptr != '=' )
+ {
+ ptr = skipSpaces( ptr, CV_XML_INSIDE_TAG );
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid attribute");
+ if( *ptr != '=' )
+ CV_PARSE_ERROR_CPP( "Attribute name should be followed by \'=\'" );
+ }
+@@ -740,6 +755,8 @@ class XMLParser : public FileStorageParser
+ if( c != '>' )
+ {
+ ptr = skipSpaces( ptr, CV_XML_INSIDE_TAG );
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid input");
+ c = *ptr;
+ }
+
+@@ -781,6 +798,8 @@ class XMLParser : public FileStorageParser
+
+ // CV_XML_INSIDE_TAG is used to prohibit leading comments
+ ptr = skipSpaces( ptr, CV_XML_INSIDE_TAG );
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid input");
+
+ if( memcmp( ptr, "<?xml", 5 ) != 0 ) // FIXIT ptr[1..] - out of bounds read without check
+ CV_PARSE_ERROR_CPP( "Valid XML should start with \'<?xml ...?>\'" );
+@@ -791,6 +810,8 @@ class XMLParser : public FileStorageParser
+ while( ptr && *ptr != '\0' )
+ {
+ ptr = skipSpaces( ptr, 0 );
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid input");
+
+ if( *ptr != '\0' )
+ {
+diff --git a/modules/core/src/persistence_yml.cpp b/modules/core/src/persistence_yml.cpp
+index 4129ca1dc57..7742e827701 100644
+--- a/modules/core/src/persistence_yml.cpp
++++ b/modules/core/src/persistence_yml.cpp
+@@ -330,6 +330,9 @@ class YAMLParser : public FileStorageParser
+
+ char* skipSpaces( char* ptr, int min_indent, int max_comment_indent )
+ {
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid input");
++
+ for(;;)
+ {
+ while( *ptr == ' ' )
+@@ -374,6 +377,9 @@ class YAMLParser : public FileStorageParser
+
+ bool getBase64Row(char* ptr, int indent, char* &beg, char* &end)
+ {
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid input");
++
+ beg = end = ptr = skipSpaces(ptr, 0, INT_MAX);
+ if (!ptr || !*ptr)
+ return false; // end of file
+@@ -394,6 +400,9 @@ class YAMLParser : public FileStorageParser
+
+ char* parseKey( char* ptr, FileNode& map_node, FileNode& value_placeholder )
+ {
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid input");
++
+ char c;
+ char *endptr = ptr - 1, *saveptr;
+
+@@ -422,6 +431,9 @@ class YAMLParser : public FileStorageParser
+
+ char* parseValue( char* ptr, FileNode& node, int min_indent, bool is_parent_flow )
+ {
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid input");
++
+ char* endptr = 0;
+ char c = ptr[0], d = ptr[1];
+ int value_type = FileNode::NONE;
+@@ -508,6 +520,8 @@ class YAMLParser : public FileStorageParser
+
+ *endptr = d;
+ ptr = skipSpaces( endptr, min_indent, INT_MAX );
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid input");
+
+ c = *ptr;
+
+@@ -634,6 +648,8 @@ class YAMLParser : public FileStorageParser
+ FileNode elem;
+
+ ptr = skipSpaces( ptr, new_min_indent, INT_MAX );
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid input");
+ if( *ptr == '}' || *ptr == ']' )
+ {
+ if( *ptr != d )
+@@ -647,6 +663,8 @@ class YAMLParser : public FileStorageParser
+ if( *ptr != ',' )
+ CV_PARSE_ERROR_CPP( "Missing , between the elements" );
+ ptr = skipSpaces( ptr + 1, new_min_indent, INT_MAX );
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid input");
+ }
+
+ if( struct_type == FileNode::MAP )
+@@ -746,6 +764,9 @@ class YAMLParser : public FileStorageParser
+
+ bool parse( char* ptr )
+ {
++ if (!ptr)
++ CV_PARSE_ERROR_CPP("Invalid input");
++
+ bool first = true;
+ bool ok = true;
+ FileNode root_collection(fs->getFS(), 0, 0);
+
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 @@
+From 5a497077f109d543ab86dfdf8add1c76c0e47d29 Mon Sep 17 00:00:00 2001
+From: Alexander Alekhin <alexander.alekhin@intel.com>
+Date: Fri, 23 Aug 2019 16:14:53 +0300
+Subject: [PATCH] objdetect: add input check in HOG detector
+
+CVE: CVE-2019-15939
+Upstream-Status: Backport [https://github.com/opencv/opencv/commit/5a497077f109d543ab86dfdf8add1c76c0e47d29.patch]
+Comment: No changes in any hunk
+
+Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
+---
+ modules/objdetect/src/hog.cpp | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+diff --git a/modules/objdetect/src/hog.cpp b/modules/objdetect/src/hog.cpp
+index 9524851eebb..378bab30876 100644
+--- a/modules/objdetect/src/hog.cpp
++++ b/modules/objdetect/src/hog.cpp
+@@ -68,6 +68,7 @@ enum {DESCR_FORMAT_COL_BY_COL, DESCR_FORMAT_ROW_BY_ROW};
+
+ static int numPartsWithin(int size, int part_size, int stride)
+ {
++ CV_Assert(stride != 0);
+ return (size - part_size + stride) / stride;
+ }
+
+@@ -80,13 +81,17 @@ static Size numPartsWithin(cv::Size size, cv::Size part_size,
+
+ static size_t getBlockHistogramSize(Size block_size, Size cell_size, int nbins)
+ {
++ CV_Assert(!cell_size.empty());
+ Size cells_per_block = Size(block_size.width / cell_size.width,
+- block_size.height / cell_size.height);
++ block_size.height / cell_size.height);
+ return (size_t)(nbins * cells_per_block.area());
+ }
+
+ size_t HOGDescriptor::getDescriptorSize() const
+ {
++ CV_Assert(!cellSize.empty());
++ CV_Assert(!blockStride.empty());
++
+ CV_Assert(blockSize.width % cellSize.width == 0 &&
+ blockSize.height % cellSize.height == 0);
+ CV_Assert((winSize.width - blockSize.width) % blockStride.width == 0 &&
+@@ -144,20 +149,20 @@ bool HOGDescriptor::read(FileNode& obj)
+ if( !obj.isMap() )
+ return false;
+ FileNodeIterator it = obj["winSize"].begin();
+- it >> winSize.width >> winSize.height;
++ it >> winSize.width >> winSize.height; CV_Assert(!winSize.empty());
+ it = obj["blockSize"].begin();
+- it >> blockSize.width >> blockSize.height;
++ it >> blockSize.width >> blockSize.height; CV_Assert(!blockSize.empty());
+ it = obj["blockStride"].begin();
+- it >> blockStride.width >> blockStride.height;
++ it >> blockStride.width >> blockStride.height; CV_Assert(!blockStride.empty());
+ it = obj["cellSize"].begin();
+- it >> cellSize.width >> cellSize.height;
+- obj["nbins"] >> nbins;
++ it >> cellSize.width >> cellSize.height; CV_Assert(!cellSize.empty());
++ obj["nbins"] >> nbins; CV_Assert(nbins > 0);
+ obj["derivAperture"] >> derivAperture;
+ obj["winSigma"] >> winSigma;
+ obj["histogramNormType"] >> histogramNormType;
+ obj["L2HysThreshold"] >> L2HysThreshold;
+ obj["gammaCorrection"] >> gammaCorrection;
+- obj["nlevels"] >> nlevels;
++ obj["nlevels"] >> nlevels; CV_Assert(nlevels > 0);
+ if (obj["signedGradient"].empty())
+ signedGradient = false;
+ else
+
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 @@
+From d1615ba11a93062b1429fce9f0f638d1572d3418 Mon Sep 17 00:00:00 2001
+From: Thang Tran <TranKimThang279@gmail.com>
+Date: Mon, 27 May 2019 08:18:26 +0200
+Subject: [PATCH] video:fixed DISOpticalFlow segfault from small img
+
+CVE: CVE-2019-19624
+Upstream-Status: Backport [https://github.com/opencv/opencv/commit/d1615ba11a93062b1429fce9f0f638d1572d3418.patch]
+Comment: No changes in any hunk
+
+Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
+---
+ modules/video/src/dis_flow.cpp | 67 ++++++++++++++++++++++++-
+ modules/video/test/test_OF_accuracy.cpp | 28 +++++++++++
+ 2 files changed, 93 insertions(+), 2 deletions(-)
+
+diff --git a/modules/video/src/dis_flow.cpp b/modules/video/src/dis_flow.cpp
+index a453d8b2b51..806d6f1ddaf 100644
+--- a/modules/video/src/dis_flow.cpp
++++ b/modules/video/src/dis_flow.cpp
+@@ -140,6 +140,8 @@ class DISOpticalFlowImpl CV_FINAL : public DISOpticalFlow
+ void prepareBuffers(Mat &I0, Mat &I1, Mat &flow, bool use_flow);
+ void precomputeStructureTensor(Mat &dst_I0xx, Mat &dst_I0yy, Mat &dst_I0xy, Mat &dst_I0x, Mat &dst_I0y, Mat &I0x,
+ Mat &I0y);
++ int autoSelectCoarsestScale(int img_width);
++ void autoSelectPatchSizeAndScales(int img_width);
+
+ struct PatchInverseSearch_ParBody : public ParallelLoopBody
+ {
+@@ -435,6 +437,44 @@ void DISOpticalFlowImpl::precomputeStructureTensor(Mat &dst_I0xx, Mat &dst_I0yy,
+ }
+ }
+
++int DISOpticalFlowImpl::autoSelectCoarsestScale(int img_width)
++{
++ const int fratio = 5;
++ return std::max(0, (int)std::floor(log2((2.0f*(float)img_width) / ((float)fratio * (float)patch_size))));
++}
++
++void DISOpticalFlowImpl::autoSelectPatchSizeAndScales(int img_width)
++{
++ switch (finest_scale)
++ {
++ case 1:
++ patch_size = 8;
++ coarsest_scale = autoSelectCoarsestScale(img_width);
++ finest_scale = std::max(coarsest_scale-2, 0);
++ break;
++
++ case 3:
++ patch_size = 12;
++ coarsest_scale = autoSelectCoarsestScale(img_width);
++ finest_scale = std::max(coarsest_scale-4, 0);
++ break;
++
++ case 4:
++ patch_size = 12;
++ coarsest_scale = autoSelectCoarsestScale(img_width);
++ finest_scale = std::max(coarsest_scale-5, 0);
++ break;
++
++ // default case, fall-through.
++ case 2:
++ default:
++ patch_size = 8;
++ coarsest_scale = autoSelectCoarsestScale(img_width);
++ finest_scale = std::max(coarsest_scale-2, 0);
++ break;
++ }
++}
++
+ DISOpticalFlowImpl::PatchInverseSearch_ParBody::PatchInverseSearch_ParBody(DISOpticalFlowImpl &_dis, int _nstripes,
+ int _hs, Mat &dst_Sx, Mat &dst_Sy,
+ Mat &src_Ux, Mat &src_Uy, Mat &_I0, Mat &_I1,
+@@ -1318,9 +1358,20 @@ bool DISOpticalFlowImpl::ocl_calc(InputArray I0, InputArray I1, InputOutputArray
+ else
+ flow.create(I1Mat.size(), CV_32FC2);
+ UMat &u_flowMat = flow.getUMatRef();
+- 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 */
++ 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 */
+ (int)(log(min(I0Mat.cols, I0Mat.rows) / patch_size) / log(2.0))); /* Deepest pyramid level greater or equal than patch*/
+
++ if (coarsest_scale<0)
++ CV_Error(cv::Error::StsBadSize, "The input image must have either width or height >= 12");
++
++ if (coarsest_scale<finest_scale)
++ {
++ // choose the finest level based on coarsest level.
++ // Refs: https://github.com/tikroeger/OF_DIS/blob/2c9f2a674f3128d3a41c10e41cc9f3a35bb1b523/run_dense.cpp#L239
++ int original_img_width = I0.size().width;
++ autoSelectPatchSizeAndScales(original_img_width);
++ }
++
+ ocl_prepareBuffers(I0Mat, I1Mat, u_flowMat, use_input_flow);
+ u_Ux[coarsest_scale].setTo(0.0f);
+ u_Uy[coarsest_scale].setTo(0.0f);
+@@ -1385,8 +1436,20 @@ void DISOpticalFlowImpl::calc(InputArray I0, InputArray I1, InputOutputArray flo
+ else
+ flow.create(I1Mat.size(), CV_32FC2);
+ Mat flowMat = flow.getMat();
+- 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 */
++ 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 */
+ (int)(log(min(I0Mat.cols, I0Mat.rows) / patch_size) / log(2.0))); /* Deepest pyramid level greater or equal than patch*/
++
++ if (coarsest_scale<0)
++ CV_Error(cv::Error::StsBadSize, "The input image must have either width or height >= 12");
++
++ if (coarsest_scale<finest_scale)
++ {
++ // choose the finest level based on coarsest level.
++ // Refs: https://github.com/tikroeger/OF_DIS/blob/2c9f2a674f3128d3a41c10e41cc9f3a35bb1b523/run_dense.cpp#L239
++ int original_img_width = I0.size().width;
++ autoSelectPatchSizeAndScales(original_img_width);
++ }
++
+ int num_stripes = getNumThreads();
+
+ prepareBuffers(I0Mat, I1Mat, flowMat, use_input_flow);
+diff --git a/modules/video/test/test_OF_accuracy.cpp b/modules/video/test/test_OF_accuracy.cpp
+index affbab65866..b99ffce2a8b 100644
+--- a/modules/video/test/test_OF_accuracy.cpp
++++ b/modules/video/test/test_OF_accuracy.cpp
+@@ -121,6 +121,34 @@ TEST(DenseOpticalFlow_DIS, ReferenceAccuracy)
+ }
+ }
+
++TEST(DenseOpticalFlow_DIS, InvalidImgSize_CoarsestLevelLessThanZero)
++{
++ cv::Ptr<cv::DISOpticalFlow> of = cv::DISOpticalFlow::create();
++ const int mat_size = 10;
++
++ cv::Mat x(mat_size, mat_size, CV_8UC1, 42);
++ cv::Mat y(mat_size, mat_size, CV_8UC1, 42);
++ cv::Mat flow;
++
++ ASSERT_THROW(of->calc(x, y, flow), cv::Exception);
++}
++
++// make sure that autoSelectPatchSizeAndScales() works properly.
++TEST(DenseOpticalFlow_DIS, InvalidImgSize_CoarsestLevelLessThanFinestLevel)
++{
++ cv::Ptr<cv::DISOpticalFlow> of = cv::DISOpticalFlow::create();
++ const int mat_size = 80;
++
++ cv::Mat x(mat_size, mat_size, CV_8UC1, 42);
++ cv::Mat y(mat_size, mat_size, CV_8UC1, 42);
++ cv::Mat flow;
++
++ of->calc(x, y, flow);
++
++ ASSERT_EQ(flow.rows, mat_size);
++ ASSERT_EQ(flow.cols, mat_size);
++}
++
+ TEST(DenseOpticalFlow_VariationalRefinement, ReferenceAccuracy)
+ {
+ Mat frame1, frame2, GT;
+
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 \
file://0001-Dont-use-isystem.patch \
file://0001-carotene-Replace-ipcp-unit-growth-with-ipa-cp-unit-g.patch \
file://download.patch \
+ file://CVE-2019-14491.patch \
+ file://CVE-2019-14493.patch \
+ file://CVE-2019-15939.patch \
+ file://CVE-2019-19624.patch \
"
PV = "4.1.0"