Fix out of memory read when using NaN.#21111
Conversation
|
I changed to keeping NaNs as NaNs as some color conversions functions keep NaNs (e.g. RGB2BGR). |
alalek
left a comment
There was a problem hiding this comment.
Please add simple test for mentioned problem.
Modified code works in non-optimized mode only.
90+% of applications uses SIMD version of the code which should be checked too.
modules/imgproc/src/color_lab.cpp
Outdated
|
|
||
| for(; i < n; i += 3, src += scn) | ||
| { | ||
| if (cvIsNaN(src[bIdx]) || cvIsNaN(src[1]) || cvIsNaN(src[bIdx^2])) { |
There was a problem hiding this comment.
Such explicit extra checks introduce performance degradation which we want to avoid.
Why is previous conversation closed?
There was a problem hiding this comment.
Sorry I closed because my patch was fairly different.
I reduced the NaN comparison to the bare minimum and added a test.
There was a problem hiding this comment.
What is about: cvIsNaN(src[0] + src[1] + src[2])?
There was a problem hiding this comment.
Done.
That results in less operations for SIMD.
0b7e352 to
c014e5c
Compare
|
I renamed the test and added partial NaNs to it. |
If a NaN is sent to RGB2Lab_f::operator(), trilinearInterpolate can be called with arguments that are +-std::numeric_limits<int> which triggers out of memory reads.
|
I think, it will be much faster to check the index when accessing LUT. If the LUT size is power-of-two, we can just do |
|
That was indeed what this patch was doing originally: capping the coordinates to fit in the LUT table (it is not a power of two so there will still be a clamping to do). opencv/modules/imgproc/src/color_lab.cpp Line 981 in 97c6ec6 We just have to decide on something so that results stay the same independently of the platform (something in [0,1]) as casting a NaN to an int is undefined behavior. Then again, if we do so, we lose the semantic: pixel with NaNs in means pixel with NaNs out (which is fine because it is to save on performance and we just have to document it). |
|
I will update |
- no NaN propagation guarantee
This is to prevent more NaN to int conversions like in opencv#21111.
This is to prevent more NaN to int conversions like in opencv#21111.
If a NaN is sent to RGB2Lab_f::operator() and is read at
opencv/modules/imgproc/src/color_lab.cpp
Line 2005 in 97c6ec6
opencv/modules/imgproc/src/color_lab.cpp
Line 2009 in 97c6ec6
When then calling trilinearInterpolate, the index is definitely outside the LUT at
opencv/modules/imgproc/src/color_lab.cpp
Line 1333 in 97c6ec6
Yes, normal users should not use NaN, but malicious users will.
Here are the other possible solutions:
Please advise.
Pull Request Readiness Checklist