OpenEXR vulnerabilities
wqh17101 opened this issue ยท 21 comments
OpenCV 4.5.5/3.4.17: disabled OpenEXR in runtime: #21327
System information (version)
- OpenCV => 4.5.2
- Operating System / Platform => Linux
- Compiler => gcc 7.3.0
Detailed description
For openexr
according to http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=openexr
CVE-2021-23169
CVE-2021-3479
CVE-2020-15306
CVE-2020-15304
CVE-2020-11758
CVE-2021-3605
CVE-2021-23215
CVE-2020-15305
CVE-2020-11760
CVE-2020-11765
For openjpeg
according to http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-29338
CVE-2021-29338
Steps to reproduce
build for default
Issue submission checklist
- I report the issue, it's not a question
- I checked the problem with documentation, FAQ, open issues,
forum.opencv.org, Stack Overflow, etc and have not found solution - I updated to latest OpenCV version and the issue is still there
- There is reproducer code and related data files: videos, images, onnx, etc
Why is it so hard to put text information as text? Text screenshots are ridiculous.
Do you understand that this blocks searching?
Why is it so hard to put text information as text? Text screenshots are ridiculous. Do you understand that this blocks searching?
Sorry for that.
according to http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=openexr
CVE-2021-23169
CVE-2021-3479
CVE-2020-15306
CVE-2020-15304
CVE-2020-11758
CVE-2021-3605
CVE-2021-23215
CVE-2020-15305
CVE-2020-11760
CVE-2020-11765
Thank you! Updated the initial post.
Also openjpeg v2.4.0 you bundled has a Vulnerability which is CVE-2021-29338.
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-29338 @alalek
CVE-2021-29338
This occurs when the attacker uses the command line option "-ImgDir" on a directory that contains 1048576 files.
Probably not applicable to OpenCV. We don't use OpenJPEG tools or apps. OpenCV uses decoder/encoder API subset only.
Also there are no new releases yet: https://github.com/uclouvain/openjpeg/releases
CVE-2021-29338
This occurs when the attacker uses the command line option "-ImgDir" on a directory that contains 1048576 files.Probably not applicable to OpenCV. We don't use OpenJPEG tools or apps. OpenCV uses decoder/encoder API subset only.
Also there are no new releases yet: https://github.com/uclouvain/openjpeg/releases
I think so. You'd better have an eye on it.
I have prepared PR #21327 which disables bundled-in OpenEXR in runtime with link on this issue. So lets keep OpenEXR only problems in this issue.
If you have concerns about openjpeg please open another new issue. Initial analyzing shows that OpenCV is not affected by OpenJPEG issue, see the comment above. More analyzing requires more input/details (which we don't have).
to fix openexr maybe you can update it to 3.x
New OpenEXR requires C++11, OpenCV 3.4 is C++98. So no upgrade is planned here.
OpenEXR upgrade PR for OpenCV 4.x is here: #21324 (to be discussed after NY holidays).
If you still need OpenEXR functionality and ensure that provided inputs are valid (from trusted sources) then you may turn off mentioned flag through environment variables (check internet how to use them).
Any downgrading attempt is a security hole. Not recommended in general.
Avoid posting text information through screenshots in internet. It is ridiculous.
@alalek Hi. I'm having a same problem as fschiffers, currently using opencv 4.5.5. I'd be really grateful if you tell me more specific ways how to fix this problem using environment variables. I've tried following instructions from the error message which was using export OPENCV_IO_ENABLE_OPENEXR = true or alternatively by os.environ ~ = 'true' but didn't work. Thanks
Both
OPENCV_IO_ENABLE_OPENEXR=1 python my_script.py
Or using os
before importing cv2
works
os.environ["OPENCV_IO_ENABLE_OPENEXR"]="1"
Why do you think you have the right to disable EXR without thinking how many applications will stop because of this decision.
at least give us the choice , or make another option to enable it (easily not by unclear environement flag)
Or using
os
before importingcv2
worksos.environ["OPENCV_IO_ENABLE_OPENEXR"]="1"
FYI, this environment variable can also be defined after importing cv2
, as it is only checked when opening the first EXR image for reading/writing (see source).
We recently noticed this issue as well. Evaluating OpenCV's alternatives to save/load of floating point images shows that TIFF and HDR formats work, but are not lossless (at least for floats). PFM works, but the image files are about 4-5 times as large as using OpenEXR. Therefore, we would like to keep using OpenEXR.
The first solution is to always define environment variables on each machine that should use it. This is the same as always activating OpenEXR by replacing the function isOpenEXREnabled()
inside grfmt_exr.cpp
with
static bool isOpenEXREnabled()
{
return true;
}
which avoids using environment variables but is unsafe for exactly the same reasoning.
To our understanding from the discussion here and the linked issues, the reason is not a general security risk but only an outdated OpenEXR version used inside OpenCV. Upgrading to a more recent one would be a solution, but is not intended because OpenEXR became a rather large library so far. Therefore, explicitly compiling OpenEXR and adding it as a dependency to OpenCV is the way to go.
Here, we tried to compile OpenEXR as static library using VS2022 and added it to OpenCV using the OpenEXR_DIR
and Imath_DIR
CMake options. Compiling works expect that there is an additional but unnecessary dependency to zlib_static.lib
in opencv_imgcodecs
- the linker prints an error that this is missing while manually removing it from the project file (after it was generated by CMake) works fine. Presumably, this has to be fixed inside OpenEXR's CMake scripts (similar issue)
Thereafter, compiling works except that isOpenEXREnabled()
should be extended such that the default return depends on the OpenEXR version. Is our understanding correct or are there different recommendations to solve this issue?
edit:
After analyzing the integration of OpenEXR in more detail, there is already an extended compile-time option available inside modules\imgcodecs\CMakeLists.txt
. There already is a preprocessor definition OPENCV_IMGCODECS_USE_OPENEXR
(not to be confused with the OPENCV_IO_ENABLE_OPENEXR
environment variable checked at runtime) that is enabled if an external OpenEXR version is used. However, currently there seems to be an error in the OpenEXRTargets.cmake
script that results in a link error (missing zlib_static.lib
) such that this option requires manually fixing the error in the project files.
Besides this, the preprocessor definition OPENCV_IMGCODECS_USE_OPENEXR
can alternatively be set by defining the CMake variable OPENCV_IO_FORCE_OPENEXR=True
. This results in always activating OpenEXR at runtime as long as it is not explicitly deactivated by setting the environment variable OPENCV_IO_ENABLE_OPENEXR = 0
. For the moment, this solution seems to be more convenient than explicitly activating OpenEXR whenever needed.
A couple years back in this thread, needing C++98 compatibility was cited as the reason for not upgrading to the newer OpenEXR in which all these CVEs have been fixed.
Since then, OpenEXR has acquired a core C API as well. This should allow re-inclusion.
I dont think this issue is fully resolved yet. Despite providing the environment variable,
os.environ["OPENCV_IO_ENABLE_OPENEXR"] = "1"
It is still failing, is there anything else we need to do, perhaps manually compile opencv with some flags?
Python 3.7.17 (default, Nov 24 2023, 18:52:28)
[GCC 11.4.1 20230605 (Red Hat 11.4.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
import os
os.environ["OPENCV_IO_ENABLE_OPENEXR"]="1"
import cv2
cv2.__version__
'4.8.1'
img = cv2.imread('/path/to/exr/file')
[ WARN:0@423.487] global grfmt_exr.cpp:102 initOpenEXR imgcodecs: OpenEXR codec is disabled. You can enable it via 'OPENCV_IO_ENABLE_OPENEXR' option. Refer for details and cautions here: https://github.com/opencv/opencv/issues/21326
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
cv2.error: OpenCV(4.8.1) /io/opencv/modules/imgcodecs/src/grfmt_exr.cpp:103: error: (-213:The function/feature is not implemented) imgcodecs: OpenEXR codec is disabled. You can enable it via 'OPENCV_IO_ENABLE_OPENEXR' option. Refer for details and cautions here: https://github.com/opencv/opencv/issues/21326 in function 'initOpenEXR'
Your code works fine for me in a fresh shell (Python 3.8.13, OpenCV 4.6.0, Ubuntu).
Not sure why it fails for you. Maybe there's an issue with updating the environment variable?
If you are open to recompiling OpenCV, it looks like enabling the CMake option OPENCV_IO_FORCE_OPENEXR
compiles OpenCV with the OPENCV_IMGCODECS_USE_OPENEXR
flag that should make the environment variable unnecessary. Hope this helps.
OPENCV_IMGCODECS_USE_OPENEXR flag should really be enabled by default