# Check for potential integer overflow in fread*/fwrite*. --- glibc-2.5.orig/libio/iofread.c +++ glibc-2.5/libio/iofread.c @@ -40,6 +40,11 @@ _IO_fread (buf, size, count, fp) CHECK_FILE (fp, 0); if (bytes_requested == 0) return 0; +#define HALF_INTERNAL_SIZE_T \ + (((size_t) 1) << (8 * sizeof (size_t) / 2)) + if (__builtin_expect ((count | size) >= HALF_INTERNAL_SIZE_T, 0)) + if (bytes_requested / size != count) + return 0; _IO_acquire_lock (fp); bytes_read = INTUSE(_IO_sgetn) (fp, (char *) buf, bytes_requested); _IO_release_lock (fp); --- glibc-2.5.orig/libio/iofread_u.c +++ glibc-2.5/libio/iofread_u.c @@ -42,6 +42,11 @@ fread_unlocked (buf, size, count, fp) CHECK_FILE (fp, 0); if (bytes_requested == 0) return 0; +#define HALF_INTERNAL_SIZE_T \ + (((size_t) 1) << (8 * sizeof (size_t) / 2)) + if (__builtin_expect ((count | size) >= HALF_INTERNAL_SIZE_T, 0)) + if (bytes_requested / size != count) + return 0; bytes_read = INTUSE(_IO_sgetn) (fp, (char *) buf, bytes_requested); return bytes_requested == bytes_read ? count : bytes_read / size; } --- glibc-2.5.orig/libio/iofwrite.c +++ glibc-2.5/libio/iofwrite.c @@ -40,6 +40,11 @@ _IO_fwrite (buf, size, count, fp) CHECK_FILE (fp, 0); if (request == 0) return 0; +#define HALF_INTERNAL_SIZE_T \ + (((size_t) 1) << (8 * sizeof (size_t) / 2)) + if (__builtin_expect ((count | size) >= HALF_INTERNAL_SIZE_T, 0)) + if (request / size != count) + return 0; _IO_acquire_lock (fp); if (_IO_vtable_offset (fp) != 0 || _IO_fwide (fp, -1) == -1) written = _IO_sputn (fp, (const char *) buf, request); --- glibc-2.5.orig/libio/iofwrite_u.c +++ glibc-2.5/libio/iofwrite_u.c @@ -42,6 +42,11 @@ fwrite_unlocked (buf, size, count, fp) CHECK_FILE (fp, 0); if (request == 0) return 0; +#define HALF_INTERNAL_SIZE_T \ + (((size_t) 1) << (8 * sizeof (size_t) / 2)) + if (__builtin_expect ((count | size) >= HALF_INTERNAL_SIZE_T, 0)) + if (request / size != count) + return 0; if (_IO_fwide (fp, -1) == -1) { written = _IO_sputn (fp, (const char *) buf, request);