mm2 / Little-CMS

A free, open source, CMM engine. It provides fast transforms between ICC profiles.
https://www.littlecms.com
MIT License
549 stars 174 forks source link

UBSan errors found in cmsGetColorSpace: not a valid value for type 'cmsColorSpaceSignature' #409

Closed PromptFuzz closed 10 months ago

PromptFuzz commented 10 months ago

Summary

Hi, I found an UBSan error in lcms, that might by cause undefined behaviors in lcms.

it reported:

poc.cc:36:37: runtime error: load of value 4182196768, which is not a valid value for type 'cmsColorSpaceSignature'

That might due to the _cmsReadHeader, called viacmsOpenProfileFromMem()->cmsOpenProfileFromMemTHR()->_cmsReadHeader(), performed type cast to Icc -> ColorSpace without check this vaule. The similar issue might also exist in Icc -> DeviceClass, Icc -> PCS and Icc -> platform.

Poc program

#include <lcms2.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <vector>
#include <fstream>
#include <iostream>

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    if(size<=0) return 0;

    // Create a profile from the input data
    cmsHPROFILE hProfile = cmsOpenProfileFromMem(data, size);
    if (!hProfile) {
        return 1;
    }

    // Get the color space of the profile
    cmsColorSpaceSignature color_space = cmsGetColorSpace(hProfile);
    std::cout << "Color Space: " << color_space << std::endl;

    cmsCloseProfile(hProfile);
    return 0;
}

Steps to reproduce

  1. Download the poc input: crash-256553a6dfe1fb5be22ce6a3cc1618af1c3b68a6
  2. Built LCMS library with UBSan
  3. Compile the poc program: clang++ -fsanitize=fuzzer,undefined -g -O0 -I/lcms/include poc.cc -o poc.out liblcms2.a
  4. export UBSAN_OPTIONS=symbolize=1:print_stacktrace=1:halt_on_error=1
  5. Run the Poc program on the input ./poc.out crash-256553a6dfe1fb5be22ce6a3cc1618af1c3b68a6
mm2 commented 10 months ago

Thanks for reporting. Indeed, this is not an error but the expected behavior. Remember this is C99 (not C++!) In C99 enums are assumed to fit in an int (32 bits in strict C99). You are compiling the code with clang++, which is not the required language. Lcms allows to open profiles with custom color spaces, as an ICC extension, despite the number then is not listed in the enum. This is perfectly valid in C99.

PromptFuzz commented 10 months ago

Thanks for reporting. Indeed, this is not an error but the expected behavior. Remember this is C99 (not C++!) In C99 enums are assumed to fit in an int (32 bits in strict C99). You are compiling the code with clang++, which is not the required language. Lcms allows to open profiles with custom color spaces, as an ICC extension, despite the number then is not listed in the enum. This is perfectly valid in C99.

Yes, i compiled it with clang++. The UBSan reported some errors confused me.

Thanks for your reply.