summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordoug <>2017-08-13 17:04:36 +0000
committerdoug <>2017-08-13 17:04:36 +0000
commit8c16d5f15ed3162b6b0d316138e55627f4c0d065 (patch)
tree58020dba3858815c3918073a15807166259ae0a0
parent0a020be0d69dd80e383f03983ec82974ac302028 (diff)
downloadopenbsd-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.c48
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
1623SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, 1623SSL_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 */
1640int 1654int
1641SSL_set_alpn_protos(SSL *ssl, const unsigned char* protos, 1655SSL_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/*