diff options
author | doug <> | 2017-08-13 17:04:36 +0000 |
---|---|---|
committer | doug <> | 2017-08-13 17:04:36 +0000 |
commit | 8c16d5f15ed3162b6b0d316138e55627f4c0d065 (patch) | |
tree | 58020dba3858815c3918073a15807166259ae0a0 | |
parent | 0a020be0d69dd80e383f03983ec82974ac302028 (diff) | |
download | openbsd-8c16d5f15ed3162b6b0d316138e55627f4c0d065.tar.gz openbsd-8c16d5f15ed3162b6b0d316138e55627f4c0d065.tar.bz2 openbsd-8c16d5f15ed3162b6b0d316138e55627f4c0d065.zip |
Make SSL{,_CTX}_set_alpn_protos() do atomic updates and handle NULL.
Previously, the code would accept NULL and 0 length and try to
malloc/memcpy it. On OpenBSD, malloc(0) does not return NULL. It could
also fail in malloc and leave the old length.
Also, add a note that this public API has backwards semantics of what you
would expect where 0 is success and 1 is failure.
input + ok jsing@ beck@
-rw-r--r-- | src/lib/libssl/ssl_lib.c | 48 |
1 files changed, 38 insertions, 10 deletions
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c index 32a5680db7..46d905ad56 100644 --- a/src/lib/libssl/ssl_lib.c +++ b/src/lib/libssl/ssl_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_lib.c,v 1.167 2017/08/12 21:03:08 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_lib.c,v 1.168 2017/08/13 17:04:36 doug Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -1623,13 +1623,27 @@ int | |||
1623 | SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, | 1623 | SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, |
1624 | unsigned int protos_len) | 1624 | unsigned int protos_len) |
1625 | { | 1625 | { |
1626 | int failed = 1; | ||
1627 | |||
1628 | if (protos == NULL || protos_len == 0) | ||
1629 | goto err; | ||
1630 | |||
1626 | free(ctx->internal->alpn_client_proto_list); | 1631 | free(ctx->internal->alpn_client_proto_list); |
1627 | if ((ctx->internal->alpn_client_proto_list = malloc(protos_len)) == NULL) | 1632 | ctx->internal->alpn_client_proto_list = NULL; |
1628 | return (1); | 1633 | ctx->internal->alpn_client_proto_list_len = 0; |
1629 | memcpy(ctx->internal->alpn_client_proto_list, protos, protos_len); | 1634 | |
1635 | if ((ctx->internal->alpn_client_proto_list = malloc(protos_len)) | ||
1636 | == NULL) | ||
1637 | goto err; | ||
1630 | ctx->internal->alpn_client_proto_list_len = protos_len; | 1638 | ctx->internal->alpn_client_proto_list_len = protos_len; |
1631 | 1639 | ||
1632 | return (0); | 1640 | memcpy(ctx->internal->alpn_client_proto_list, protos, protos_len); |
1641 | |||
1642 | failed = 0; | ||
1643 | |||
1644 | err: | ||
1645 | /* NOTE: Return values are the reverse of what you expect. */ | ||
1646 | return (failed); | ||
1633 | } | 1647 | } |
1634 | 1648 | ||
1635 | /* | 1649 | /* |
@@ -1638,16 +1652,30 @@ SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, | |||
1638 | * 8-bit length-prefixed strings). Returns 0 on success. | 1652 | * 8-bit length-prefixed strings). Returns 0 on success. |
1639 | */ | 1653 | */ |
1640 | int | 1654 | int |
1641 | SSL_set_alpn_protos(SSL *ssl, const unsigned char* protos, | 1655 | SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, |
1642 | unsigned int protos_len) | 1656 | unsigned int protos_len) |
1643 | { | 1657 | { |
1658 | int failed = 1; | ||
1659 | |||
1660 | if (protos == NULL || protos_len == 0) | ||
1661 | goto err; | ||
1662 | |||
1644 | free(ssl->internal->alpn_client_proto_list); | 1663 | free(ssl->internal->alpn_client_proto_list); |
1645 | if ((ssl->internal->alpn_client_proto_list = malloc(protos_len)) == NULL) | 1664 | ssl->internal->alpn_client_proto_list = NULL; |
1646 | return (1); | 1665 | ssl->internal->alpn_client_proto_list_len = 0; |
1647 | memcpy(ssl->internal->alpn_client_proto_list, protos, protos_len); | 1666 | |
1667 | if ((ssl->internal->alpn_client_proto_list = malloc(protos_len)) | ||
1668 | == NULL) | ||
1669 | goto err; | ||
1648 | ssl->internal->alpn_client_proto_list_len = protos_len; | 1670 | ssl->internal->alpn_client_proto_list_len = protos_len; |
1649 | 1671 | ||
1650 | return (0); | 1672 | memcpy(ssl->internal->alpn_client_proto_list, protos, protos_len); |
1673 | |||
1674 | failed = 0; | ||
1675 | |||
1676 | err: | ||
1677 | /* NOTE: Return values are the reverse of what you expect. */ | ||
1678 | return (failed); | ||
1651 | } | 1679 | } |
1652 | 1680 | ||
1653 | /* | 1681 | /* |