Skip to content

Commit 3464f48

Browse files
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.
1 parent 3414ed7 commit 3464f48

11 files changed

+499
-5
lines changed

projects/lcms/Dockerfile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ RUN mkdir $SRC/seeds && \
2424
cp $SRC/lcms/testbed/test1.icc . && \
2525
cp $SRC/lcms/testbed/crayons.icc . && \
2626
cp $SRC/lcms/testbed/ibm-t61.icc . && \
27+
#add more seeds from the testbed dir
28+
cp $SRC/lcms/testbed/bad_mpe.icc . && \
29+
cp $SRC/lcms/testbed/new.icc . && \
30+
cp $SRC/lcms/testbed/test2.icc . && \
31+
cp $SRC/lcms/testbed/test3.icc . && \
32+
cp $SRC/lcms/testbed/test4.icc . && \
33+
cp $SRC/lcms/testbed/test5.icc . && \
34+
cp $SRC/lcms/testbed/TestCLT.icc . && \
2735
zip -rj $SRC/seed_corpus.zip $SRC/seeds/*
2836

2937
WORKDIR lcms

projects/lcms/build.sh

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,16 @@ FUZZERS="cmsIT8_load_fuzzer \
2626
cms_transform_all_fuzzer \
2727
cms_profile_fuzzer \
2828
cms_universal_transform_fuzzer \
29-
cms_transform_extended_fuzzer"
29+
cms_transform_extended_fuzzer \
30+
cms_md5_fuzzer \
31+
cms_dict_fuzzer \
32+
cms_postscript_fuzzer \
33+
cms_cie_cam02_fuzzer \
34+
cms_gdb_fuzzer \
35+
cms_cgats_fuzzer \
36+
cms_virtual_profile_fuzzer \
37+
cms_devicelink_fuzzer"
38+
3039

3140
for F in $FUZZERS; do
3241
$CC $CFLAGS -c -Iinclude \
@@ -36,11 +45,21 @@ for F in $FUZZERS; do
3645
$LIB_FUZZING_ENGINE src/.libs/liblcms2.a
3746
done
3847

39-
cp $SRC/icc.dict $SRC/*.options $OUT/
48+
cp $SRC/*.dict $SRC/*.options $OUT/
4049
cp $SRC/icc.dict $OUT/cms_transform_all_fuzzer.dict
4150
cp $SRC/icc.dict $OUT/cms_transform_extended_fuzzer.dict
4251
cp $SRC/icc.dict $OUT/cms_universal_transform_fuzzer.dict
4352
cp $SRC/icc.dict $OUT/cms_profile_fuzzer.dict
44-
cp $SRC/seed_corpus.zip $OUT/cms_transform_fuzzer_seed_corpus.zip
53+
cp $SRC/icc.dict $OUT/cms_postscript_fuzzer.dict
54+
cp $SRC/icc.dict $OUT/cms_virtual_profile_fuzzer.dict
55+
cp $SRC/icc.dict $OUT/cms_md5_fuzzer.dict
56+
cp $SRC/seed_corpus.zip $OUT/cms_postscript_fuzzer_seed_corpus.zip
4557
cp $SRC/seed_corpus.zip $OUT/cms_profile_fuzzer_seed_corpus.zip
4658
cp $SRC/seed_corpus.zip $OUT/cms_universal_transform_fuzzer_seed_corpus.zip
59+
cp $SRC/seed_corpus.zip $OUT/cms_transform_all_fuzzer_seed_corpus.zip
60+
cp $SRC/seed_corpus.zip $OUT/cms_transform_extended_fuzzer_seed_corpus.zip
61+
cp $SRC/seed_corpus.zip $OUT/cms_transform_fuzzer_seed_corpus.zip
62+
cp $SRC/seed_corpus.zip $OUT/cms_virtual_profile_fuzzer_seed_corpus.zip
63+
cp $SRC/seed_corpus.zip $OUT/cmsIT8_load_fuzzer_seed_corpus.zip
64+
cp $SRC/seed_corpus.zip $OUT/cms_md5_fuzzer_seed_corpus.zip
65+
cp $SRC/seed_corpus.zip $OUT/cms_overwrite_transform_fuzzer_seed_corpus.zip

projects/lcms/cms_cgats_fuzzer.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/* Copyright 2023 Google LLC
2+
Licensed under the Apache License, Version 2.0 (the "License");
3+
you may not use this file except in compliance with the License.
4+
You may obtain a copy of the License at
5+
http://www.apache.org/licenses/LICENSE-2.0
6+
Unless required by applicable law or agreed to in writing, software
7+
distributed under the License is distributed on an "AS IS" BASIS,
8+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
See the License for the specific language governing permissions and
10+
limitations under the License.
11+
*/
12+
13+
#include <stdint.h>
14+
#include "lcms2.h"
15+
16+
17+
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
18+
19+
if (size < 8){
20+
return 0;
21+
}
22+
23+
cmsContext context = cmsCreateContext(NULL, (void *)data);
24+
25+
uint32_t Row = *((uint32_t *)data);
26+
uint32_t Col = *((uint32_t *)data+1);
27+
28+
/* Write */
29+
cmsHANDLE it8;
30+
cmsInt32Number i;
31+
32+
it8 = cmsIT8Alloc(0);
33+
if (it8 == NULL) return 0;
34+
35+
cmsIT8SetSheetType(it8, "LCMS/TESTING");
36+
cmsIT8SetPropertyStr(it8, "ORIGINATOR", "1 2 3 4");
37+
cmsIT8SetPropertyUncooked(it8, "DESCRIPTOR", "1234");
38+
cmsIT8SetPropertyStr(it8, "MANUFACTURER", "3");
39+
cmsIT8SetPropertyDbl(it8, "CREATED", data[0] / 255.0);
40+
cmsIT8SetPropertyDbl(it8, "SERIAL", data[1] / 255.0);
41+
cmsIT8SetPropertyHex(it8, "MATERIAL", 0x123);
42+
43+
cmsIT8SetPropertyDbl(it8, "NUMBER_OF_SETS", 10);
44+
cmsIT8SetPropertyDbl(it8, "NUMBER_OF_FIELDS", Row);
45+
46+
cmsIT8SetDataFormat(it8, 0, "SAMPLE_ID");
47+
cmsIT8SetDataFormat(it8, 1, "RGB_R");
48+
cmsIT8SetDataFormat(it8, 2, "RGB_G");
49+
cmsIT8SetDataFormat(it8, 3, "RGB_B");
50+
51+
for (i=0; i < 10; i++) {
52+
53+
char Patch[20];
54+
55+
sprintf(Patch, "P%d", i);
56+
57+
cmsIT8SetDataRowCol(it8, i, 0, Patch);
58+
cmsIT8SetDataRowColDbl(it8, i, 1, i);
59+
cmsIT8SetDataRowColDbl(it8, i, 2, i);
60+
cmsIT8SetDataRowColDbl(it8, i, 3, i);
61+
}
62+
63+
cmsIT8SaveToFile(it8, "TEST.IT8");
64+
cmsIT8Free(it8);
65+
66+
it8 = cmsIT8LoadFromFile(0, "TEST.IT8");
67+
if (it8 == NULL) return 0;
68+
69+
/* Read */
70+
cmsIT8GetDataRowColDbl(it8,Row,Col);
71+
cmsIT8GetPropertyDbl(it8, "DESCRIPTOR");
72+
cmsIT8GetDataDbl(it8, "P3", "RGB_G");
73+
74+
cmsIT8Free(it8);
75+
return 1;
76+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/* Copyright 2023 Google LLC
2+
Licensed under the Apache License, Version 2.0 (the "License");
3+
you may not use this file except in compliance with the License.
4+
You may obtain a copy of the License at
5+
http://www.apache.org/licenses/LICENSE-2.0
6+
Unless required by applicable law or agreed to in writing, software
7+
distributed under the License is distributed on an "AS IS" BASIS,
8+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
See the License for the specific language governing permissions and
10+
limitations under the License.
11+
*/
12+
13+
#include <stdint.h>
14+
#include "lcms2.h"
15+
16+
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
17+
18+
if (size < sizeof(cmsViewingConditions)) {
19+
return 0;
20+
}
21+
22+
// Define and initialize the viewing conditions structure
23+
cmsViewingConditions viewingConditions;
24+
viewingConditions.whitePoint.X = data[0]/ 255.0;
25+
viewingConditions.whitePoint.Y = data[1]/ 255.0;
26+
viewingConditions.whitePoint.Z = data[2]/ 255.0;
27+
viewingConditions.Yb = data[3] / 255.0;
28+
viewingConditions.La = data[4]/ 255.0;
29+
viewingConditions.surround = data[5] % 4 + 1; //from 1 to 4
30+
viewingConditions.D_value = data[6] / 255.0;
31+
32+
cmsContext context = cmsCreateContext(NULL, NULL);
33+
34+
cmsHANDLE hModel = cmsCIECAM02Init(context, &viewingConditions);
35+
36+
if (hModel) {
37+
// Perform forward and reverse CAM02 transformations with appropriate input data
38+
cmsCIEXYZ inputXYZ;
39+
inputXYZ.X = data[0]/ 255.0; // Random value between 0 and 1
40+
inputXYZ.Y = data[1] / 255.0;
41+
inputXYZ.Z = data[2] / 255.0;
42+
cmsJCh outputJCh;
43+
cmsCIEXYZ outputXYZ;
44+
cmsCIECAM02Forward(hModel, &inputXYZ, &outputJCh);
45+
cmsCIECAM02Reverse(hModel, &outputJCh, &outputXYZ);
46+
cmsCIECAM02Done(hModel);
47+
}
48+
cmsDeleteContext(context);
49+
50+
return 0;
51+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* Copyright 2023 Google LLC
2+
Licensed under the Apache License, Version 2.0 (the "License");
3+
you may not use this file except in compliance with the License.
4+
You may obtain a copy of the License at
5+
http://www.apache.org/licenses/LICENSE-2.0
6+
Unless required by applicable law or agreed to in writing, software
7+
distributed under the License is distributed on an "AS IS" BASIS,
8+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
See the License for the specific language governing permissions and
10+
limitations under the License.
11+
*/
12+
13+
#include "lcms2.h"
14+
#include <stdint.h>
15+
16+
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
17+
18+
if (size < 4) {
19+
return 0;
20+
}
21+
22+
// cmsCreateInkLimitingDeviceLink
23+
cmsFloat64Number limit = *((const uint32_t *)data) % 401;
24+
25+
cmsHPROFILE limitingDeviceLinkProfile =
26+
cmsCreateInkLimitingDeviceLink(cmsSigCmykData, limit);
27+
if (limitingDeviceLinkProfile) {
28+
cmsCloseProfile(limitingDeviceLinkProfile);
29+
}
30+
31+
return 0;
32+
}

projects/lcms/cms_dict_fuzzer.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/* Copyright 2023 Google LLC
2+
Licensed under the Apache License, Version 2.0 (the "License");
3+
you may not use this file except in compliance with the License.
4+
You may obtain a copy of the License at
5+
http://www.apache.org/licenses/LICENSE-2.0
6+
Unless required by applicable law or agreed to in writing, software
7+
distributed under the License is distributed on an "AS IS" BASIS,
8+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
See the License for the specific language governing permissions and
10+
limitations under the License.
11+
*/
12+
13+
#include <stdint.h>
14+
#include <stdlib.h>
15+
#include "lcms2.h"
16+
17+
wchar_t* generateWideString(const char* characters, const uint8_t *data){
18+
if (!characters){
19+
return NULL;
20+
}
21+
22+
char stringToWide[10];
23+
for (int i = 0; i < 9; i++){
24+
stringToWide[i] = characters[data[i] % 95];
25+
}
26+
stringToWide[9] = '\0';
27+
28+
int requiredSize = mbstowcs(NULL, stringToWide, 0);
29+
wchar_t* wideString = (wchar_t *)malloc((requiredSize + 1) * sizeof(wchar_t));
30+
mbstowcs(wideString, stringToWide, requiredSize + 1);
31+
return wideString;
32+
}
33+
34+
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
35+
if (size < 27){
36+
return 0;
37+
}
38+
39+
cmsContext context = cmsCreateContext(NULL, (void *)data);
40+
if (!context) {
41+
return 0;
42+
}
43+
44+
// Create a Dictionary handle
45+
cmsHANDLE hDict = cmsDictAlloc(context);
46+
if (!hDict) {
47+
return 0;
48+
}
49+
50+
51+
cmsMLU *mlu = cmsMLUalloc(hDict, 0);
52+
if (!mlu) {
53+
return 0;
54+
}
55+
56+
char* characters = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
57+
wchar_t* wideString = generateWideString(characters, data);
58+
cmsMLUsetWide(mlu, "en", "US", wideString);
59+
free(wideString);
60+
61+
62+
char ObtainedLanguage[3], ObtainedCountry[3];
63+
ObtainedLanguage[0] = characters[*(data+1) % 95];
64+
ObtainedLanguage[1] = characters[*(data+2) % 95];
65+
ObtainedLanguage[2] = characters[*(data) % 95];
66+
67+
ObtainedCountry[0] = characters[*(data+2) % 95];
68+
ObtainedCountry[1] = characters[*data % 95];
69+
ObtainedCountry[2] = characters[*(data+1) % 95];
70+
cmsMLUgetTranslation(mlu, "en", "US",ObtainedLanguage,ObtainedCountry);
71+
cmsMLUtranslationsCount(mlu);
72+
cmsMLUtranslationsCodes(mlu, *((uint32_t *)data), ObtainedLanguage, ObtainedCountry);
73+
74+
cmsMLU* displayName = mlu;
75+
cmsMLU* displayValue = mlu;
76+
77+
//cmsDictAddEntry
78+
wchar_t* name = generateWideString(characters, data + 9);
79+
wchar_t* value = generateWideString(characters, data + 18);
80+
cmsDictAddEntry(hDict, name, value, displayName, displayValue);
81+
free(name);
82+
free(value);
83+
84+
//cmsDictDup
85+
cmsHANDLE ResultDictDup = cmsDictDup(hDict);
86+
if (ResultDictDup) {
87+
cmsDictFree(ResultDictDup);
88+
}
89+
// Iterate over the Dictionary entries
90+
const cmsDICTentry* entry = cmsDictGetEntryList(hDict);
91+
cmsDictNextEntry(entry);
92+
cmsMLUfree(mlu);
93+
cmsDictFree(hDict);
94+
return 0;
95+
}

projects/lcms/cms_gdb_fuzzer.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/* Copyright 2023 Google LLC
2+
Licensed under the Apache License, Version 2.0 (the "License");
3+
you may not use this file except in compliance with the License.
4+
You may obtain a copy of the License at
5+
http://www.apache.org/licenses/LICENSE-2.0
6+
Unless required by applicable law or agreed to in writing, software
7+
distributed under the License is distributed on an "AS IS" BASIS,
8+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
See the License for the specific language governing permissions and
10+
limitations under the License.
11+
*/
12+
13+
#include <stdint.h>
14+
#include "lcms2.h"
15+
16+
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
17+
18+
if (size < 16) {
19+
return 0;
20+
}
21+
//cmsGBDAlloc
22+
cmsHANDLE hGDB = cmsGBDAlloc(NULL);
23+
if (!hGDB){
24+
return 0;
25+
}
26+
//cmsGDBAddPoint
27+
cmsCIELab Lab;
28+
Lab.L = *((const uint32_t *)data);
29+
Lab.a = *((const uint32_t *)data+1);
30+
Lab.b = *((const uint32_t *)data+2);
31+
cmsGDBAddPoint(hGDB, &Lab);
32+
33+
//cmsGDBCheckPoint
34+
cmsGDBCheckPoint(hGDB, &Lab);
35+
36+
//cmsGDBCompute
37+
cmsGDBCompute(hGDB, *((const uint32_t *)data+3));
38+
39+
//cmsGBDFree
40+
cmsGBDFree(hGDB);
41+
42+
return 0;
43+
}

projects/lcms/cms_md5_fuzzer.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/* Copyright 2023 Google LLC
2+
Licensed under the Apache License, Version 2.0 (the "License");
3+
you may not use this file except in compliance with the License.
4+
You may obtain a copy of the License at
5+
http://www.apache.org/licenses/LICENSE-2.0
6+
Unless required by applicable law or agreed to in writing, software
7+
distributed under the License is distributed on an "AS IS" BASIS,
8+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
See the License for the specific language governing permissions and
10+
limitations under the License.
11+
*/
12+
13+
#include <stdint.h>
14+
#include "lcms2.h"
15+
16+
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
17+
18+
cmsHPROFILE hProfile = cmsOpenProfileFromMem(data, size);
19+
if (!hProfile){
20+
return 0;
21+
}
22+
//cmsMD5computeID
23+
cmsMD5computeID(hProfile);
24+
cmsCloseProfile(hProfile);
25+
return 0;
26+
}

0 commit comments

Comments
 (0)