InternationalColorConsortium / DemoIccMAX

Demonstration Implementation for iccMAX color profiles
Other
119 stars 37 forks source link

Reproduction for Float cast overflow, Type Confusion, enum NaN #93

Closed xsscx closed 1 month ago

xsscx commented 1 month ago

Reporter: David Hoyt @xsscx
Date: August 31, 2024

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.

Reproduction Host

macOS 14.6.1 (23G93) x86_64

Required

sudo nvram boot-args="amfi_get_out_of_my_way=1"
sudo csrutil disable

Platform

% 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

2. Download the Test ICC Profile

3. PoC

4. Observe the UBSan Output

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

2. Potential Impact on Program Behavior

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

2. Start LLDB and Set Breakpoints

3. Run the Program

4. Float Cast Overflow Detection

5. Inspect the Backtrace

6. Examine the icDtoF Function

7. Inspect Higher-Level Function

8. Perform Inline Evaluation

(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 ] }


### 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

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

#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)

(lldb) bt

1. Initial Setup

LLDB Debugging Session and Analysis

2. Breakpoint Setup

3. Inspecting this Pointer

(lldb) p *this
(CIccMpeCalculator) {
  CIccMultiProcessElement = (m_nReserved = 0, m_nInputChannels = 11, m_nOutputChannels = 36)
  m_nTempChannels = 0
  m_bNeedTempReset = true
  m_nSubElem = 2
  m_SubElem = 0x0000602000000250
  m_calcFunc = nullptr
  m_pCmmEnvVarLookup = nullptr
}

4. Inspecting pElem

(lldb) p *pElem
(CIccMultiProcessElement)  (m_nReserved = 0, m_nInputChannels = 11, m_nOutputChannels = 36)

5. Checking the Virtual Table Pointer (vptr)

(lldb) p *(void**)this
(void *) 0x0000000100d42130

6. Inspecting the Element Signature (elemSig)

(lldb) p elemSig
(icElemTypeSignature) icSigMatrixElemType

Observations

  1. Type of this: The this pointer is correctly identified as a CIccMpeCalculator.
  2. Type of pElem: The pElem pointer is treated as a CIccMultiProcessElement, but based on the elemSig, it is actually a CIccMpeXmlMatrix.
  3. 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

Refactoring of different types

  1. 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).
  2. 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).
  3. 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

Float Cast Overflow in icDtoF Function

Type Confusion in CIccMpeCalculator::Read

Other MITRE Taxonomy Categories

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])

2. Switch-Case Issues with Enumeration Types ([-Wswitch], [-Wenum-compare-switch])

Should Fix

3. Unused Variables ([-Wunused-variable])

4. Deprecated Functions ([-Wdeprecated-declarations])

Nice to Fix

5. Unused Functions ([-Wunused-function])

6. Implicit Conversions ([-Wnull-conversion])

Minor Issues

7. Miscellaneous Minor Warnings

TODO

xsscx commented 1 month ago

The Branch for this Development work is at PatchIccMAX