Security: Fix shift-related undefined behaviour in jpc_undo_roi for malformed ROI parameters #408
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.
Reproduce
Build jasper with UBSan enabled, for example:
cmake -S ./jasper -B build-ubsan -DCMAKE_BUILD_TYPE=RelWithDebInfo
-DCMAKE_C_COMPILER=clang
-DCMAKE_C_FLAGS="-fsanitize=undefined -fno-omit-frame-pointer"
-DCMAKE_CXX_FLAGS="-fsanitize=undefined -fno-omit-frame-pointer"
cmake --build build-ubsan -j
Run jasper on the malformed JPEG 2000 codestream (attached as crash.bin.zip):
crash.bin.zip
build-ubsan/src/app/jasper
--input crash.bin
--output /dev/null
--input-format jpc
--output-format jpc
UBSan reports undefined behaviour in jpc_undo_roi():
/data/jasper/src/libjasper/jpc/jpc_dec.c:2088:13: runtime error: shift exponent 32 is too large for 32-bit type 'int'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /data/jasper/src/libjasper/jpc/jpc_dec.c:2088:13
/data/jasper/src/libjasper/jpc/jpc_dec.c:2106:9: runtime error: shift exponent -32 is negative
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /data/jasper/src/libjasper/jpc/jpc_dec.c:2106:9
/data/jasper/src/libjasper/jpc/jpc_dec.c:2107:40: runtime error: shift exponent 4294967295 is too large for 64-bit type 'uint_fast32_t' (aka 'unsigned long')
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /data/jasper/src/libjasper/jpc/jpc_dec.c:2107:40
Fix
warning: ignoring unknown marker segment (0xff50)
warning: limiting ROI shift from 32 to 0 (bitstream is probably corrupt)
warning: forcing negative background shift to zero (bitstream is probably corrupt)
warning: limiting ROI shift from 32 to 0 (bitstream is probably corrupt)
warning: forcing negative background shift to zero (bitstream is probably corrupt)
warning: limiting ROI shift from 32 to 0 (bitstream is probably corrupt)
warning: forcing negative background shift to zero (bitstream is probably corrupt)
warning: limiting ROI shift from 32 to 0 (bitstream is probably corrupt)
warning: forcing negative background shift to zero (bitstream is probably corrupt)
warning: limiting ROI shift from 32 to 0 (bitstream is probably corrupt)
warning: forcing negative background shift to zero (bitstream is probably corrupt)
warning: limiting ROI shift from 32 to 0 (bitstream is probably corrupt)
warning: forcing negative background shift to zero (bitstream is probably corrupt)
warning: limiting ROI shift from 32 to 0 (bitstream is probably corrupt)
warning: forcing negative background shift to zero (bitstream is probably corrupt)
build-ubsan/src/app/jasper
--input ./is_codestream.jp2
--output /dev/null
--input-format jpc
--output-format jp2
output:
warning: skipping unknown tag type
warning: skipping unknown tag type
warning: skipping unknown tag type
test file: https://github.com/openpreserve/jpylyzer-test-files/blob/master/files/is_codestream.jp2