From b8e6390bdd2b1351ffd67f2e5e4797f05baf5a59 Mon Sep 17 00:00:00 2001 From: Paul Dreik Date: Thu, 25 Aug 2022 10:04:32 +0200 Subject: [PATCH 01/10] add script for building with afl --- tests/fuzzers/afl/build-afl.sh | 56 ++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100755 tests/fuzzers/afl/build-afl.sh diff --git a/tests/fuzzers/afl/build-afl.sh b/tests/fuzzers/afl/build-afl.sh new file mode 100755 index 00000000..b6f7c41a --- /dev/null +++ b/tests/fuzzers/afl/build-afl.sh @@ -0,0 +1,56 @@ +#/bin/sh +# +# this creates builds which can be used to fuzz with afl +# +# by Paul Dreik 20220825 + +set -eux + +here=$(dirname $0) +gitroot=$(git -C $here rev-parse --show-toplevel) + + +################################### +# afl clang +export AFL_USE_ASAN=1 +export AFL_USE_UBSAN=1 + +target=$here/build-afl-clang + +cmake \ +-DCMAKE_C_COMPILER=afl-clang-fast \ +-S $gitroot -B $target + +cmake --build $target -j $(nproc) + +################################### +# afl clang, with asserts disabled + +target=$here/build-afl-clang-ndebug + +cmake \ +-DCMAKE_C_COMPILER=afl-clang-fast \ +-DCMAKE_C_FLAGS="-g -DNDEBUG" \ +-S $gitroot -B $target + +cmake --build $target -j $(nproc) + +################################### +# sanitizer build with asserts disabled +target=$here/build-clang-release-replay +cmake \ +-DCMAKE_C_COMPILER=clang-14 \ +-DCMAKE_C_FLAGS="-g -fsanitize=address,undefined -O3 -DNDEBUG" \ +-S $gitroot -B $target + +cmake --build $target -j $(nproc) + +################################### +# sanitizer build with asserts enabled +target=$here/build-clang-debug-replay +cmake \ +-DCMAKE_C_COMPILER=clang-14 \ +-DCMAKE_C_FLAGS="-g -fsanitize=address,undefined -O3" \ +-S $gitroot -B $target + +cmake --build $target -j $(nproc) From aecacb8c0b4aed8a6349408da8e831fa00c5ded8 Mon Sep 17 00:00:00 2001 From: Paul Dreik Date: Thu, 25 Aug 2022 10:15:36 +0200 Subject: [PATCH 02/10] git ignore fuzz working directories --- tests/fuzzers/afl/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/fuzzers/afl/.gitignore diff --git a/tests/fuzzers/afl/.gitignore b/tests/fuzzers/afl/.gitignore new file mode 100644 index 00000000..414487d5 --- /dev/null +++ b/tests/fuzzers/afl/.gitignore @@ -0,0 +1 @@ +build-*/ From bbf52faf8c7c7afc2247d0614f7eb0799f50a912 Mon Sep 17 00:00:00 2001 From: Paul Dreik Date: Thu, 25 Aug 2022 08:38:24 +0200 Subject: [PATCH 03/10] assert illegal null pointer arithmetic in tcd.c opj_tcd_dc_level_shift_decode --- src/lib/openjp2/tcd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/openjp2/tcd.c b/src/lib/openjp2/tcd.c index 438247b6..a807bc3f 100644 --- a/src/lib/openjp2/tcd.c +++ b/src/lib/openjp2/tcd.c @@ -2324,6 +2324,7 @@ static OPJ_BOOL opj_tcd_dc_level_shift_decode(opj_tcd_t *p_tcd) l_max); ++l_current_ptr; } + assert(l_current_ptr!=NULL && "pointer arithmetic on null pointer is undefined behaviour"); l_current_ptr += l_stride; } } else { @@ -2342,6 +2343,7 @@ static OPJ_BOOL opj_tcd_dc_level_shift_decode(opj_tcd_t *p_tcd) } ++l_current_ptr; } + assert(l_current_ptr!=NULL && "pointer arithmetic on null pointer is undefined behaviour"); l_current_ptr += l_stride; } } From 4e7a8d0aff9541e8bf49085633516646b39261d3 Mon Sep 17 00:00:00 2001 From: Paul Dreik Date: Thu, 25 Aug 2022 10:17:51 +0200 Subject: [PATCH 04/10] add reproducers for tcd.c opj_tcd_dc_level_shift_decode use the following commands to reproduce: build-clang-debug-replay/bin/opj_decompress -i crashes/tcd_2327 -o /tmp/xxx.bmp build-clang-debug-replay/bin/opj_decompress -i crashes/tcd_2346 -o /tmp/xxx.bmp --- tests/fuzzers/afl/crashes/tcd_2327 | Bin 0 -> 293 bytes tests/fuzzers/afl/crashes/tcd_2346 | Bin 0 -> 276 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/fuzzers/afl/crashes/tcd_2327 create mode 100644 tests/fuzzers/afl/crashes/tcd_2346 diff --git a/tests/fuzzers/afl/crashes/tcd_2327 b/tests/fuzzers/afl/crashes/tcd_2327 new file mode 100644 index 0000000000000000000000000000000000000000..348a8477beb66347188312c7f7feced058b449d2 GIT binary patch literal 293 zcmZQzVBpCLP*C9IYUg5LU=T?wsVvB1a8O`SW?;xFFj4@D=>q8tAT5@ekx~StL1GFF z%E8l51)w-?{{jHW0y>NU literal 0 HcmV?d00001 diff --git a/tests/fuzzers/afl/crashes/tcd_2346 b/tests/fuzzers/afl/crashes/tcd_2346 new file mode 100644 index 0000000000000000000000000000000000000000..b70043c6f34fe7bad92ade9bcea4bdcbd5f9cbdd GIT binary patch literal 276 zcmZ{fy9&ZU6hvo9U?C?wp%BP zjo`xW+?{)w-2=c42O^$xbO4kWn_UvZ7gSfNBpsnw50g$ntt^9CO3gfhC7KEprZJ#c z*eIF@ZXBMPz8RwVZVS(Bf0xIi_`Sf=_FZ?CR?3Xv!orhL3^QZczHg##7QLOP>t!5G uYK?ZIWlnJT6fl7@=j#RDJ`cAS%t&y^(SH+A|4;$^ps@d;D*aMvQoR7tIxw36 literal 0 HcmV?d00001 From b5ed4a189ab6b69ecc71459716c0f31c9d247065 Mon Sep 17 00:00:00 2001 From: Paul Dreik Date: Thu, 25 Aug 2022 08:40:25 +0200 Subject: [PATCH 05/10] assert memcpy on NULL in ht_dec.c opj_t1_ht_decode_cblk --- src/lib/openjp2/ht_dec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/openjp2/ht_dec.c b/src/lib/openjp2/ht_dec.c index 62a6c9e1..186ae24c 100644 --- a/src/lib/openjp2/ht_dec.c +++ b/src/lib/openjp2/ht_dec.c @@ -1192,6 +1192,7 @@ OPJ_BOOL opj_t1_ht_decode_cblk(opj_t1_t *t1, cblkdata = t1->cblkdatabuffer; cblk_len = 0; for (i = 0; i < cblk->numchunks; i++) { + assert(cblkdata!=NULL && "memcpy on NULL is undefined behaviour"); memcpy(cblkdata + cblk_len, cblk->chunks[i].data, cblk->chunks[i].len); cblk_len += cblk->chunks[i].len; } From 4f4cf2ee8c3a305f6ab5d528ef37f9831c981bff Mon Sep 17 00:00:00 2001 From: Paul Dreik Date: Thu, 25 Aug 2022 10:16:21 +0200 Subject: [PATCH 06/10] add reproducer for ht_dec.c opj_t1_ht_decode_cblk --- tests/fuzzers/afl/crashes/ht_dec_1195 | Bin 0 -> 274 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/fuzzers/afl/crashes/ht_dec_1195 diff --git a/tests/fuzzers/afl/crashes/ht_dec_1195 b/tests/fuzzers/afl/crashes/ht_dec_1195 new file mode 100644 index 0000000000000000000000000000000000000000..e31fb9faabf74306e7169414bd868a522f8ba6d3 GIT binary patch literal 274 zcmZQzVBpCLP*C9IYUg5LU=T?wsVvB1a8O`SW?;xFFj4@D=>q8tAT5@ekx~StL1GFF z%C#BCe<_kk6~bOaQL6+7~txyP?lO$oY|L`prL1|XYhXl1IV2W3<(U3 z|0f^6&S2iaps@ds-m6VOF&;0d Date: Thu, 25 Aug 2022 08:44:28 +0200 Subject: [PATCH 07/10] add note on illegal shift in color.c color_cmyk_to_rgb --- src/bin/common/color.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bin/common/color.c b/src/bin/common/color.c index 27f15f13..e16464e8 100644 --- a/src/bin/common/color.c +++ b/src/bin/common/color.c @@ -1072,6 +1072,7 @@ void color_esycc_to_rgb(opj_image_t *image) int y, cb, cr, sign1, sign2, val; unsigned int w, h, max, i; int flip_value = (1 << (image->comps[0].prec - 1)); + // runtime error: left shift of 1 by 31 places cannot be represented in type 'int' int max_value = (1 << image->comps[0].prec) - 1; if ( From fda72a7cc6e1e41f22051f2d670af65f6fcbeca5 Mon Sep 17 00:00:00 2001 From: Paul Dreik Date: Thu, 25 Aug 2022 08:45:01 +0200 Subject: [PATCH 08/10] add note on integer underflow in color.c color_cmyk_to_rgb --- src/bin/common/color.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bin/common/color.c b/src/bin/common/color.c index e16464e8..92d5d734 100644 --- a/src/bin/common/color.c +++ b/src/bin/common/color.c @@ -1073,6 +1073,7 @@ void color_esycc_to_rgb(opj_image_t *image) unsigned int w, h, max, i; int flip_value = (1 << (image->comps[0].prec - 1)); // runtime error: left shift of 1 by 31 places cannot be represented in type 'int' + // runtime error: signed integer overflow: -2147483648 - 1 cannot be represented in type 'int' int max_value = (1 << image->comps[0].prec) - 1; if ( From 70050037b40f059cba8165bbac4956b70d795b38 Mon Sep 17 00:00:00 2001 From: Paul Dreik Date: Thu, 25 Aug 2022 11:31:46 +0200 Subject: [PATCH 09/10] add reproducer for color.c color_cmyk_to_rgb() --- tests/fuzzers/afl/crashes/color_1077_1123 | Bin 0 -> 293 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/fuzzers/afl/crashes/color_1077_1123 diff --git a/tests/fuzzers/afl/crashes/color_1077_1123 b/tests/fuzzers/afl/crashes/color_1077_1123 new file mode 100644 index 0000000000000000000000000000000000000000..3a9c18784e9c8c7d0f8cb3616f23ab120444235c GIT binary patch literal 293 zcmZQzVBpCLP*C9IYUg5LU=T?wsVvAUFj4@r8KAT-kj?;d#WFKeih#5N7&Ei818D{Z z{^b0eB1SM%0!ZEfDo+0I|38pHA1tN-BtaMk6o3p6h5%+cMn-lp`X9u=!vJD2u&^*N z{*Pf`ad7yb!l25)=vtqEGq& literal 0 HcmV?d00001 From 01719f042312954e2443e64d07873c9b683badbf Mon Sep 17 00:00:00 2001 From: Paul Dreik Date: Thu, 25 Aug 2022 08:52:40 +0200 Subject: [PATCH 10/10] add comment on potential UB in j2k.c opj_j2k_setup_encoder --- src/lib/openjp2/j2k.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lib/openjp2/j2k.c b/src/lib/openjp2/j2k.c index 923bd891..c2adf1ee 100644 --- a/src/lib/openjp2/j2k.c +++ b/src/lib/openjp2/j2k.c @@ -7817,6 +7817,11 @@ OPJ_BOOL opj_j2k_setup_encoder(opj_j2k_t *p_j2k, image->comps[0].h * image->comps[0].prec) / ((double)parameters->tcp_rates[parameters->tcp_numlayers - 1] * 8 * image->comps[0].dx * image->comps[0].dy)); + // this is problematic because INT_MAX is converted to float, but + // it can not represent that value (2147483647) exactly, instead it + // becomes 2147483648.0f which means the else clause may be hit with + // the value 2147483648.0f. that can not be represented as an int, + // so the assignment to int is undefined behaviour if (temp_size > INT_MAX) { parameters->max_cs_size = INT_MAX; } else {