diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4608a46b..cfd5ffc3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -167,6 +167,7 @@ jobs: uses: actions/checkout@v4 - name: Set up build run: | + sudo apt install -y nasm sudo sysctl vm.mmap_rnd_bits=28 - name: Build env: @@ -174,7 +175,7 @@ jobs: run: | mkdir build pushd build - cmake -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_COMPILER=clang -DCMAKE_C_FLAGS_RELWITHDEBINFO="-O0 -g -fsanitize=memory -fsanitize-memory-param-retval -fno-sanitize-recover=all -fPIE" -DWITH_SIMD=0 .. + cmake -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_COMPILER=clang -DCMAKE_C_FLAGS_RELWITHDEBINFO="-O0 -g -fsanitize=memory -fsanitize-memory-param-retval -fno-sanitize-recover=all -fPIE -DZERO_BUFFERS=1" -DREQUIRE_SIMD=1 .. export NUMCPUS=`grep -c '^processor' /proc/cpuinfo` make -j$NUMCPUS --load-average=$NUMCPUS make test diff --git a/fuzz/cjpeg.cc b/fuzz/cjpeg.cc index ee7b7ab8..4d598f35 100644 --- a/fuzz/cjpeg.cc +++ b/fuzz/cjpeg.cc @@ -57,13 +57,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) (char *)"-targa", NULL }; int fd = -1; -#if defined(__has_feature) && __has_feature(memory_sanitizer) - char env[18] = "JSIMD_FORCENONE=1"; - - /* The libjpeg-turbo SIMD extensions produce false positives with - MemorySanitizer. */ - putenv(env); -#endif snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_cjpeg_fuzz.XXXXXX"); if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0) diff --git a/fuzz/compress.cc b/fuzz/compress.cc index f59f66d1..daad0471 100644 --- a/fuzz/compress.cc +++ b/fuzz/compress.cc @@ -59,13 +59,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { TJPF_GRAY, TJSAMP_GRAY, 50 }, { TJPF_CMYK, TJSAMP_440, 40 } }; -#if defined(__has_feature) && __has_feature(memory_sanitizer) - char env[18] = "JSIMD_FORCENONE=1"; - - /* The libjpeg-turbo SIMD extensions produce false positives with - MemorySanitizer. */ - putenv(env); -#endif snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_compress_fuzz.XXXXXX"); if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0) diff --git a/fuzz/compress12.cc b/fuzz/compress12.cc index 8a082999..12cb7565 100644 --- a/fuzz/compress12.cc +++ b/fuzz/compress12.cc @@ -60,13 +60,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { TJPF_GRAY, TJSAMP_GRAY, 50 }, { TJPF_CMYK, TJSAMP_440, 40 } }; -#if defined(__has_feature) && __has_feature(memory_sanitizer) - char env[18] = "JSIMD_FORCENONE=1"; - - /* The libjpeg-turbo SIMD extensions produce false positives with - MemorySanitizer. */ - putenv(env); -#endif snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_compress12_fuzz.XXXXXX"); if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0) diff --git a/fuzz/compress12_lossless.cc b/fuzz/compress12_lossless.cc index 76a0a0d9..3ac10f7c 100644 --- a/fuzz/compress12_lossless.cc +++ b/fuzz/compress12_lossless.cc @@ -59,13 +59,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { TJPF_GRAY, 6, 3 }, { TJPF_CMYK, 7, 0 } }; -#if defined(__has_feature) && __has_feature(memory_sanitizer) - char env[18] = "JSIMD_FORCENONE=1"; - - /* The libjpeg-turbo SIMD extensions produce false positives with - MemorySanitizer. */ - putenv(env); -#endif snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_compress_fuzz.XXXXXX"); if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0) diff --git a/fuzz/compress16_lossless.cc b/fuzz/compress16_lossless.cc index aa6037ec..35cfff6f 100644 --- a/fuzz/compress16_lossless.cc +++ b/fuzz/compress16_lossless.cc @@ -59,13 +59,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { TJPF_GRAY, 6, 3 }, { TJPF_CMYK, 7, 0 } }; -#if defined(__has_feature) && __has_feature(memory_sanitizer) - char env[18] = "JSIMD_FORCENONE=1"; - - /* The libjpeg-turbo SIMD extensions produce false positives with - MemorySanitizer. */ - putenv(env); -#endif snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_compress_fuzz.XXXXXX"); if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0) diff --git a/fuzz/compress_lossless.cc b/fuzz/compress_lossless.cc index 7c2bb790..d094cad2 100644 --- a/fuzz/compress_lossless.cc +++ b/fuzz/compress_lossless.cc @@ -58,13 +58,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { TJPF_GRAY, 6, 3 }, { TJPF_CMYK, 7, 0 } }; -#if defined(__has_feature) && __has_feature(memory_sanitizer) - char env[18] = "JSIMD_FORCENONE=1"; - - /* The libjpeg-turbo SIMD extensions produce false positives with - MemorySanitizer. */ - putenv(env); -#endif snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_compress_fuzz.XXXXXX"); if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0) diff --git a/fuzz/compress_yuv.cc b/fuzz/compress_yuv.cc index 0b12e0ce..ddde0b85 100644 --- a/fuzz/compress_yuv.cc +++ b/fuzz/compress_yuv.cc @@ -58,13 +58,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { TJPF_BGR, TJSAMP_GRAY, 60 }, { TJPF_GRAY, TJSAMP_GRAY, 50 } }; -#if defined(__has_feature) && __has_feature(memory_sanitizer) - char env[18] = "JSIMD_FORCENONE=1"; - - /* The libjpeg-turbo SIMD extensions produce false positives with - MemorySanitizer. */ - putenv(env); -#endif snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_compress_yuv_fuzz.XXXXXX"); if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0) diff --git a/fuzz/decompress.cc b/fuzz/decompress.cc index eadc7342..bb14c6bb 100644 --- a/fuzz/decompress.cc +++ b/fuzz/decompress.cc @@ -44,13 +44,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) necessary to achieve full coverage. */ enum TJPF pixelFormats[NUMPF] = { TJPF_RGB, TJPF_BGRX, TJPF_GRAY, TJPF_CMYK }; -#if defined(__has_feature) && __has_feature(memory_sanitizer) - char env[18] = "JSIMD_FORCENONE=1"; - - /* The libjpeg-turbo SIMD extensions produce false positives with - MemorySanitizer. */ - putenv(env); -#endif if ((handle = tj3Init(TJINIT_DECOMPRESS)) == NULL) goto bailout; diff --git a/fuzz/decompress_yuv.cc b/fuzz/decompress_yuv.cc index 4e869df6..36252104 100644 --- a/fuzz/decompress_yuv.cc +++ b/fuzz/decompress_yuv.cc @@ -44,13 +44,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) necessary to achieve full coverage. */ enum TJPF pixelFormats[NUMPF] = { TJPF_BGR, TJPF_XRGB, TJPF_GRAY }; -#if defined(__has_feature) && __has_feature(memory_sanitizer) - char env[18] = "JSIMD_FORCENONE=1"; - - /* The libjpeg-turbo SIMD extensions produce false positives with - MemorySanitizer. */ - putenv(env); -#endif if ((handle = tj3Init(TJINIT_DECOMPRESS)) == NULL) goto bailout; diff --git a/fuzz/transform.cc b/fuzz/transform.cc index 8d2e6aca..84a8ccec 100644 --- a/fuzz/transform.cc +++ b/fuzz/transform.cc @@ -39,13 +39,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) size_t dstSizes[1] = { 0 }, maxBufSize; int width = 0, height = 0, jpegSubsamp, i; tjtransform transforms[1]; -#if defined(__has_feature) && __has_feature(memory_sanitizer) - char env[18] = "JSIMD_FORCENONE=1"; - - /* The libjpeg-turbo SIMD extensions produce false positives with - MemorySanitizer. */ - putenv(env); -#endif if ((handle = tj3Init(TJINIT_TRANSFORM)) == NULL) goto bailout; diff --git a/jchuff.c b/jchuff.c index 488c9b5c..8cdd5bd3 100644 --- a/jchuff.c +++ b/jchuff.c @@ -542,6 +542,10 @@ encode_one_block_simd(working_state *state, JCOEFPTR block, int last_dc_val, JOCTET _buffer[BUFSIZE], *buffer; int localbuf = 0; +#ifdef ZERO_BUFFERS + memset(_buffer, 0, sizeof(_buffer)); +#endif + LOAD_BUFFER() buffer = jsimd_huff_encode_one_block(state, buffer, block, last_dc_val, diff --git a/jcphuff.c b/jcphuff.c index 484e2d85..58287328 100644 --- a/jcphuff.c +++ b/jcphuff.c @@ -650,6 +650,11 @@ encode_mcu_AC_first(j_compress_ptr cinfo, JBLOCKROW *MCU_data) size_t bits[8 / SIZEOF_SIZE_T]; int max_coef_bits = cinfo->data_precision + 2; +#ifdef ZERO_BUFFERS + memset(values_unaligned, 0, sizeof(values_unaligned)); + memset(bits, 0, sizeof(bits)); +#endif + entropy->next_output_byte = cinfo->dest->next_output_byte; entropy->free_in_buffer = cinfo->dest->free_in_buffer; @@ -915,6 +920,11 @@ encode_mcu_AC_refine(j_compress_ptr cinfo, JBLOCKROW *MCU_data) size_t zerobits, signbits; size_t bits[16 / SIZEOF_SIZE_T]; +#ifdef ZERO_BUFFERS + memset(absvalues_unaligned, 0, sizeof(absvalues_unaligned)); + memset(bits, 0, sizeof(bits)); +#endif + entropy->next_output_byte = cinfo->dest->next_output_byte; entropy->free_in_buffer = cinfo->dest->free_in_buffer; diff --git a/jdatadst-tj.c b/jdatadst-tj.c index cce263af..270b2c2c 100644 --- a/jdatadst-tj.c +++ b/jdatadst-tj.c @@ -19,6 +19,7 @@ */ /* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +#define JPEG_INTERNALS #include "jinclude.h" #include "jpeglib.h" #include "jerror.h" @@ -92,7 +93,7 @@ empty_mem_output_buffer(j_compress_ptr cinfo) /* Try to allocate new buffer with double size */ nextsize = dest->bufsize * 2; - nextbuffer = (JOCTET *)malloc(nextsize); + nextbuffer = (JOCTET *)MALLOC(nextsize); if (nextbuffer == NULL) ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10); @@ -183,7 +184,7 @@ jpeg_mem_dest_tj(j_compress_ptr cinfo, unsigned char **outbuffer, if (*outbuffer == NULL || *outsize == 0) { if (alloc) { /* Allocate initial buffer */ - dest->newbuffer = *outbuffer = (unsigned char *)malloc(OUTPUT_BUF_SIZE); + dest->newbuffer = *outbuffer = (unsigned char *)MALLOC(OUTPUT_BUF_SIZE); if (dest->newbuffer == NULL) ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10); *outsize = OUTPUT_BUF_SIZE; diff --git a/jmemnobs.c b/jmemnobs.c index cd6571ba..692775f5 100644 --- a/jmemnobs.c +++ b/jmemnobs.c @@ -4,7 +4,7 @@ * This file was part of the Independent JPEG Group's software: * Copyright (C) 1992-1996, Thomas G. Lane. * libjpeg-turbo Modifications: - * Copyright (C) 2017-2018, D. R. Commander. + * Copyright (C) 2017-2018, 2024, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -31,7 +31,7 @@ GLOBAL(void *) jpeg_get_small(j_common_ptr cinfo, size_t sizeofobject) { - return (void *)malloc(sizeofobject); + return (void *)MALLOC(sizeofobject); } GLOBAL(void) @@ -48,7 +48,7 @@ jpeg_free_small(j_common_ptr cinfo, void *object, size_t sizeofobject) GLOBAL(void *) jpeg_get_large(j_common_ptr cinfo, size_t sizeofobject) { - return (void *)malloc(sizeofobject); + return (void *)MALLOC(sizeofobject); } GLOBAL(void) diff --git a/jpegint.h b/jpegint.h index 7c28da3d..a90493f9 100644 --- a/jpegint.h +++ b/jpegint.h @@ -446,6 +446,12 @@ struct jpeg_color_quantizer { #undef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) +#ifdef ZERO_BUFFERS +#define MALLOC(size) calloc(1, size) +#else +#define MALLOC(size) malloc(size) +#endif + /* We assume that right shift corresponds to signed division by 2 with * rounding towards minus infinity. This is correct for typical "arithmetic diff --git a/turbojpeg.c b/turbojpeg.c index 3c936160..6c484d5b 100644 --- a/turbojpeg.c +++ b/turbojpeg.c @@ -879,7 +879,7 @@ DLLEXPORT void tjFree(unsigned char *buf) /* TurboJPEG 3+ */ DLLEXPORT void *tj3Alloc(size_t bytes) { - return malloc(bytes); + return MALLOC(bytes); } /* TurboJPEG 1.2+ */ @@ -1292,7 +1292,7 @@ DLLEXPORT int tj3EncodeYUVPlanes8(tjhandle handle, const unsigned char *srcBuf, for (i = 0; i < cinfo->num_components; i++) { compptr = &cinfo->comp_info[i]; - _tmpbuf[i] = (JSAMPLE *)malloc( + _tmpbuf[i] = (JSAMPLE *)MALLOC( PAD((compptr->width_in_blocks * cinfo->max_h_samp_factor * DCTSIZE) / compptr->h_samp_factor, 32) * cinfo->max_v_samp_factor + 32); @@ -1311,7 +1311,7 @@ DLLEXPORT int tj3EncodeYUVPlanes8(tjhandle handle, const unsigned char *srcBuf, compptr->h_samp_factor, 32) * row]; } _tmpbuf2[i] = - (JSAMPLE *)malloc(PAD(compptr->width_in_blocks * DCTSIZE, 32) * + (JSAMPLE *)MALLOC(PAD(compptr->width_in_blocks * DCTSIZE, 32) * compptr->v_samp_factor + 32); if (!_tmpbuf2[i]) THROW("Memory allocation failure"); @@ -2399,7 +2399,7 @@ DLLEXPORT int tj3DecompressToYUVPlanes8(tjhandle handle, } } if (usetmpbuf) { - if ((_tmpbuf = (JSAMPLE *)malloc(sizeof(JSAMPLE) * tmpbufsize)) == NULL) + if ((_tmpbuf = (JSAMPLE *)MALLOC(sizeof(JSAMPLE) * tmpbufsize)) == NULL) THROW("Memory allocation failure"); ptr = _tmpbuf; for (i = 0; i < dinfo->num_components; i++) {