Fuzzing Coverage Expansion of Little-CMS (#11165)

Hi! This pull request expands fuzzing coverage of Little-CMS by adding 7
new fuzz targets and modifying 1 existing fuzz target
(cms_transform_extended_fuzzer).
Docker file includes 7 new ICC profiles derived from Little-CMS/testbed
and build.sh is modified and added with new fuzz targets and their seed
corpuses.
This commit is contained in:
viktoriia-lsg 2023-11-06 16:06:24 +02:00 committed by GitHub
parent 3414ed74fb
commit 3464f489f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 499 additions and 5 deletions

View File

@ -24,6 +24,14 @@ RUN mkdir $SRC/seeds && \
cp $SRC/lcms/testbed/test1.icc . && \
cp $SRC/lcms/testbed/crayons.icc . && \
cp $SRC/lcms/testbed/ibm-t61.icc . && \
#add more seeds from the testbed dir
cp $SRC/lcms/testbed/bad_mpe.icc . && \
cp $SRC/lcms/testbed/new.icc . && \
cp $SRC/lcms/testbed/test2.icc . && \
cp $SRC/lcms/testbed/test3.icc . && \
cp $SRC/lcms/testbed/test4.icc . && \
cp $SRC/lcms/testbed/test5.icc . && \
cp $SRC/lcms/testbed/TestCLT.icc . && \
zip -rj $SRC/seed_corpus.zip $SRC/seeds/*
WORKDIR lcms

View File

@ -26,7 +26,16 @@ FUZZERS="cmsIT8_load_fuzzer \
cms_transform_all_fuzzer \
cms_profile_fuzzer \
cms_universal_transform_fuzzer \
cms_transform_extended_fuzzer"
cms_transform_extended_fuzzer \
cms_md5_fuzzer \
cms_dict_fuzzer \
cms_postscript_fuzzer \
cms_cie_cam02_fuzzer \
cms_gdb_fuzzer \
cms_cgats_fuzzer \
cms_virtual_profile_fuzzer \
cms_devicelink_fuzzer"
for F in $FUZZERS; do
$CC $CFLAGS -c -Iinclude \
@ -36,11 +45,21 @@ for F in $FUZZERS; do
$LIB_FUZZING_ENGINE src/.libs/liblcms2.a
done
cp $SRC/icc.dict $SRC/*.options $OUT/
cp $SRC/*.dict $SRC/*.options $OUT/
cp $SRC/icc.dict $OUT/cms_transform_all_fuzzer.dict
cp $SRC/icc.dict $OUT/cms_transform_extended_fuzzer.dict
cp $SRC/icc.dict $OUT/cms_universal_transform_fuzzer.dict
cp $SRC/icc.dict $OUT/cms_profile_fuzzer.dict
cp $SRC/seed_corpus.zip $OUT/cms_transform_fuzzer_seed_corpus.zip
cp $SRC/icc.dict $OUT/cms_postscript_fuzzer.dict
cp $SRC/icc.dict $OUT/cms_virtual_profile_fuzzer.dict
cp $SRC/icc.dict $OUT/cms_md5_fuzzer.dict
cp $SRC/seed_corpus.zip $OUT/cms_postscript_fuzzer_seed_corpus.zip
cp $SRC/seed_corpus.zip $OUT/cms_profile_fuzzer_seed_corpus.zip
cp $SRC/seed_corpus.zip $OUT/cms_universal_transform_fuzzer_seed_corpus.zip
cp $SRC/seed_corpus.zip $OUT/cms_transform_all_fuzzer_seed_corpus.zip
cp $SRC/seed_corpus.zip $OUT/cms_transform_extended_fuzzer_seed_corpus.zip
cp $SRC/seed_corpus.zip $OUT/cms_transform_fuzzer_seed_corpus.zip
cp $SRC/seed_corpus.zip $OUT/cms_virtual_profile_fuzzer_seed_corpus.zip
cp $SRC/seed_corpus.zip $OUT/cmsIT8_load_fuzzer_seed_corpus.zip
cp $SRC/seed_corpus.zip $OUT/cms_md5_fuzzer_seed_corpus.zip
cp $SRC/seed_corpus.zip $OUT/cms_overwrite_transform_fuzzer_seed_corpus.zip

View File

@ -0,0 +1,76 @@
/* Copyright 2023 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <stdint.h>
#include "lcms2.h"
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size < 8){
return 0;
}
cmsContext context = cmsCreateContext(NULL, (void *)data);
uint32_t Row = *((uint32_t *)data);
uint32_t Col = *((uint32_t *)data+1);
/* Write */
cmsHANDLE it8;
cmsInt32Number i;
it8 = cmsIT8Alloc(0);
if (it8 == NULL) return 0;
cmsIT8SetSheetType(it8, "LCMS/TESTING");
cmsIT8SetPropertyStr(it8, "ORIGINATOR", "1 2 3 4");
cmsIT8SetPropertyUncooked(it8, "DESCRIPTOR", "1234");
cmsIT8SetPropertyStr(it8, "MANUFACTURER", "3");
cmsIT8SetPropertyDbl(it8, "CREATED", data[0] / 255.0);
cmsIT8SetPropertyDbl(it8, "SERIAL", data[1] / 255.0);
cmsIT8SetPropertyHex(it8, "MATERIAL", 0x123);
cmsIT8SetPropertyDbl(it8, "NUMBER_OF_SETS", 10);
cmsIT8SetPropertyDbl(it8, "NUMBER_OF_FIELDS", Row);
cmsIT8SetDataFormat(it8, 0, "SAMPLE_ID");
cmsIT8SetDataFormat(it8, 1, "RGB_R");
cmsIT8SetDataFormat(it8, 2, "RGB_G");
cmsIT8SetDataFormat(it8, 3, "RGB_B");
for (i=0; i < 10; i++) {
char Patch[20];
sprintf(Patch, "P%d", i);
cmsIT8SetDataRowCol(it8, i, 0, Patch);
cmsIT8SetDataRowColDbl(it8, i, 1, i);
cmsIT8SetDataRowColDbl(it8, i, 2, i);
cmsIT8SetDataRowColDbl(it8, i, 3, i);
}
cmsIT8SaveToFile(it8, "TEST.IT8");
cmsIT8Free(it8);
it8 = cmsIT8LoadFromFile(0, "TEST.IT8");
if (it8 == NULL) return 0;
/* Read */
cmsIT8GetDataRowColDbl(it8,Row,Col);
cmsIT8GetPropertyDbl(it8, "DESCRIPTOR");
cmsIT8GetDataDbl(it8, "P3", "RGB_G");
cmsIT8Free(it8);
return 1;
}

View File

@ -0,0 +1,51 @@
/* Copyright 2023 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <stdint.h>
#include "lcms2.h"
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size < sizeof(cmsViewingConditions)) {
return 0;
}
// Define and initialize the viewing conditions structure
cmsViewingConditions viewingConditions;
viewingConditions.whitePoint.X = data[0]/ 255.0;
viewingConditions.whitePoint.Y = data[1]/ 255.0;
viewingConditions.whitePoint.Z = data[2]/ 255.0;
viewingConditions.Yb = data[3] / 255.0;
viewingConditions.La = data[4]/ 255.0;
viewingConditions.surround = data[5] % 4 + 1; //from 1 to 4
viewingConditions.D_value = data[6] / 255.0;
cmsContext context = cmsCreateContext(NULL, NULL);
cmsHANDLE hModel = cmsCIECAM02Init(context, &viewingConditions);
if (hModel) {
// Perform forward and reverse CAM02 transformations with appropriate input data
cmsCIEXYZ inputXYZ;
inputXYZ.X = data[0]/ 255.0; // Random value between 0 and 1
inputXYZ.Y = data[1] / 255.0;
inputXYZ.Z = data[2] / 255.0;
cmsJCh outputJCh;
cmsCIEXYZ outputXYZ;
cmsCIECAM02Forward(hModel, &inputXYZ, &outputJCh);
cmsCIECAM02Reverse(hModel, &outputJCh, &outputXYZ);
cmsCIECAM02Done(hModel);
}
cmsDeleteContext(context);
return 0;
}

View File

@ -0,0 +1,32 @@
/* Copyright 2023 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "lcms2.h"
#include <stdint.h>
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size < 4) {
return 0;
}
// cmsCreateInkLimitingDeviceLink
cmsFloat64Number limit = *((const uint32_t *)data) % 401;
cmsHPROFILE limitingDeviceLinkProfile =
cmsCreateInkLimitingDeviceLink(cmsSigCmykData, limit);
if (limitingDeviceLinkProfile) {
cmsCloseProfile(limitingDeviceLinkProfile);
}
return 0;
}

View File

@ -0,0 +1,95 @@
/* Copyright 2023 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <stdint.h>
#include <stdlib.h>
#include "lcms2.h"
wchar_t* generateWideString(const char* characters, const uint8_t *data){
if (!characters){
return NULL;
}
char stringToWide[10];
for (int i = 0; i < 9; i++){
stringToWide[i] = characters[data[i] % 95];
}
stringToWide[9] = '\0';
int requiredSize = mbstowcs(NULL, stringToWide, 0);
wchar_t* wideString = (wchar_t *)malloc((requiredSize + 1) * sizeof(wchar_t));
mbstowcs(wideString, stringToWide, requiredSize + 1);
return wideString;
}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size < 27){
return 0;
}
cmsContext context = cmsCreateContext(NULL, (void *)data);
if (!context) {
return 0;
}
// Create a Dictionary handle
cmsHANDLE hDict = cmsDictAlloc(context);
if (!hDict) {
return 0;
}
cmsMLU *mlu = cmsMLUalloc(hDict, 0);
if (!mlu) {
return 0;
}
char* characters = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
wchar_t* wideString = generateWideString(characters, data);
cmsMLUsetWide(mlu, "en", "US", wideString);
free(wideString);
char ObtainedLanguage[3], ObtainedCountry[3];
ObtainedLanguage[0] = characters[*(data+1) % 95];
ObtainedLanguage[1] = characters[*(data+2) % 95];
ObtainedLanguage[2] = characters[*(data) % 95];
ObtainedCountry[0] = characters[*(data+2) % 95];
ObtainedCountry[1] = characters[*data % 95];
ObtainedCountry[2] = characters[*(data+1) % 95];
cmsMLUgetTranslation(mlu, "en", "US",ObtainedLanguage,ObtainedCountry);
cmsMLUtranslationsCount(mlu);
cmsMLUtranslationsCodes(mlu, *((uint32_t *)data), ObtainedLanguage, ObtainedCountry);
cmsMLU* displayName = mlu;
cmsMLU* displayValue = mlu;
//cmsDictAddEntry
wchar_t* name = generateWideString(characters, data + 9);
wchar_t* value = generateWideString(characters, data + 18);
cmsDictAddEntry(hDict, name, value, displayName, displayValue);
free(name);
free(value);
//cmsDictDup
cmsHANDLE ResultDictDup = cmsDictDup(hDict);
if (ResultDictDup) {
cmsDictFree(ResultDictDup);
}
// Iterate over the Dictionary entries
const cmsDICTentry* entry = cmsDictGetEntryList(hDict);
cmsDictNextEntry(entry);
cmsMLUfree(mlu);
cmsDictFree(hDict);
return 0;
}

View File

@ -0,0 +1,43 @@
/* Copyright 2023 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <stdint.h>
#include "lcms2.h"
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size < 16) {
return 0;
}
//cmsGBDAlloc
cmsHANDLE hGDB = cmsGBDAlloc(NULL);
if (!hGDB){
return 0;
}
//cmsGDBAddPoint
cmsCIELab Lab;
Lab.L = *((const uint32_t *)data);
Lab.a = *((const uint32_t *)data+1);
Lab.b = *((const uint32_t *)data+2);
cmsGDBAddPoint(hGDB, &Lab);
//cmsGDBCheckPoint
cmsGDBCheckPoint(hGDB, &Lab);
//cmsGDBCompute
cmsGDBCompute(hGDB, *((const uint32_t *)data+3));
//cmsGBDFree
cmsGBDFree(hGDB);
return 0;
}

View File

@ -0,0 +1,26 @@
/* Copyright 2023 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <stdint.h>
#include "lcms2.h"
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
cmsHPROFILE hProfile = cmsOpenProfileFromMem(data, size);
if (!hProfile){
return 0;
}
//cmsMD5computeID
cmsMD5computeID(hProfile);
cmsCloseProfile(hProfile);
return 0;
}

View File

@ -0,0 +1,44 @@
/* Copyright 2023 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <stdint.h>
#include "lcms2.h"
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size < 16) {
return 0;
}
cmsContext context = cmsCreateContext(NULL, (void *)data);
if (!context){
return 0;
}
cmsHPROFILE hProfile = cmsOpenProfileFromMem(data, size);
if (!hProfile){
return 0;
}
uint32_t flags = *((const uint32_t *)data+2);
uint32_t intent = *((const uint32_t *)data+3) % 16;
/* cmsGetPostScriptCSA */
cmsUInt32Number result1 = cmsGetPostScriptCSA(context, hProfile, intent, flags, NULL, size);
/* cmsGetPostScriptCRD */
cmsUInt32Number result2 = cmsGetPostScriptCRD(context, hProfile, intent, flags, NULL, size);
cmsCloseProfile(hProfile);
cmsDeleteContext(context);
return 0;
}

View File

@ -62,6 +62,18 @@ run_test(const uint8_t *data,
dstProfile = cmsCreateLab4Profile(NULL);
dstFormat = TYPE_Lab_DBL;
}
else if (dstVal == 8){
dstProfile = cmsCreate_OkLabProfile(NULL);
dstFormat = (FLOAT_SH(1)|COLORSPACE_SH(PT_MCH3)|CHANNELS_SH(3)|BYTES_SH(0));
}
else if (dstVal == 9){
dstProfile = cmsCreateNULLProfile();
dstFormat = 0;
}
else if (dstVal == 10){
dstProfile = cmsCreateBCHSWabstractProfile(17, 0, 1.2, 0, 3, 5000, 5000);
dstFormat = TYPE_Lab_DBL;
}
else {
dstProfile = cmsCreate_sRGBProfile();
dstFormat = TYPE_RGB_8;
@ -128,7 +140,7 @@ run_test(const uint8_t *data,
cmsCIEXYZTRIPLE out[4];
cmsDoTransform(hTransform, input, out, 1);
}
else if (dstFormat == TYPE_Lab_DBL) {
else if (dstFormat == TYPE_Lab_DBL || dstFormat == (FLOAT_SH(1)|COLORSPACE_SH(PT_MCH3)|CHANNELS_SH(3)|BYTES_SH(0))) {
cmsCIELab Lab1;
cmsDoTransform(hTransform, input, &Lab1, 1);
}
@ -148,7 +160,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
uint32_t flags = *((const uint32_t *)data+0);
uint32_t intent = *((const uint32_t *)data+1) % 16;
int decider = *((int*)data+2) % 10;
int decider = *((int*)data+2) % 11;
data += 12;
size -= 12;

View File

@ -0,0 +1,88 @@
/* Copyright 2023 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "lcms2.h"
#include <stdint.h>
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size < 16) {
return 0;
}
cmsHPROFILE hInProfile = cmsOpenProfileFromMem(data, size);
if (!hInProfile) {
return 0;
}
cmsHPROFILE hOutProfile = cmsCreate_sRGBProfile();
if (!hOutProfile) {
cmsCloseProfile(hInProfile);
return 0;
}
cmsColorSpaceSignature srcCS = cmsGetColorSpace(hInProfile);
cmsUInt32Number nSrcComponents = cmsChannelsOf(srcCS);
cmsUInt32Number srcFormat;
if (srcCS == cmsSigLabData) {
srcFormat =
COLORSPACE_SH(PT_Lab) | CHANNELS_SH(nSrcComponents) | BYTES_SH(0);
} else {
srcFormat =
COLORSPACE_SH(PT_ANY) | CHANNELS_SH(nSrcComponents) | BYTES_SH(1);
}
cmsHTRANSFORM hTransform = cmsCreateTransform(
hInProfile, srcFormat, hOutProfile, TYPE_BGR_8,
*((const uint32_t *)data + 3) % 16, *((const uint32_t *)data + 2));
cmsCloseProfile(hInProfile);
cmsCloseProfile(hOutProfile);
if (!hTransform) {
return 0;
}
cmsFloat64Number version;
if (*((const uint32_t *)data + 3) % 2 == 0) {
version = 3.4;
} else {
version = 4.4;
}
// cmsTransform2DeviceLink
cmsHPROFILE devicelinkProfile = cmsTransform2DeviceLink(
hTransform, version, *((const uint32_t *)data + 2));
// clean up
cmsDeleteTransform(hTransform);
if (devicelinkProfile) {
cmsCloseProfile(devicelinkProfile);
}
// cmsCreateLinearizationDeviceLink
cmsToneCurve *tone = cmsBuildGamma(NULL, *((const uint32_t *)data + 3));
if (!tone) {
return 0;
}
// 15 curves, so it can handle all color spaces
cmsToneCurve *rgb_curves[15] = {tone, tone, tone, tone, tone,
tone, tone, tone, tone, tone,
tone, tone, tone, tone, tone};
cmsHPROFILE linearizationDeviceLinkProfile =
cmsCreateLinearizationDeviceLink(srcCS, rgb_curves);
cmsFreeToneCurve(tone);
if (linearizationDeviceLinkProfile) {
cmsCloseProfile(linearizationDeviceLinkProfile);
}
return 0;
}