bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] af_alg: avoid hangs when reading from streams


From: Pádraig Brady
Subject: [PATCH] af_alg: avoid hangs when reading from streams
Date: Sun, 24 Jun 2018 01:52:15 -0700

* lib/af_alg.c (afalg_stream): Don't assume EOF is sticky,
and thus avoid doing a fread() when feof() is set.
* lib/md5.c: Ensure feof() is called before fread().
* lib/sha1.c: Likewise.
* lib/sha256.c: Likewise.
* lib/sha512.c: Likewise.
---
 ChangeLog    | 10 ++++++++++
 lib/af_alg.c | 12 +++++++++---
 lib/md5.c    | 12 ++++++------
 lib/sha1.c   | 12 ++++++------
 lib/sha256.c | 12 ++++++------
 lib/sha512.c | 12 ++++++------
 6 files changed, 43 insertions(+), 27 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 5c6e93f..0be24ae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2018-06-24  Pádraig Brady  <address@hidden>
 
+       af_alg: avoid hangs when reading from streams
+       * lib/af_alg.c (afalg_stream): Don't assume EOF is sticky,
+       and thus avoid doing a fread() when feof() is set.
+       * lib/md5.c: Ensure feof() is called before fread().
+       * lib/sha1.c: Likewise.
+       * lib/sha256.c: Likewise.
+       * lib/sha512.c: Likewise.
+
+2018-06-24  Pádraig Brady  <address@hidden>
+
        af_alg: fix error handling when hash not returned
        * lib/af_alg.c (afalg_stream): Handle the case where we've
        successfully written data to the kernel in the read/write loop,
diff --git a/lib/af_alg.c b/lib/af_alg.c
index f362cab..9630d03 100644
--- a/lib/af_alg.c
+++ b/lib/af_alg.c
@@ -120,9 +120,7 @@ afalg_stream (FILE *stream, const char *alg,
     }
   else
     {
-     /* sendfile not possible, do a classic read-write loop.
-        Defer to glibc as to whether EOF is sticky; see
-        <https://sourceware.org/bugzilla/show_bug.cgi?id=19476>.  */
+     /* sendfile not possible, do a classic read-write loop.  */
       for (;;)
         {
           char buf[BLOCKSIZE];
@@ -141,6 +139,14 @@ afalg_stream (FILE *stream, const char *alg,
                         ? -EAFNOSUPPORT : -EIO);
               break;
             }
+
+          /* Assume EOF is not sticky. See:
+             <https://sourceware.org/bugzilla/show_bug.cgi?id=19476>.  */
+          if (feof (stream))
+            {
+              result = 0;
+              break;
+            }
         }
     }
 
diff --git a/lib/md5.c b/lib/md5.c
index a9b65b0..ea69a59 100644
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -170,6 +170,12 @@ md5_stream (FILE *stream, void *resblock)
       /* Read block.  Take care for partial reads.  */
       while (1)
         {
+          /* Either process a partial fread() from this loop,
+             or the fread() in afalg_stream may have gotten EOF.
+             We need to avoid a subsequent fread() due to glibc BZ 1190.  */
+          if (feof (stream))
+            goto process_partial_block;
+
           n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
 
           sum += n;
@@ -189,12 +195,6 @@ md5_stream (FILE *stream, void *resblock)
                 }
               goto process_partial_block;
             }
-
-          /* We've read at least one byte, so ignore errors.  But always
-             check for EOF, since feof may be true even though N > 0.
-             Otherwise, we could end up calling fread after EOF.  */
-          if (feof (stream))
-            goto process_partial_block;
         }
 
       /* Process buffer with BLOCKSIZE bytes.  Note that
diff --git a/lib/sha1.c b/lib/sha1.c
index 6cfd6c6..1295d05 100644
--- a/lib/sha1.c
+++ b/lib/sha1.c
@@ -158,6 +158,12 @@ sha1_stream (FILE *stream, void *resblock)
       /* Read block.  Take care for partial reads.  */
       while (1)
         {
+          /* Either process a partial fread() from this loop,
+             or the fread() in afalg_stream may have gotten EOF.
+             We need to avoid a subsequent fread() due to glibc BZ 1190.  */
+          if (feof (stream))
+            goto process_partial_block;
+
           n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
 
           sum += n;
@@ -177,12 +183,6 @@ sha1_stream (FILE *stream, void *resblock)
                 }
               goto process_partial_block;
             }
-
-          /* We've read at least one byte, so ignore errors.  But always
-             check for EOF, since feof may be true even though N > 0.
-             Otherwise, we could end up calling fread after EOF.  */
-          if (feof (stream))
-            goto process_partial_block;
         }
 
       /* Process buffer with BLOCKSIZE bytes.  Note that
diff --git a/lib/sha256.c b/lib/sha256.c
index d45cd18..bdea1bd 100644
--- a/lib/sha256.c
+++ b/lib/sha256.c
@@ -208,6 +208,12 @@ shaxxx_stream (FILE *stream, char const *alg, void 
*resblock,
       /* Read block.  Take care for partial reads.  */
       while (1)
         {
+          /* Either process a partial fread() from this loop,
+             or the fread() in afalg_stream may have gotten EOF.
+             We need to avoid a subsequent fread() due to glibc BZ 1190.  */
+          if (feof (stream))
+            goto process_partial_block;
+
           n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
 
           sum += n;
@@ -227,12 +233,6 @@ shaxxx_stream (FILE *stream, char const *alg, void 
*resblock,
                 }
               goto process_partial_block;
             }
-
-          /* We've read at least one byte, so ignore errors.  But always
-             check for EOF, since feof may be true even though N > 0.
-             Otherwise, we could end up calling fread after EOF.  */
-          if (feof (stream))
-            goto process_partial_block;
         }
 
       /* Process buffer with BLOCKSIZE bytes.  Note that
diff --git a/lib/sha512.c b/lib/sha512.c
index 503a54f..863d6ba 100644
--- a/lib/sha512.c
+++ b/lib/sha512.c
@@ -209,6 +209,12 @@ shaxxx_stream (FILE *stream, char const *alg, void 
*resblock,
       /* Read block.  Take care for partial reads.  */
       while (1)
         {
+          /* Either process a partial fread() from this loop,
+             or the fread() in afalg_stream may have gotten EOF.
+             We need to avoid a subsequent fread() due to glibc BZ 1190.  */
+          if (feof (stream))
+            goto process_partial_block;
+
           n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
 
           sum += n;
@@ -228,12 +234,6 @@ shaxxx_stream (FILE *stream, char const *alg, void 
*resblock,
                 }
               goto process_partial_block;
             }
-
-          /* We've read at least one byte, so ignore errors.  But always
-             check for EOF, since feof may be true even though N > 0.
-             Otherwise, we could end up calling fread after EOF.  */
-          if (feof (stream))
-            goto process_partial_block;
         }
 
       /* Process buffer with BLOCKSIZE bytes.  Note that
-- 
2.9.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]