From: Dr. Matthias St. Pierre Date: Wed, 21 Feb 2018 00:45:14 +0000 (+0100) Subject: bio_b64.c: prevent base64 filter BIO from decoding out-of-bound data X-Git-Tag: OpenSSL_1_1_1-pre3~224 X-Git-Url: https://git.openssl.org/?p=openssl.git;a=commitdiff_plain;h=d070b4ae78a1280c5cb6b88df75bcbfbcef6a8f1;hp=9763f15e80f7e663f140f6201725e0910b59d86a bio_b64.c: prevent base64 filter BIO from decoding out-of-bound data Fixes #5405, #1381 The base64 filter BIO reads its input in chunks of B64_BLOCK_SIZE bytes. When processing input in PEM format it can happen in rare cases that - the trailing PEM marker crosses the boundary of a chunk, and - the beginning of the following chunk contains valid base64 encoded data. This happened in issue #5405, where the PEM marker was split into "-----END CER" and "TIFICATE-----" at the end of the first chunk. The decoding of the first chunk terminated correctly at the '-' character, which is treated as an EOF marker, and b64_read() returned. However, when called the second time, b64_read() read the next chunk and interpreted the string "TIFICATE" as valid base64 encoded data, adding 6 extra bytes '4c 81 48 08 04 c4'. This patch restores the assignment of the error code to 'ctx->cont', which was deleted accidentally in commit 5562cfaca4f3 and which prevents b64_read() from reading additional data on subsequent calls. This issue was observed and reported by Annie Yousar. Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/5422) --- diff --git a/crypto/evp/bio_b64.c b/crypto/evp/bio_b64.c index cade6f8f95..e70fc322d8 100644 --- a/crypto/evp/bio_b64.c +++ b/crypto/evp/bio_b64.c @@ -289,6 +289,14 @@ static int b64_read(BIO *b, char *out, int outl) (unsigned char *)ctx->tmp, i); ctx->tmp_len = 0; } + /* + * If eof or an error was signalled, then the condition + * 'ctx->cont <= 0' will prevent b64_read() from reading + * more data on subsequent calls. This assignment was + * deleted accidentally in commit 5562cfaca4f3. + */ + ctx->cont = i; + ctx->buf_off = 0; if (i < 0) { ret_code = 0;