From: Mika Lindqvist Date: Wed, 5 Oct 2022 10:58:28 +0000 (+0300) Subject: Fix memcpy() overflow in adler32_fold.c and crc32_fold.c X-Git-Tag: 2.1.0-beta1~148 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=65c45b064a1b10683e8cbc425b4f4f32ef5017fa;p=thirdparty%2Fzlib-ng.git Fix memcpy() overflow in adler32_fold.c and crc32_fold.c * On 32-bit platforms, last parameter of memcpy() is limited to SSIZE_MAX, but is likely to overlap if used --- diff --git a/adler32_fold.c b/adler32_fold.c index 66d63dd35..adaabe021 100644 --- a/adler32_fold.c +++ b/adler32_fold.c @@ -7,14 +7,19 @@ #include "functable.h" #include "adler32_fold.h" +#include + Z_INTERNAL uint32_t adler32_fold_copy_c(uint32_t adler, uint8_t *dst, const uint8_t *src, uint64_t len) { adler = functable.adler32(adler, src, len); - while (len > SIZE_MAX) { - memcpy(dst, src, SIZE_MAX); - dst += SIZE_MAX; - src += SIZE_MAX; - len -= SIZE_MAX; +/* Test that we don't try to copy more than actually fits in available address space */ +#if INTPTR_MAX > SSIZE_MAX + while (len > SSIZE_MAX) { + memcpy(dst, src, SSIZE_MAX); + dst += SSIZE_MAX; + src += SSIZE_MAX; + len -= SSIZE_MAX; } +#endif if (len) { memcpy(dst, src, (size_t)len); } diff --git a/crc32_fold.c b/crc32_fold.c index eb0aeeb76..b1011debd 100644 --- a/crc32_fold.c +++ b/crc32_fold.c @@ -7,6 +7,8 @@ #include "crc32_fold.h" +#include + Z_INTERNAL uint32_t crc32_fold_reset_c(crc32_fold *crc) { crc->value = CRC32_INITIAL_VALUE; return crc->value; @@ -14,12 +16,15 @@ Z_INTERNAL uint32_t crc32_fold_reset_c(crc32_fold *crc) { Z_INTERNAL void crc32_fold_copy_c(crc32_fold *crc, uint8_t *dst, const uint8_t *src, uint64_t len) { crc->value = functable.crc32(crc->value, src, len); - while (len > SIZE_MAX) { - memcpy(dst, src, SIZE_MAX); - dst += SIZE_MAX; - src += SIZE_MAX; - len -= SIZE_MAX; +/* Test that we don't try to copy more than actually fits in available address space */ +#if INTPTR_MAX > SSIZE_MAX + while (len > SSIZE_MAX) { + memcpy(dst, src, SSIZE_MAX); + dst += SSIZE_MAX; + src += SSIZE_MAX; + len -= SSIZE_MAX; } +#endif if (len) { memcpy(dst, src, (size_t)len); } diff --git a/zbuild.h b/zbuild.h index 10a7fd6b3..510c5addb 100644 --- a/zbuild.h +++ b/zbuild.h @@ -46,6 +46,12 @@ # else typedef long ssize_t; # endif + +# if defined(_WIN64) + #define SSIZE_MAX _I64_MAX +# else + #define SSIZE_MAX LONG_MAX +# endif #endif /* MS Visual Studio does not allow inline in C, only C++.