tl;dr
These reproductions cover the following compiler warnings:
'const' vs unqualified
add missing switch cases
bool literal returned from 'main'
can be cast as
case value not in enumerated type
comparison of different enumeration types in switch statement
declared here
different number of parameters
different qualifiers
enumeration values not handled in switch
expanded from macro
explicitly marked deprecated
hidden overloaded virtual function
hides overloaded virtual function
instantiation of member function
is deprecated
set but not used
unqualified vs 'const'
unused variable
PatchIccMAX Refactoring
The PatchIccMAX Fork attempts to refactor code with respect to the compiler errors and warning with emphasis on accuracy and precision when working with icc color profiles.
Below are reproduction samples of Float cast overflow, Type Confusion and enum issues as seen in the compiler warnings.
UBSan repro steps for the enum example.
LLDB repro for Float cast overflow and type confusion examples.
% sysctl -a | grep vendor
machdep.cpu.vendor: GenuineIntel
% sysctl -a | grep kern.version
kern.version: Darwin Kernel Version 23.6.0: Mon Jul 29 21:13:00 PDT 2024; root:xnu-10063.141.2~1/RELEASE_X86_64
sysctl -a | grep kern.osversion
kern.osversion: 23G93
-- The C compiler is AppleClang 15.0.0.15000309
-- The CXX compiler is AppleClang 15.0.0.15000309
-- Configuring build for X86_64 architecture.
-- Info build "Debug"
-- Found LibXml2: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk/usr/lib/libxml2.tbd (found version "2.9.4")
-- Found TIFF: /usr/local/lib/libtiff.dylib (found version "4.6.0")
-- Found wxWidgets: -L/usr/local/lib;;;-framework IOKit;-framework Carbon;-framework Cocoa;-framework QuartzCore;-framework AudioToolbox;-framework System;-framework OpenGL;-lwx_osx_cocoau_core-3.2;-lwx_baseu-3.2 (found version "3.2.5")
Issue 1 - enum not a valid value for type 'icPlatformSignature'
UBSan Reproduction Steps
1. Initial Setup
Ensure the code is compiled with debugging symbols (-g) and without optimizations (-O0).
Enable Undefined Behavior Sanitizer (UBSan) to detect runtime issues.
Checkout the Base Commit:
Start by cloning the repository (if not already cloned):
git clone https://github.com/xsscx/PatchIccMAX.git
cd PatchIccMAX
Checkout the base commit:
git checkout development
Cmake Build:
Build the Project
cd Build/
cmake -DCMAKE_INSTALL_PREFIX=$HOME/.local -DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="-g -fsanitize=address,undefined -fno-omit-frame-pointer -Wall" \
-Wno-dev Cmake/
make
2. Download the Test ICC Profile
Navigate to the Testing directory within the DemoIccMAX project:
cd ../Testing
Download the ICC profile used for this Ubsan repro:
Execute the iccDumpProfile tool on the downloaded ICC profile:
iccDumpProfile icPlatformSignature-ubsan-poc.icc
4. Observe the UBSan Output
The UBSan will report runtime errors related to invalid values for icPlatformSignature:
Tools/CmdLine/IccDumpProfile/iccDumpProfile.cpp:227:69: runtime error: load of value 2543294359, which is not a valid value for type 'icPlatformSignature'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior Tools/CmdLine/IccDumpProfile/iccDumpProfile.cpp:227:69
IccProfLib/IccUtil.cpp:1845:11: runtime error: load of value 2543294359, which is not a valid value for type 'icPlatformSignature'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior IccProfLib/IccUtil.cpp:1845:11
IccProfLib/IccUtil.cpp:1865:27: runtime error: load of value 2543294359, which is not a valid value for type 'icPlatformSignature'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior IccProfLib/IccUtil.cpp:1865:27
5. LLDB Session Log
(lldb) thread info -s
thread #1: tid = 14207, 0x0000555555638be0 iccDumpProfile`__ubsan_on_report, name = 'iccDumpProfile', stop reason = Invalid enum load
{
"col": 69,
"description": "invalid-enum-load",
"filename": "Tools/CmdLine/IccDumpProfile/iccDumpProfile.cpp",
"instrumentation_class": "UndefinedBehaviorSanitizer",
"line": 227,
"memory_address": 0,
"summary": "Load of value 2543294359, which is not a valid value for type 'icPlatformSignature'",
"tid": 14207,
"trace": [
140737332772239,
140737332772415
]
}
Observations
1. Invalid icPlatformSignature Values
The UBSan report indicates that the value 2543294359 was loaded as an icPlatformSignature, but this value is outside the range of valid values for this type.
The errors occur in multiple locations within the code, suggesting a systematic issue with how these values are processed or validated.
2. Potential Impact on Program Behavior
Loading invalid values for icPlatformSignature can lead to undefined behavior, including incorrect platform identification or unexpected results in profile processing.
Issue 2 - Float Cast Overflow and Type Confusion in CIccEvalCompare::EvaluateProfile
PoC
iccRoundTrip PCC/Lab_float-D50_2deg.icc
IccProfLib/IccEval.cpp:139:28: runtime error: downcast of address 0x607000000100 which does not point to an object of type 'CIccTagLutAtoB'
0x607000000100: note: object is of type 'CIccTagMultiProcessElement'
00 00 00 00 58 8f bf 91 2f 7f 00 00 00 00 00 00 03 00 03 00 90 01 00 00 30 60 00 00 00 00 00 00
^~~~~~~~~~~~~~~~~~~~~~~
vptr for 'CIccTagMultiProcessElement'
1. Initial Setup
Ensure the code is compiled with debugging symbols (-g) and without optimizations (-O0).
Enable Undefined Behavior Sanitizer (UBSan) to detect runtime issues.
Checkout the Base Commit:
Start by cloning the repository (if not already cloned):
git clone https://github.com/xsscx/PatchIccMAX.git
cd PatchIccMAX
Checkout the base commit:
git checkout development
Cmake Build:
Build the Project
cd Build/
cmake -DCMAKE_INSTALL_PREFIX=$HOME/.local -DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="-g -fsanitize=address,undefined -fno-omit-frame-pointer -Wall" \
-Wno-dev Cmake/
make
2. Start LLDB and Set Breakpoints
Launch the iccRoundTrip program under LLDB:
lldb ./iccRoundTrip
Set a breakpoint in the main function:
(lldb) breakpoint set --file iccRoundTrip.cpp --line 151
3. Run the Program
Run the program with the ICC profile as an argument:
(lldb) run Testing/PCC/Lab_float-D50_2deg.icc
Continue execution to proceed past the initial breakpoint:
(lldb) continue
4. Float Cast Overflow Detection
The program will stop at a "Float cast overflow" issue detected by UBSan:
* thread #1, stop reason = Float cast overflow
This indicates an issue in the icDtoF function, where a NaN value caused an overflow during a floating-point to fixed-point conversion.
5. Inspect the Backtrace
Obtain the backtrace to see the sequence of function calls leading to the overflow:
(lldb) bt
The backtrace shows the flow from icDtoF to the higher-level functions, revealing the point of failure:
* frame #4: 0x0000000101b4abaf libIccProfLib2.2.dylib`icDtoF(num=NaN) at IccUtil.cpp:554:28
6. Examine the icDtoF Function
Select the frame of the icDtoF function to examine it:
(lldb) frame select 4
Inspect the local variables to confirm the NaN value:
(lldb) frame variable
The variable num is NaN, leading to an invalid fixed-point conversion.
7. Inspect Higher-Level Function
Go back to the higher-level function (CIccEvalCompare::EvaluateProfile) where the problematic call was made:
(lldb) frame select 8
Review the variables and state in this function:
(lldb) frame variable
This function handles the transformation and evaluation processes that ultimately led to the overflow.
8. Perform Inline Evaluation
Due to LLDB's issues with retaining variables, perform the following inline evaluation to directly calculate and retrieve the tag:
{
"col": 28,
"description": "float-cast-overflow",
"filename": "IccProfLib/IccUtil.cpp",
"instrumentation_class": "UndefinedBehaviorSanitizer",
"line": 554,
"memory_address": 0,
"summary": "Nan is outside the range of representable values of type 'int'",
"tid": 7419244,
"trace": [
4323576782,
4315770882,
4316595365,
4316754531,
4317500491,
4317509437,
4294987730,
140703506256708
]
}
### Observations
#### 1. Float Cast Overflow
- The `icDtoF` function was called with a `NaN` value, leading to a float-to-fixed-point conversion overflow.
#### 2. Data Integrity
- Variables such as `ndim` and `ndim1` were found to contain invalid data (`-1074795552` and `-884041631`, respectively). This indicates possible issues with data processing or passing between functions, potentially leading to undefined behavior.
#### 3. Type Mismatch Concerns
- The inline evaluation confirmed that the tag retrieved was a `CIccTagMultiProcessElement` rather than the expected `CIccTagLutAtoB` type. This mismatch can result in unsafe operations or misbehavior, particularly during downcasting or type-specific processing.
## Issue 3 - Type Confusion in `CIccMpeCalculator::Read`
### PoC
IccProfLib/IccMpeCalc.cpp:4562:37: runtime error: downcast of address 0x606000001940 which does not point to an object of type 'CIccMpeCalculator'
0x606000001940: note: object is of type 'CIccMpeXmlMatrix'
00 00 00 00 50 15 d4 01 01 00 00 00 00 00 00 00 0b 00 24 00 80 07 00 00 b0 61 00 00 b0 1c 00 00
^~~~~~~
vptr for 'CIccMpeXmlMatrix'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior IccProfLib/IccMpeCalc.cpp:4562:37 in
==22246==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6140000003f0 at pc 0x000101c0153a bp 0x7ff7bee70070 sp 0x7ff7bee70068
READ of size 4 at 0x6140000003f0 thread T0
0 0x101c01539 in CIccTagXmlSpectralViewingConditions::ToXml(std::1::basic_string<char, std::__1::char_traits, std::1::allocator>&, std::1::basic_string<char, std::__1::char_traits, std::1::allocator>) IccTagXml.cpp:2026
#1 0x101b97dc3 in CIccProfileXml::ToXmlWithBlanks(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>) IccProfileXml.cpp:281
#2 0x101b8dd05 in CIccProfileXml::ToXml(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>&) IccProfileXml.cpp:79
#3 0x10109028e in main IccToXml.cpp:38
#4 0x7ff816825344 in start+0x774 (dyld:x86_64+0xfffffffffff5c344)
pElem is treated as a CIccMultiProcessElement, but we see below it is a CIccMpeXmlMatrix.
5. Checking the Virtual Table Pointer (vptr)
(lldb) p *(void**)this
(void *) 0x0000000100d42130
The vptr indicates that this is indeed pointing to a CIccMpeCalculator.
6. Inspecting the Element Signature (elemSig)
(lldb) p elemSig
(icElemTypeSignature) icSigMatrixElemType
The element signature is icSigMatrixElemType, indicating that pElem is actually a CIccMpeXmlMatrix.
Observations
Type of this: The this pointer is correctly identified as a CIccMpeCalculator.
Type of pElem: The pElem pointer is treated as a CIccMultiProcessElement, but based on the elemSig, it is actually a CIccMpeXmlMatrix.
Type Confusion Confirmation: Since pElem is a CIccMpeXmlMatrix (as indicated by elemSig being icSigMatrixElemType), but it's being cast to a CIccMpeCalculator within the SetSubElem call, this represents a classic case of type confusion.
See also Overflow in CIccTagNamedColor2::CIccTagNamedColor2
Validation of Issues
The icPlatformSignature is an identifier used in ICC profiles to specify the platform for which the profile is intended. Invalid values can result in the profile being misinterpreted, causing incorrect rendering of colors or other undefined behavior.
The value 2543294359 does not correspond to any known valid platform signature. Platform signatures are predefined values.
The UBSan errors are present in multiple areas of the code, indicating potential systematic issues leading to type confusion.
Refactoring of different types
IccProfLib/IccUtil.cpp
Line 1950, Column 8: Comparison of different enumeration types in switch statement (icCmmSignature and icPlatformSignature).
Line 2581, Column 10: Comparison of different enumeration types in switch statement (icColorSpaceSignature and icSpectralColorSignature).
IccProfLib/IccProfile.cpp
Line 1483, Column 14: Comparison of different enumeration types in switch statement (icColorSpaceSignature and icSpectralColorSignature).
Line 2183, Column 8: Comparison of different enumeration types in switch statement (icTagSignature and icTagTypeSignature).
IccProfLib/IccTagFactory.cpp
Line 413, Column 10: Comparison of different enumeration types in switch statement (icTagTypeSignature and icTagSignature).
Identified Issues and Corresponding CWEs
Invalid Enum Value for icPlatformSignature
CWE-686: Function Call With Incorrect Argument Type
CWE-835: Loop with Unreachable Exit Condition ('Infinite Loop')
Impact: Misinterpretation of ICC profile data due to invalid values, leading to undefined behavior.
Float Cast Overflow in icDtoF Function
CWE-190: Integer Overflow or Wraparound
CWE-681: Incorrect Conversion Between Numeric Types
Impact: Overflow in floating-point operations resulting in inaccurate data handling and potential crashes.
Type Confusion in CIccMpeCalculator::Read
CWE-843: Access of Resource Using Incompatible Type ('Type Confusion')
CWE-125: Out-of-bounds Read
Impact: Accessing an object of one type as if it were another, leading to unpredictable behavior and potential security vulnerabilities.
Other MITRE Taxonomy Categories
CAPEC-160: Forced Integer Overflow
Applicable to the float cast overflow, where an intentional or accidental mismanagement of numerical values could be exploited.
CAPEC-213: Type Confusion
Reflects the issues related to accessing resources as incompatible types, which could be exploited for arbitrary code execution or other malicious activities.
Warning Summary Report
This section provides a summary of the major categories of warnings identified in the project build output. The warnings are ranked from top priority (must-fix) to lower priority (nice-to-fix), along with specific examples and recommendations for each category.
Impact: These warnings indicate that an overloaded virtual function is hiding another virtual function in the base class. This can lead to unexpected behavior, as the base class's version of the function may not be called when expected.
Examples:
'CIccTagLut8::GetPrecision' hides overloaded virtual function in IccTagLut.h:535 (69 occurrences)
'CIccMpeUnknown::GetNewApply' hides overloaded virtual function in IccTagMPE.h:255 (67 occurrences)
Recommendation: Address these issues first, as they can lead to significant logical errors in your program.
2. Switch-Case Issues with Enumeration Types ([-Wswitch], [-Wenum-compare-switch])
Impact: These warnings occur when switch statements do not account for all possible enumeration values or when there is a type mismatch. This can lead to unhandled cases, which may cause undefined behavior or crashes.
Examples:
case value not in enumerated type 'icColorSpaceSignature' in IccCmm.cpp:2177 (Multiple occurrences)
comparison of different enumeration types in switch statement in IccUtil.cpp:2585 (Multiple occurrences)
Recommendation: Ensure all possible enumeration values are handled in switch cases, and avoid comparing different enum types directly.
Should Fix
3. Unused Variables ([-Wunused-variable])
Impact: These warnings indicate variables that are declared but not used in the code. While these do not typically cause runtime errors, they can lead to unnecessary memory usage and cluttered code.
Examples:
unused variable 'dest' in IccCmm.cpp:10770 (6 occurrences)
unused variable 'pToProfile' in IccCmm.cpp:2286 (2 occurrences)
Recommendation: Remove or utilize these variables to clean up the code, which will also improve maintainability.
Impact: Deprecated functions are older functions that may be removed in future versions of the language or libraries. Continuing to use them may lead to compatibility issues.
Examples:
'sprintf' is deprecated in various files, including IccApplyProfiles/TiffImg.cpp:238 and IccDumpProfile.cpp:341 (Multiple occurrences)
Recommendation: Replace deprecated functions with their recommended alternatives.
Nice to Fix
5. Unused Functions ([-Wunused-function])
Impact: These warnings indicate functions that are defined but never called. Like unused variables, they do not cause runtime issues but contribute to code bloat.
Examples:
unused function 'compare_float' in IccProfile.cpp:1333
unused function 'icGetParamFloatNum' in IccEncoding.cpp:125
Recommendation: Review these functions and remove them if they are truly unnecessary.
6. Implicit Conversions ([-Wnull-conversion])
Impact: Implicit conversions, particularly involving NULL to bool, can lead to subtle bugs and undefined behavior.
Examples:
implicit conversion of NULL constant to 'bool' in IccProfileXml.cpp:855
Recommendation: Refactor the code to make the conversion explicit or avoid it altogether.
Minor Issues
7. Miscellaneous Minor Warnings
Impact: These are generally non-critical issues like variables set but not used or enum comparison outside switch statements. They typically don't cause immediate issues but can contribute to long-term technical debt.
Examples:
variable 'pad' set but not used in wxProfileDump.cpp:777
10 enumeration values not handled in switch in IccMpeCalc.cpp:1808
Recommendation: Fix these issues as time permits, focusing on overall code quality.
TODO
First: Refactor the overloaded virtual functions and switch-case issues, as these can directly impact program behavior and stability.
Second: Address the unused variables and deprecated functions to improve code quality and future-proofing.
Long-Term: Clean up the unused functions, implicit conversions, and other minor warnings as part of ongoing code maintenance.
Reporter: David Hoyt @xsscx
Date: August 31, 2024
tl;dr These reproductions cover the following compiler warnings:
PatchIccMAX Refactoring
The PatchIccMAX Fork attempts to refactor code with respect to the compiler errors and warning with emphasis on accuracy and precision when working with icc color profiles.
Below are reproduction samples of Float cast overflow, Type Confusion and enum issues as seen in the compiler warnings.
Reproduction Host
macOS 14.6.1 (23G93) x86_64
Required
Platform
Issue 1 - enum not a valid value for type 'icPlatformSignature'
UBSan Reproduction Steps
1. Initial Setup
-g
) and without optimizations (-O0
).Enable Undefined Behavior Sanitizer (UBSan) to detect runtime issues.
Checkout the Base Commit:
Cmake Build:
2. Download the Test ICC Profile
Testing
directory within the DemoIccMAX project:3. PoC
iccDumpProfile
tool on the downloaded ICC profile:4. Observe the UBSan Output
icPlatformSignature
:5. LLDB Session Log
Observations
1. Invalid
icPlatformSignature
Values2543294359
was loaded as anicPlatformSignature
, but this value is outside the range of valid values for this type.2. Potential Impact on Program Behavior
icPlatformSignature
can lead to undefined behavior, including incorrect platform identification or unexpected results in profile processing.Issue 2 - Float Cast Overflow and Type Confusion in
CIccEvalCompare::EvaluateProfile
PoC
1. Initial Setup
-g
) and without optimizations (-O0
).Enable Undefined Behavior Sanitizer (UBSan) to detect runtime issues.
Checkout the Base Commit:
Cmake Build:
2. Start LLDB and Set Breakpoints
iccRoundTrip
program under LLDB:main
function:3. Run the Program
4. Float Cast Overflow Detection
icDtoF
function, where aNaN
value caused an overflow during a floating-point to fixed-point conversion.5. Inspect the Backtrace
icDtoF
to the higher-level functions, revealing the point of failure:6. Examine the
icDtoF
FunctionicDtoF
function to examine it:NaN
value:num
isNaN
, leading to an invalid fixed-point conversion.7. Inspect Higher-Level Function
CIccEvalCompare::EvaluateProfile
) where the problematic call was made:8. Perform Inline Evaluation
Due to LLDB's issues with retaining variables, perform the following inline evaluation to directly calculate and retrieve the tag:
The result should be a pointer to a
CIccTagMultiProcessElement
, confirming the tag's type:Further inspect the tag to confirm its contents:
9. Reproduction Log
thread #1, queue = 'com.apple.main-thread', stop reason = Float cast overflow
__ubsan_on_report frame #1: 0x00000001021b7c9e libclang_rt.asan_osx_dynamic.dylib
ubsan::Diag::~Diag() + 206 frame #2: 0x00000001021bb192 libclang_rt.asan_osx_dynamic.dylibhandleFloatCastOverflow(void*, unsigned long, __ubsan::ReportOptions) + 466 frame #3: 0x00000001021bafb0 libclang_rt.asan_osx_dynamic.dylib
ubsan_handle_float_cast_overflow + 48 frame #4: 0x0000000101b48bcf libIccProfLib2.2.dylibicDtoF(num=NaN) at IccUtil.cpp:554:28 frame #5: 0x00000001013d7003 libIccProfLib2.2.dylib
CIccXform::Begin(this=0x000060e000003d80) at IccCmm.cpp:1528:16 frame #6: 0x00000001014a04a6 libIccProfLib2.2.dylibCIccXformMpe::Begin(this=0x000060e000003d80) at IccCmm.cpp:7228:23 frame #7: 0x00000001014c7264 libIccProfLib2.2.dylib
CIccCmm::Begin(this=0x00007ff7bfefe760, bAllocApplyCmm=true, bUsePCSConversions=false) at IccCmm.cpp:8409:18 frame #8: 0x000000010157d44c libIccProfLib2.2.dylibCIccEvalCompare::EvaluateProfile(this=0x00007ff7bfeff020, pProfile=0x000060e000003bc0, nGran='\0', nIntent=icRelativeColorimetric, nInterp=icInterpLinear, buseMpeTags=false) at IccEval.cpp:111:20 frame #9: 0x000000010157f73e libIccProfLib2.2.dylib
CIccEvalCompare::EvaluateProfile(this=0x00007ff7bfeff020, szProfilePath="PCC/Lab_float-D50_2deg.icc", nGrid='\0', nIntent=icRelativeColorimetric, nInterp=icInterpLinear, buseMpeTags=false) at IccEval.cpp:216:24 frame #10: 0x0000000100004fd3 iccRoundTripmain(argc=2, argv=0x00007ff7bfeff898) at iccRoundTrip.cpp:170:27 frame #11: 0x00007ff816825345 dyld
start + 1909(lldb) fr se 4 frame #4: 0x0000000101b48bcf libIccProfLib2.2.dylib`icDtoF(num=NaN) at IccUtil.cpp:554:28 551 else if (num>32767.0) 552 num = 32767.0; 553 -> 554 rv = (icS15Fixed16Number)icRoundOffset((double)num*65536.0); 555 556 return rv; 557 }
(lldb) fr va (icFloatNumber) num = NaN (icS15Fixed16Number) rv = 15520
(lldb) thr inf -s thread #1: tid = 0x71356c, 0x00000001021bcd70 libclang_rt.asan_osx_dynamic.dylib`__ubsan_on_report, queue = 'com.apple.main-thread', stop reason = Float cast overflow
{ "col": 28, "description": "float-cast-overflow", "filename": "IccProfLib/IccUtil.cpp", "instrumentation_class": "UndefinedBehaviorSanitizer", "line": 554, "memory_address": 0, "summary": "Nan is outside the range of representable values of type 'int'", "tid": 7419244, "trace": [ 4323576782, 4315770882, 4316595365, 4316754531, 4317500491, 4317509437, 4294987730, 140703506256708 ] }
cd Testing/ wget https://github.com/xsscx/PatchIccMAX/raw/development/contrib/UnitTest/icSigMatrixElemType-Read-poc.icc iccToXml icSigMatrixElemType-Read-poc.icc icSigMatrixElemType-Read-poc.xml
IccProfLib/IccMpeCalc.cpp:4562:37: runtime error: downcast of address 0x606000001940 which does not point to an object of type 'CIccMpeCalculator' 0x606000001940: note: object is of type 'CIccMpeXmlMatrix' 00 00 00 00 50 15 d4 01 01 00 00 00 00 00 00 00 0b 00 24 00 80 07 00 00 b0 61 00 00 b0 1c 00 00 ^
~~~~~~ vptr for 'CIccMpeXmlMatrix' SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior IccProfLib/IccMpeCalc.cpp:4562:37 in==22246==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6140000003f0 at pc 0x000101c0153a bp 0x7ff7bee70070 sp 0x7ff7bee70068 READ of size 4 at 0x6140000003f0 thread T0
0 0x101c01539 in CIccTagXmlSpectralViewingConditions::ToXml(std::1::basic_string<char, std::__1::char_traits, std:: 1::allocator>&, std::1::basic_string<char, std::__1::char_traits, std:: 1::allocator>) IccTagXml.cpp:2026
(lldb) bt
__ubsan_on_report frame #1: 0x0000000101047c9e libclang_rt.asan_osx_dynamic.dylib
ubsan::Diag::~Diag() + 206 frame #2: 0x000000010104d568 libclang_rt.asan_osx_dynamic.dylibHandleDynamicTypeCacheMiss(__ubsan::DynamicTypeCacheMissData*, unsigned long, unsigned long, __ubsan::ReportOptions) + 440 frame #3: 0x000000010104d3a0 libclang_rt.asan_osx_dynamic.dylib
ubsan_handle_dynamic_type_cache_miss + 48 frame #4: 0x0000000101fce4ef libIccProfLib2.2.dylibCIccMpeCalculator::Read(this=0x0000612000000340, size=3868, pIO=0x00007ff7bfeff000) at IccMpeCalc.cpp:4562:37 frame #5: 0x00000001023f0cb1 libIccProfLib2.2.dylib
CIccTagMultiProcessElement::Read(this=0x00006070000001e0, size=3892, pIO=0x00007ff7bfeff000) at IccTagMPE.cpp:1059:21 frame #6: 0x0000000100c7191f libIccXML2.2.dylibCIccTag::Read(this=0x00006070000001e0, size=3892, pIO=0x00007ff7bfeff000, pProfile=0x00007ff7bfefef20) at IccTagBasic.h:197:87 frame #7: 0x0000000102092de4 libIccProfLib2.2.dylib
CIccProfile::LoadTag(this=0x00007ff7bfefef20, pTagEntry=0x0000604000000d20, pIO=0x00007ff7bfeff000, bReadAll=false) at IccProfile.cpp:1214:14 frame #8: 0x00000001020a3738 libIccProfLib2.2.dylibCIccProfile::Read(this=0x00007ff7bfefef20, pIO=0x00007ff7bfeff000, bUseSubProfile=false) at IccProfile.cpp:774:10 frame #9: 0x000000010000409a iccToXml
main(argc=3, argv=0x00007ff7bfeff4a8) at IccToXml.cpp:30:16 frame #10: 0x00007ff816825345 dyldstart + 1909 (lldb) fr se 4 frame #4: 0x0000000101fce4ef libIccProfLib2.2.dylib
CIccMpeCalculator::Read(this=0x0000612000000340, size=3868, pIO=0x00007ff7bfeff000) at IccMpeCalc.cpp:4562:37 4559 free(posvals); 4560 return false; 4561 } -> 4562 SetSubElem((icUInt16Number)n, (CIccMpeCalculator)pElem); 4563 pos++; 4564 } 4565 } (lldb) fr va (CIccMpeXmlCalculator ) this = 0x0000612000000340 (icUInt32Number) size = 3868 (CIccFileIO ) pIO = 0x00007ff7bfeff000 (icElemTypeSignature) sig = icSigCalculatorElemType (icUInt32Number) startPos = 356 (icUInt32Number) headerSize = 20 (icUInt16Number) nInputChannels = 11 (icUInt16Number) nOutputChannels = 36 (icUInt32Number) nSubElem = 2 (icUInt32Number) nPos = 3 (icPositionNumber ) pos = 0x00006030000042a8 (icPositionNumber ) posvals = 0x00006030000042a0 (icUInt32Number) n = 0 (icElemTypeSignature) elemSig = icSigMatrixElemType (CIccMpeXmlMatrix ) pElem = 0x00006060000011c0 (lldb) p *(void*)this (void ) 0x0000000100d42130 (lldb) p elemSig (icElemTypeSignature) icSigMatrixElemType (lldb) p *pElem (CIccMultiProcessElement) (m_nReserved = 0, m_nInputChannels = 11, m_nOutputChannels = 36)1. Initial Setup
-g
) and without optimizations (-O0
).Enable Undefined Behavior Sanitizer (UBSan) to detect runtime issues.
Checkout the Base Commit:
Cmake Build:
LLDB Debugging Session and Analysis
2. Breakpoint Setup
A breakpoint set at line 4562 in
IccMpeCalc.cpp
, which is where the type confusion occurs:Upon running the program (
iccToXml
), the process stops at the specified breakpoint, confirming that the program reached the problematic code segment.3. Inspecting
this
Pointerthis
pointer is confirmed to be of typeCIccMpeCalculator
.4. Inspecting
pElem
pElem
is treated as aCIccMultiProcessElement
, but we see below it is aCIccMpeXmlMatrix
.5. Checking the Virtual Table Pointer (
vptr
)vptr
indicates thatthis
is indeed pointing to aCIccMpeCalculator
.6. Inspecting the Element Signature (
elemSig
)icSigMatrixElemType
, indicating thatpElem
is actually aCIccMpeXmlMatrix
.Observations
this
: Thethis
pointer is correctly identified as aCIccMpeCalculator
.pElem
: ThepElem
pointer is treated as aCIccMultiProcessElement
, but based on theelemSig
, it is actually aCIccMpeXmlMatrix
.pElem
is aCIccMpeXmlMatrix
(as indicated byelemSig
beingicSigMatrixElemType
), but it's being cast to aCIccMpeCalculator
within theSetSubElem
call, this represents a classic case of type confusion.See also Overflow in
CIccTagNamedColor2::CIccTagNamedColor2
Validation of Issues
The
icPlatformSignature
is an identifier used in ICC profiles to specify the platform for which the profile is intended. Invalid values can result in the profile being misinterpreted, causing incorrect rendering of colors or other undefined behavior.The value
2543294359
does not correspond to any known valid platform signature. Platform signatures are predefined values.The UBSan errors are present in multiple areas of the code, indicating potential systematic issues leading to type confusion.
Refactoring of different types
IccProfLib/IccUtil.cpp
icCmmSignature
andicPlatformSignature
).icColorSpaceSignature
andicSpectralColorSignature
).IccProfLib/IccProfile.cpp
icColorSpaceSignature
andicSpectralColorSignature
).icTagSignature
andicTagTypeSignature
).IccProfLib/IccTagFactory.cpp
icTagTypeSignature
andicTagSignature
).Identified Issues and Corresponding CWEs
Invalid Enum Value for
icPlatformSignature
Float Cast Overflow in
icDtoF
FunctionType Confusion in
CIccMpeCalculator::Read
Other MITRE Taxonomy Categories
CAPEC-160: Forced Integer Overflow
Applicable to the float cast overflow, where an intentional or accidental mismanagement of numerical values could be exploited.
CAPEC-213: Type Confusion
Reflects the issues related to accessing resources as incompatible types, which could be exploited for arbitrary code execution or other malicious activities.
Warning Summary Report
This section provides a summary of the major categories of warnings identified in the project build output. The warnings are ranked from top priority (must-fix) to lower priority (nice-to-fix), along with specific examples and recommendations for each category.
Must Fix
1. Overloaded Virtual Functions (
[-Woverloaded-virtual]
)'CIccTagLut8::GetPrecision' hides overloaded virtual function
inIccTagLut.h:535
(69 occurrences)'CIccMpeUnknown::GetNewApply' hides overloaded virtual function
inIccTagMPE.h:255
(67 occurrences)2. Switch-Case Issues with Enumeration Types (
[-Wswitch]
,[-Wenum-compare-switch]
)case value not in enumerated type 'icColorSpaceSignature'
inIccCmm.cpp:2177
(Multiple occurrences)comparison of different enumeration types in switch statement
inIccUtil.cpp:2585
(Multiple occurrences)Should Fix
3. Unused Variables (
[-Wunused-variable]
)unused variable 'dest'
inIccCmm.cpp:10770
(6 occurrences)unused variable 'pToProfile'
inIccCmm.cpp:2286
(2 occurrences)4. Deprecated Functions (
[-Wdeprecated-declarations]
)'sprintf' is deprecated
in various files, includingIccApplyProfiles/TiffImg.cpp:238
andIccDumpProfile.cpp:341
(Multiple occurrences)Nice to Fix
5. Unused Functions (
[-Wunused-function]
)unused function 'compare_float'
inIccProfile.cpp:1333
unused function 'icGetParamFloatNum'
inIccEncoding.cpp:125
6. Implicit Conversions (
[-Wnull-conversion]
)NULL
tobool
, can lead to subtle bugs and undefined behavior.implicit conversion of NULL constant to 'bool'
inIccProfileXml.cpp:855
Minor Issues
7. Miscellaneous Minor Warnings
variable 'pad' set but not used
inwxProfileDump.cpp:777
10 enumeration values not handled in switch
inIccMpeCalc.cpp:1808
TODO