[patch] Fix BZ 19165 -- overflow in fread / fwrite
Paul Pluzhnikov
ppluzhnikov@google.com
Mon Oct 26 03:50:00 GMT 2015
Greetings,
Attached patch fixes BZ 19165 by failing fwrite when the byte count is
impossibly large, and by returning actual count from fread, instead of
approximation of it. Tested on Linux/x86_64, no new failures.
2015-10-25 Paul Pluzhnikov <ppluzhnikov@google.com>
[BZ #19165]
* libio/iofread.c (_IO_fread): Return correct count.
* ibio/iofread_u.c (__fread_unlocked): Likewise.
* libio/iofwrite.c (_IO_fwrite): Error on overflow.
* libio/iofwrite_u.c (fwrite_unlocked): Likewise.
--
Paul Pluzhnikov
-------------- next part --------------
diff --git a/libio/iofread.c b/libio/iofread.c
index eb69b05..a8ea391 100644
--- a/libio/iofread.c
+++ b/libio/iofread.c
@@ -37,7 +37,7 @@ _IO_fread (void *buf, _IO_size_t size, _IO_size_t count, _IO_FILE *fp)
_IO_acquire_lock (fp);
bytes_read = _IO_sgetn (fp, (char *) buf, bytes_requested);
_IO_release_lock (fp);
- return bytes_requested == bytes_read ? count : bytes_read / size;
+ return bytes_read / size;
}
libc_hidden_def (_IO_fread)
diff --git a/libio/iofread_u.c b/libio/iofread_u.c
index 997b714..28651bf 100644
--- a/libio/iofread_u.c
+++ b/libio/iofread_u.c
@@ -38,7 +38,7 @@ __fread_unlocked (void *buf, _IO_size_t size, _IO_size_t count, _IO_FILE *fp)
if (bytes_requested == 0)
return 0;
bytes_read = _IO_sgetn (fp, (char *) buf, bytes_requested);
- return bytes_requested == bytes_read ? count : bytes_read / size;
+ return bytes_read / size;
}
libc_hidden_def (__fread_unlocked)
weak_alias (__fread_unlocked, fread_unlocked)
diff --git a/libio/iofwrite.c b/libio/iofwrite.c
index 48ad4bc..4f6c29c 100644
--- a/libio/iofwrite.c
+++ b/libio/iofwrite.c
@@ -34,6 +34,11 @@ _IO_fwrite (const void *buf, _IO_size_t size, _IO_size_t count, _IO_FILE *fp)
CHECK_FILE (fp, 0);
if (request == 0)
return 0;
+ if (count > SIZE_MAX / size)
+ {
+ __set_errno(EOVERFLOW);
+ 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);
diff --git a/libio/iofwrite_u.c b/libio/iofwrite_u.c
index 2b1c47a..f818aec 100644
--- a/libio/iofwrite_u.c
+++ b/libio/iofwrite_u.c
@@ -38,6 +38,11 @@ fwrite_unlocked (const void *buf, _IO_size_t size, _IO_size_t count,
CHECK_FILE (fp, 0);
if (request == 0)
return 0;
+ if (count > SIZE_MAX / size)
+ {
+ __set_errno(EOVERFLOW);
+ return 0;
+ }
if (_IO_fwide (fp, -1) == -1)
{
written = _IO_sputn (fp, (const char *) buf, request);
More information about the Libc-alpha
mailing list