]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
openssl dgst, openssl enc: check for end of input
authorRichard Levitte <levitte@openssl.org>
Thu, 22 Aug 2019 11:34:16 +0000 (13:34 +0200)
committerRichard Levitte <levitte@openssl.org>
Thu, 22 Aug 2019 12:47:22 +0000 (14:47 +0200)
The input reading loop in 'openssl dgst' and 'openssl enc' doesn't
check for end of input, and because of the way BIO works, it thereby
won't detect that the end is reached before the read is an error.
With the FILE BIO, an error occurs when trying to read past EOF, which
is fairly much ok, except when the command is used interactively, at
least on Unix.  The result in that case is that the user has to press
Ctrl-D twice for the command to terminate.

The issue is further complicated because both these commands use
filter BIOs on top of the FILE BIO, so a naïve attempt to check
BIO_eof() doesn't quite solve it, since that only checks the state of
the source/sink BIO, and the filter BIO may have some buffered data
that still needs to be read.  Fortunately, there's BIO_pending() that
checks exactly that, if any filter BIO has pending data that needs to
be processed.

We end up having to check both BIO_pending() and BIO_eof().

Thanks to Zsigmond Lőrinczy for the initial effort and inspiration.

Fixes #9355

Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/9668)

apps/dgst.c
apps/enc.c

index 7b433385861625595529080fe40c4dec7c1219d3..b44468bc796a61287530e9f28481a09b495413c6 100644 (file)
@@ -461,7 +461,7 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
     size_t len;
     int i, backslash = 0;
 
-    for (;;) {
+    while (BIO_pending(bp) || !BIO_eof(bp)) {
         i = BIO_read(bp, (char *)buf, BUFSIZE);
         if (i < 0) {
             BIO_printf(bio_err, "Read Error in %s\n", file);
index 57ce92433723ec9d35e93b7530f37e2d144ffa20..d2505639e00f4023de7dfb710024617dfc4b9d10 100644 (file)
@@ -586,7 +586,7 @@ int enc_main(int argc, char **argv)
     if (benc != NULL)
         wbio = BIO_push(benc, wbio);
 
-    for (;;) {
+    while (BIO_pending(rbio) || !BIO_eof(rbio)) {
         inl = BIO_read(rbio, (char *)buff, bsize);
         if (inl <= 0)
             break;