From c911e5da3c8e09a9531149c95aa92c65ecdf4b99 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Mon, 19 Mar 2018 14:20:53 +0100 Subject: Fix bio callback backward compatibility Don't pass a pointer to uninitialized processed value for BIO_CB_READ and BIO_CB_WRITE Check the correct cmd code in BIO_callback_ctrl Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/5516) --- crypto/bio/bio_lib.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'crypto/bio') diff --git a/crypto/bio/bio_lib.c b/crypto/bio/bio_lib.c index 557d609cd1..95eef7d4bf 100644 --- a/crypto/bio/bio_lib.c +++ b/crypto/bio/bio_lib.c @@ -34,9 +34,8 @@ static long bio_call_callback(BIO *b, int oper, const char *argp, size_t len, long ret; int bareoper; - if (b->callback_ex != NULL) { + if (b->callback_ex != NULL) return b->callback_ex(b, oper, argp, len, argi, argl, inret, processed); - } /* Strip off any BIO_CB_RETURN flag */ bareoper = oper & ~BIO_CB_RETURN; @@ -51,17 +50,17 @@ static long bio_call_callback(BIO *b, int oper, const char *argp, size_t len, return -1; argi = (int)len; + } - if (inret && (oper & BIO_CB_RETURN)) { - if (*processed > INT_MAX) - return -1; - inret = *processed; - } + if (inret && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) { + if (*processed > INT_MAX) + return -1; + inret = *processed; } ret = b->callback(b, oper, argp, argi, argl, inret); - if (ret >= 0 && (HAS_LEN_OPER(bareoper) || bareoper == BIO_CB_PUTS)) { + if (ret >= 0 && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) { *processed = (size_t)ret; ret = 1; } @@ -260,7 +259,7 @@ static int bio_read_intern(BIO *b, void *data, size_t dlen, size_t *readbytes) if ((b->callback != NULL || b->callback_ex != NULL) && ((ret = (int)bio_call_callback(b, BIO_CB_READ, data, dlen, 0, 0L, 1L, - readbytes)) <= 0)) + NULL)) <= 0)) return ret; if (!b->init) { @@ -333,7 +332,7 @@ static int bio_write_intern(BIO *b, const void *data, size_t dlen, if ((b->callback != NULL || b->callback_ex != NULL) && ((ret = (int)bio_call_callback(b, BIO_CB_WRITE, data, dlen, 0, 0L, 1L, - written)) <= 0)) + NULL)) <= 0)) return ret; if (!b->init) { @@ -542,7 +541,8 @@ long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) if (b == NULL) return 0; - if ((b->method == NULL) || (b->method->callback_ctrl == NULL)) { + if ((b->method == NULL) || (b->method->callback_ctrl == NULL) + || (cmd != BIO_CTRL_SET_CALLBACK)) { BIOerr(BIO_F_BIO_CALLBACK_CTRL, BIO_R_UNSUPPORTED_METHOD); return -2; } -- cgit v1.2.3