Repository navigation
fix uninitialised ResizerNearest indices for 1-pixel sources - #1138
Open
metsw24-max wants to merge 1 commit into
Open
metsw24-max wants to merge 1 commit into
metsw24-max wants to merge 1 commit into
Conversation
IsNearest() sends a source with a 1-pixel side to ResizerNearest whatever the method, but EstimateIndex only filled the index tables for the nearest, bilinear, bicubic and PyTorch methods, so BilinearCaffe, BilinearOpenCv, Area and AreaFast resized through stale heap offsets. On x86 the Avx2 and Avx512bw init functions could also hand such a source to the area and bicubic resizers, which read past the source row. Use the standard mapping for every non-PyTorch method and keep 1-pixel sources on a nearest resizer on every backend.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Uninitialised index tables in ResizerNearest for 1-pixel sources
ResParam::IsNearest()sends any source withsrcW == 1orsrcH == 1toResizerNearestwhatever the method, butResizerNearest::EstimateIndexonly filled_ix/_iyfor Nearest, Bilinear, Bicubic and the two PyTorch methods. BilinearCaffe, BilinearOpenCv, Area and AreaFast fell through toassert(0), so in a release build the tables keep stale heap data andResize(and the SSE4.1/AVX2 shuffle and gather paths) use it as source offsets. A 1xN or Nx1 image resized withSimdResizeMethodArea, for example throughSimd::Resize, is enough to hit it. On x86 there is a second route:Avx2::ResizerInitonly takes the nearest branch whendstX >= FandAvx512bw::ResizerInitonly whenResizerNearest::Preferable(), so a 1-pixel source can reach the area and bicubic resizers instead, which read past the source row.Fix
EstimateIndexnow gives every method except the PyTorch ones the standard mapping, and the AVX2 and AVX-512BW init functions pass a 1-pixel source on to the next init rather than to the other resizers, so all backends end up in a nearest resizer as Base, SSE4.1, NEON and SVE2 already do. I have also dropped the resizer fuzzer's Area/AreaFast skip for 1-pixel sources, which looks like it was working around this.Notes
ResizerNearest::Resizefor a 1x64 to 8x16 resize with each of the four methods. On x86 (SSE4.1/AVX2 under Rosetta) the same inputs SEGV inShuffle16x1andGather4, and with a narrow destination ASan reports heap-buffer-overflow READs in the AVX2 area resizers and the bicubic resizer. Without ASan, a releaseTestreturned pixels such as (0,0,78,1) that are not in the source.ResizerAutoTestnow compares BilinearCaffe, BilinearOpenCv, Bicubic, Area and AreaFast against Nearest for 1-pixel sources on each backend. It segfaults before the fix and passes after.Test -m=apasses with GCC 13 on aarch64 (NEON) and x86_64 (SSE4.1/AVX2 under Rosetta), and the resizer group also passes in a Debug build. The AVX-512BW change compiles but I could not run it here.