--- libressl-2.7.4.orig/tls/tls_bio_cb.c +++ libressl-2.7.4/tls/tls_bio_cb.c @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -29,19 +30,36 @@ static int bio_cb_puts(BIO *bio, const char *str); static long bio_cb_ctrl(BIO *bio, int cmd, long num, void *ptr); -static BIO_METHOD bio_cb_method = { - .type = BIO_TYPE_MEM, - .name = "libtls_callbacks", - .bwrite = bio_cb_write, - .bread = bio_cb_read, - .bputs = bio_cb_puts, - .ctrl = bio_cb_ctrl, -}; +static pthread_once_t bio_cb_init_once = PTHREAD_ONCE_INIT; +static BIO_METHOD *bio_cb_method = NULL; + +static void +bio_s_cb_init(void) +{ + BIO_METHOD *method; + + method = BIO_meth_new(BIO_TYPE_MEM, "libtls_callbacks"); + assert(method != NULL); + + BIO_meth_set_read(method, bio_cb_read); + BIO_meth_set_write(method, bio_cb_write); + BIO_meth_set_puts(method, bio_cb_puts); + BIO_meth_set_ctrl(method, bio_cb_ctrl); + + bio_cb_method = method; +} + static BIO_METHOD * bio_s_cb(void) { - return (&bio_cb_method); + if (bio_cb_method != NULL) { + return bio_cb_method; + } + + (void) pthread_once(&bio_cb_init_once, bio_s_cb_init); + + return bio_cb_method; } static int @@ -57,10 +75,10 @@ switch (cmd) { case BIO_CTRL_GET_CLOSE: - ret = (long)bio->shutdown; + ret = (long) BIO_get_shutdown(bio); break; case BIO_CTRL_SET_CLOSE: - bio->shutdown = (int)num; + BIO_set_shutdown(bio, (int) num); break; case BIO_CTRL_DUP: case BIO_CTRL_FLUSH: @@ -69,7 +87,7 @@ case BIO_CTRL_GET: case BIO_CTRL_SET: default: - ret = BIO_ctrl(bio->next_bio, cmd, num, ptr); + ret = BIO_ctrl(BIO_next(bio), cmd, num, ptr); } return (ret); @@ -78,7 +96,7 @@ static int bio_cb_write(BIO *bio, const char *buf, int num) { - struct tls *ctx = bio->ptr; + struct tls *ctx = BIO_get_data(bio); int rv; BIO_clear_retry_flags(bio); @@ -96,7 +114,7 @@ static int bio_cb_read(BIO *bio, char *buf, int size) { - struct tls *ctx = bio->ptr; + struct tls *ctx = BIO_get_data(bio); int rv; BIO_clear_retry_flags(bio); @@ -131,8 +149,8 @@ tls_set_errorx(ctx, "failed to create callback i/o"); goto err; } - bio->ptr = ctx; - bio->init = 1; + BIO_set_data(bio, ctx); + BIO_set_init(bio, 1); SSL_set_bio(ctx->ssl_conn, bio, bio);