summary refs log tree commit diff
path: root/libio/iofwrite.c
diff options
context:
space:
mode:
authorEric Biggers <ebiggers3@gmail.com>2013-10-11 22:29:38 +0530
committerSiddhesh Poyarekar <siddhesh@redhat.com>2013-10-11 22:29:38 +0530
commit3d110c7c6e6549bd4124fce49cdc672f9e449799 (patch)
tree465a14f8a2e1c8e58f470c2550a524fff481228e /libio/iofwrite.c
parent75b4202ab03337edb37536e3d9470a48a04c9341 (diff)
downloadglibc-3d110c7c6e6549bd4124fce49cdc672f9e449799.tar.gz
glibc-3d110c7c6e6549bd4124fce49cdc672f9e449799.tar.xz
glibc-3d110c7c6e6549bd4124fce49cdc672f9e449799.zip
Fix fwrite() reading beyond end of buffer in error path
Partially revert commits 2b766585f9b4ffabeef2f36200c275976b93f2c7 and
de2fd463b1c0310d75084b6d774fb974075a4ad9, which were intended to fix BZ#11741
but caused another, likely worse bug, namely that fwrite() and fputs() could,
in an error path, read data beyond the end of the specified buffer, and
potentially even write this data to the file.

Fix BZ#11741 properly by checking the return value from _IO_padn() in
stdio-common/vfprintf.c.
Diffstat (limited to 'libio/iofwrite.c')
-rw-r--r--libio/iofwrite.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/libio/iofwrite.c b/libio/iofwrite.c
index 81596a64c4..66542eaea5 100644
--- a/libio/iofwrite.c
+++ b/libio/iofwrite.c
@@ -42,12 +42,12 @@ _IO_fwrite (buf, size, count, fp)
   if (_IO_vtable_offset (fp) != 0 || _IO_fwide (fp, -1) == -1)
     written = _IO_sputn (fp, (const char *) buf, request);
   _IO_release_lock (fp);
-  /* We are guaranteed to have written all of the input, none of it, or
-     some of it.  */
-  if (written == request)
+  /* We have written all of the input in case the return value indicates
+     this or EOF is returned.  The latter is a special case where we
+     simply did not manage to flush the buffer.  But the data is in the
+     buffer and therefore written as far as fwrite is concerned.  */
+  if (written == request || written == EOF)
     return count;
-  else if (written == EOF)
-    return 0;
   else
     return written / size;
 }