X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=crypto%2Fbio%2Fbio_lib.c;h=ca375b911ae8b510b39c0456f90b897a3aff6756;hb=b4b42d441d350b48449ea93aaa035152123f70ae;hp=6d958b1e92af650271f7b827cfebb32a69cdfc22;hpb=bb5310bed5ab14747cad1f6a57aa3b075ca4af65;p=oweals%2Fopenssl.git diff --git a/crypto/bio/bio_lib.c b/crypto/bio/bio_lib.c index 6d958b1e92..ca375b911a 100644 --- a/crypto/bio/bio_lib.c +++ b/crypto/bio/bio_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -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,20 +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 > 0 && (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 > LONG_MAX || ret < LONG_MIN) - return -1; - - 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; } @@ -78,7 +74,7 @@ BIO *BIO_new(const BIO_METHOD *method) if (bio == NULL) { BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE); - return (NULL); + return NULL; } bio->method = method; @@ -101,6 +97,8 @@ BIO *BIO_new(const BIO_METHOD *method) CRYPTO_THREAD_lock_free(bio->lock); goto err; } + if (method->create == NULL) + bio->init = 1; return bio; @@ -116,7 +114,7 @@ int BIO_free(BIO *a) if (a == NULL) return 0; - if (CRYPTO_atomic_add(&a->references, -1, &ret, a->lock) <= 0) + if (CRYPTO_DOWN_REF(&a->references, &ret, a->lock) <= 0) return 0; REF_PRINT_COUNT("BIO", a); @@ -181,7 +179,7 @@ int BIO_up_ref(BIO *a) { int i; - if (CRYPTO_atomic_add(&a->references, 1, &i, a->lock) <= 0) + if (CRYPTO_UP_REF(&a->references, &i, a->lock) <= 0) return 0; REF_PRINT_COUNT("BIO", a); @@ -246,64 +244,70 @@ int BIO_method_type(const BIO *b) /* * This is essentially the same as BIO_read_ex() except that it allows - * 0 or a -ve value to indicate failure (retryable or not) in the return. This - * is for compatibility with the old style BIO_read(), where existing code may - * make assumptions about the return value that it might get. + * 0 or a negative value to indicate failure (retryable or not) in the return. + * This is for compatibility with the old style BIO_read(), where existing code + * may make assumptions about the return value that it might get. */ -static int bio_read_intern(BIO *b, void *out, size_t outl, size_t *read) +static int bio_read_intern(BIO *b, void *data, size_t dlen, size_t *readbytes) { int ret; if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) { - BIOerr(BIO_F_BIO_READ_EX, BIO_R_UNSUPPORTED_METHOD); + BIOerr(BIO_F_BIO_READ_INTERN, BIO_R_UNSUPPORTED_METHOD); return -2; } if ((b->callback != NULL || b->callback_ex != NULL) && - ((ret = (int)bio_call_callback(b, BIO_CB_READ, out, outl, 0, 0L, 1L, - read)) <= 0)) + ((ret = (int)bio_call_callback(b, BIO_CB_READ, data, dlen, 0, 0L, 1L, + NULL)) <= 0)) return ret; if (!b->init) { - BIOerr(BIO_F_BIO_READ_EX, BIO_R_UNINITIALIZED); + BIOerr(BIO_F_BIO_READ_INTERN, BIO_R_UNINITIALIZED); return -2; } - ret = b->method->bread(b, out, outl, read); + ret = b->method->bread(b, data, dlen, readbytes); if (ret > 0) - b->num_read += (uint64_t)*read; + b->num_read += (uint64_t)*readbytes; if (b->callback != NULL || b->callback_ex != NULL) - ret = (int)bio_call_callback(b, BIO_CB_READ | BIO_CB_RETURN, out, outl, - 0, 0L, ret, read); + ret = (int)bio_call_callback(b, BIO_CB_READ | BIO_CB_RETURN, data, + dlen, 0, 0L, ret, readbytes); + + /* Shouldn't happen */ + if (ret > 0 && *readbytes > dlen) { + BIOerr(BIO_F_BIO_READ_INTERN, ERR_R_INTERNAL_ERROR); + return -1; + } return ret; } -int BIO_read(BIO *b, void *out, int outl) +int BIO_read(BIO *b, void *data, int dlen) { - size_t read; + size_t readbytes; int ret; - if (outl < 0) + if (dlen < 0) return 0; - ret = bio_read_intern(b, out, (size_t)outl, &read); + ret = bio_read_intern(b, data, (size_t)dlen, &readbytes); if (ret > 0) { - /* *read should always be <= outl */ - ret = (int)read; + /* *readbytes should always be <= dlen */ + ret = (int)readbytes; } return ret; } -int BIO_read_ex(BIO *b, void *out, size_t outl, size_t *read) +int BIO_read_ex(BIO *b, void *data, size_t dlen, size_t *readbytes) { int ret; - ret = bio_read_intern(b, out, outl, read); + ret = bio_read_intern(b, data, dlen, readbytes); if (ret > 0) ret = 1; @@ -313,7 +317,8 @@ int BIO_read_ex(BIO *b, void *out, size_t outl, size_t *read) return ret; } -static int bio_write_intern(BIO *b, const void *in, size_t inl, size_t *written) +static int bio_write_intern(BIO *b, const void *data, size_t dlen, + size_t *written) { int ret; @@ -321,55 +326,55 @@ static int bio_write_intern(BIO *b, const void *in, size_t inl, size_t *written) return 0; if ((b->method == NULL) || (b->method->bwrite == NULL)) { - BIOerr(BIO_F_BIO_WRITE_EX, BIO_R_UNSUPPORTED_METHOD); + BIOerr(BIO_F_BIO_WRITE_INTERN, BIO_R_UNSUPPORTED_METHOD); return -2; } if ((b->callback != NULL || b->callback_ex != NULL) && - ((ret = (int)bio_call_callback(b, BIO_CB_WRITE, in, inl, 0, 0L, 1L, - written)) <= 0)) + ((ret = (int)bio_call_callback(b, BIO_CB_WRITE, data, dlen, 0, 0L, 1L, + NULL)) <= 0)) return ret; if (!b->init) { - BIOerr(BIO_F_BIO_WRITE_EX, BIO_R_UNINITIALIZED); + BIOerr(BIO_F_BIO_WRITE_INTERN, BIO_R_UNINITIALIZED); return -2; } - ret = b->method->bwrite(b, in, inl, written); + ret = b->method->bwrite(b, data, dlen, written); if (ret > 0) b->num_write += (uint64_t)*written; if (b->callback != NULL || b->callback_ex != NULL) - ret = (int)bio_call_callback(b, BIO_CB_WRITE | BIO_CB_RETURN, in, inl, - 0, 0L, ret, written); + ret = (int)bio_call_callback(b, BIO_CB_WRITE | BIO_CB_RETURN, data, + dlen, 0, 0L, ret, written); return ret; } -int BIO_write(BIO *b, const void *in, int inl) +int BIO_write(BIO *b, const void *data, int dlen) { size_t written; int ret; - if (inl < 0) + if (dlen < 0) return 0; - ret = bio_write_intern(b, in, (size_t)inl, &written); + ret = bio_write_intern(b, data, (size_t)dlen, &written); if (ret > 0) { - /* *written should always be <= inl */ + /* *written should always be <= dlen */ ret = (int)written; } return ret; } -int BIO_write_ex(BIO *b, const void *in, size_t inl, size_t *written) +int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written) { int ret; - ret = bio_write_intern(b, in, inl, written); + ret = bio_write_intern(b, data, dlen, written); if (ret > 0) ret = 1; @@ -379,7 +384,7 @@ int BIO_write_ex(BIO *b, const void *in, size_t inl, size_t *written) return ret; } -int BIO_puts(BIO *b, const char *in) +int BIO_puts(BIO *b, const char *buf) { int ret; size_t written = 0; @@ -390,7 +395,7 @@ int BIO_puts(BIO *b, const char *in) } if (b->callback != NULL || b->callback_ex != NULL) { - ret = (int)bio_call_callback(b, BIO_CB_PUTS, in, 0, 0, 0L, 1L, NULL); + ret = (int)bio_call_callback(b, BIO_CB_PUTS, buf, 0, 0, 0L, 1L, NULL); if (ret <= 0) return ret; } @@ -400,7 +405,7 @@ int BIO_puts(BIO *b, const char *in) return -2; } - ret = b->method->bputs(b, in); + ret = b->method->bputs(b, buf); if (ret > 0) { b->num_write += (uint64_t)ret; @@ -409,56 +414,64 @@ int BIO_puts(BIO *b, const char *in) } if (b->callback != NULL || b->callback_ex != NULL) - ret = (int)bio_call_callback(b, BIO_CB_PUTS | BIO_CB_RETURN, in, 0, 0, + ret = (int)bio_call_callback(b, BIO_CB_PUTS | BIO_CB_RETURN, buf, 0, 0, 0L, ret, &written); if (ret > 0) { - if (written > INT_MAX) + if (written > INT_MAX) { + BIOerr(BIO_F_BIO_PUTS, BIO_R_LENGTH_TOO_LONG); ret = -1; - else + } else { ret = (int)written; + } } return ret; } -int BIO_gets(BIO *b, char *out, int outl) +int BIO_gets(BIO *b, char *buf, int size) { int ret; - size_t read = 0; + size_t readbytes = 0; if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) { BIOerr(BIO_F_BIO_GETS, BIO_R_UNSUPPORTED_METHOD); - return (-2); + return -2; + } + + if (size < 0) { + BIOerr(BIO_F_BIO_GETS, BIO_R_INVALID_ARGUMENT); + return 0; } if (b->callback != NULL || b->callback_ex != NULL) { - ret = (int)bio_call_callback(b, BIO_CB_GETS, out, outl, 0, 0L, 1, NULL); + ret = (int)bio_call_callback(b, BIO_CB_GETS, buf, size, 0, 0L, 1, NULL); if (ret <= 0) return ret; } if (!b->init) { BIOerr(BIO_F_BIO_GETS, BIO_R_UNINITIALIZED); - return (-2); + return -2; } - ret = b->method->bgets(b, out, outl); + ret = b->method->bgets(b, buf, size); if (ret > 0) { - read = ret; + readbytes = ret; ret = 1; } if (b->callback != NULL || b->callback_ex != NULL) - ret = (int)bio_call_callback(b, BIO_CB_GETS | BIO_CB_RETURN, out, outl, - 0, 0L, ret, &read); + ret = (int)bio_call_callback(b, BIO_CB_GETS | BIO_CB_RETURN, buf, size, + 0, 0L, ret, &readbytes); if (ret > 0) { - if (read > INT_MAX) + /* Shouldn't happen */ + if (readbytes > (size_t)size) ret = -1; else - ret = (int)read; + ret = (int)readbytes; } return ret; @@ -481,7 +494,7 @@ long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) int i; i = iarg; - return (BIO_ctrl(b, cmd, larg, (char *)&i)); + return BIO_ctrl(b, cmd, larg, (char *)&i); } void *BIO_ptr_ctrl(BIO *b, int cmd, long larg) @@ -489,9 +502,9 @@ void *BIO_ptr_ctrl(BIO *b, int cmd, long larg) void *p = NULL; if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0) - return (NULL); + return NULL; else - return (p); + return p; } long BIO_ctrl(BIO *b, int cmd, long larg, void *parg) @@ -521,18 +534,17 @@ long BIO_ctrl(BIO *b, int cmd, long larg, void *parg) return ret; } -long BIO_callback_ctrl(BIO *b, int cmd, - void (*fp) (struct bio_st *, int, const char *, int, - long, long)) +long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) { long ret; if (b == NULL) - return (0); + 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); + return -2; } if (b->callback != NULL || b->callback_ex != NULL) { @@ -572,7 +584,7 @@ BIO *BIO_push(BIO *b, BIO *bio) BIO *lb; if (b == NULL) - return (bio); + return bio; lb = b; while (lb->next_bio != NULL) lb = lb->next_bio; @@ -581,7 +593,7 @@ BIO *BIO_push(BIO *b, BIO *bio) bio->prev_bio = lb; /* called to do internal processing */ BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb); - return (b); + return b; } /* Remove the first and return the rest */ @@ -590,7 +602,7 @@ BIO *BIO_pop(BIO *b) BIO *ret; if (b == NULL) - return (NULL); + return NULL; ret = b->next_bio; BIO_ctrl(b, BIO_CTRL_POP, 0, b); @@ -602,7 +614,7 @@ BIO *BIO_pop(BIO *b) b->next_bio = NULL; b->prev_bio = NULL; - return (ret); + return ret; } BIO *BIO_get_retry_BIO(BIO *bio, int *reason) @@ -620,12 +632,12 @@ BIO *BIO_get_retry_BIO(BIO *bio, int *reason) } if (reason != NULL) *reason = last->retry_reason; - return (last); + return last; } int BIO_get_retry_reason(BIO *bio) { - return (bio->retry_reason); + return bio->retry_reason; } void BIO_set_retry_reason(BIO *bio, int reason) @@ -646,13 +658,13 @@ BIO *BIO_find_type(BIO *bio, int type) if (!mask) { if (mt & type) - return (bio); + return bio; } else if (mt == type) - return (bio); + return bio; } bio = bio->next_bio; } while (bio != NULL); - return (NULL); + return NULL; } BIO *BIO_next(BIO *b) @@ -720,11 +732,11 @@ BIO *BIO_dup_chain(BIO *in) eoc = new_bio; } } - return (ret); + return ret; err: BIO_free_all(ret); - return (NULL); + return NULL; } void BIO_copy_next_retry(BIO *b) @@ -735,12 +747,12 @@ void BIO_copy_next_retry(BIO *b) int BIO_set_ex_data(BIO *bio, int idx, void *data) { - return (CRYPTO_set_ex_data(&(bio->ex_data), idx, data)); + return CRYPTO_set_ex_data(&(bio->ex_data), idx, data); } void *BIO_get_ex_data(BIO *bio, int idx) { - return (CRYPTO_get_ex_data(&(bio->ex_data), idx)); + return CRYPTO_get_ex_data(&(bio->ex_data), idx); } uint64_t BIO_number_read(BIO *bio)