changeset 39707:5fd4481b1d32

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.
author Pádraig Brady <P@draigBrady.com>
date Sun, 24 Jun 2018 01:46:10 -0700
parents 21fef17e5c30
children 0de0c14ac6cb
files ChangeLog lib/af_alg.c lib/md5.c lib/sha1.c lib/sha256.c lib/sha512.c
diffstat 6 files changed, 43 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sun Jun 24 01:29:55 2018 -0700
+++ b/ChangeLog	Sun Jun 24 01:46:10 2018 -0700
@@ -34,6 +34,16 @@
 
 2018-06-24  Pádraig Brady  <P@draigBrady.com>
 
+	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  <P@draigBrady.com>
+
 	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,
--- a/lib/af_alg.c	Sun Jun 24 01:29:55 2018 -0700
+++ b/lib/af_alg.c	Sun Jun 24 01:46:10 2018 -0700
@@ -120,9 +120,7 @@
     }
   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 @@
                         ? -EAFNOSUPPORT : -EIO);
               break;
             }
+
+          /* Assume EOF is not sticky. See:
+             <https://sourceware.org/bugzilla/show_bug.cgi?id=19476>.  */
+          if (feof (stream))
+            {
+              result = 0;
+              break;
+            }
         }
     }
 
--- a/lib/md5.c	Sun Jun 24 01:29:55 2018 -0700
+++ b/lib/md5.c	Sun Jun 24 01:46:10 2018 -0700
@@ -170,6 +170,12 @@
       /* 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 @@
                 }
               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
--- a/lib/sha1.c	Sun Jun 24 01:29:55 2018 -0700
+++ b/lib/sha1.c	Sun Jun 24 01:46:10 2018 -0700
@@ -158,6 +158,12 @@
       /* 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 @@
                 }
               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
--- a/lib/sha256.c	Sun Jun 24 01:29:55 2018 -0700
+++ b/lib/sha256.c	Sun Jun 24 01:46:10 2018 -0700
@@ -208,6 +208,12 @@
       /* 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 @@
                 }
               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
--- a/lib/sha512.c	Sun Jun 24 01:29:55 2018 -0700
+++ b/lib/sha512.c	Sun Jun 24 01:46:10 2018 -0700
@@ -209,6 +209,12 @@
       /* 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 @@
                 }
               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