From 20c918561e6af48b03f3dbaa7553dfd688fd9732 Mon Sep 17 00:00:00 2001 From: =?utf8?q?P=C3=A1draig=20Brady?= Date: Sun, 24 Jun 2018 01:46:10 -0700 Subject: [PATCH] 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. --- 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 093ec41fb5..fbf20a9bd2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -32,6 +32,16 @@ * tests/test-wcwidth.c (main): If the wchar-single module is present, skip the tests in the C locale. +2018-06-24 Pádraig Brady + + 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 af_alg: fix error handling when hash not returned diff --git a/lib/af_alg.c b/lib/af_alg.c index f362caba8b..9630d03912 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 - . */ + /* 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: + . */ + if (feof (stream)) + { + result = 0; + break; + } } } diff --git a/lib/md5.c b/lib/md5.c index a9b65b0191..ea69a59d8e 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 6cfd6c6f37..1295d051cf 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 d45cd184cb..bdea1bda60 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 503a54fe8a..863d6ba7ac 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.39.5