Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DISOpticalFlow: segfault for small images #14554

Closed
vasiliev-vb opened this issue May 14, 2019 · 2 comments · Fixed by #14641
Closed

DISOpticalFlow: segfault for small images #14554

vasiliev-vb opened this issue May 14, 2019 · 2 comments · Fixed by #14641

Comments

@vasiliev-vb
Copy link
Contributor

System information (version)
  • OpenCV => 4.0
  • Operating System / Platform => Any
  • Compiler => Any
Detailed description

DISOpticalFlow segfaults for small images.
The problem is in the calculation of pyramid scales.

Variable coarsest_scale is assumed to be greater or equal than finest_scale in calc()/ocl_calc() functions, while this is not true for small images. Actually, coarsest_scale can be even less than 0.

If coarsest_scale is less than finest_scale, loop body in calc()/ocl_calc() functions doesn't execute and Ux,Uy arrays are accessed out-of-bounds.

As a solution, the finest level may be selected dependent on the coarsest level as in DIS author's code instead of constant for every preset, while coarsest level may be limited to be greater or equal than zero.

Steps to reproduce
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/video/tracking.hpp>

int main(int argc, char *argv[]) {

    cv::Ptr<cv::DISOpticalFlow> of = cv::DISOpticalFlow::create();

    const int mat_size = 10; // use mat_size<=90 to crash and <= 11 to get coarsest_level<0
    const int patch_size = 8;
    int dis_coarsest_scale = (int)(std::log(mat_size / (4.0 * patch_size)) / std::log(2.0) + 0.5); /* Original code serach for maximal movement of width/4 */
    std::cout << "Coarsest scale " << dis_coarsest_scale << ", finest scale " << of->getFinestScale() << std::endl;

    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);

    std::cout << "Result size " << flow.rows << ", " << flow.cols << std::endl;

    return 0;
}
@thangktran
Copy link
Contributor

i'm working on this issue.

@jzySaber1996
Copy link

Hello, we're investigating the issue reports in security. Since we observed that this issue may relate to security, has it been disclosed in CVE already? Thanks for your reply.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants