summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMaxim Dounin <mdounin@mdounin.ru>2017-08-22 17:36:12 +0300
committerMaxim Dounin <mdounin@mdounin.ru>2017-08-22 17:36:12 +0300
commited0cc4d52308b75ab217724392994e6828af4fda (patch)
tree72a91d2bcff58902adcfb7ab344225ec33d6bef5
parent50a0f25c60bcc0fb46efcab00985c200c08c2b2f (diff)
downloadnginx-ed0cc4d52308b75ab217724392994e6828af4fda.tar.gz
nginx-ed0cc4d52308b75ab217724392994e6828af4fda.tar.bz2
SSL: fixed possible use-after-free in $ssl_server_name.
The $ssl_server_name variable used SSL_get_servername() result directly, but this is not safe: it references a memory allocation in an SSL session, and this memory might be freed at any time due to renegotiation. Instead, copy the name to memory allocated from the pool.
-rw-r--r--src/event/ngx_event_openssl.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 4b74cb3f2..88a6dbed3 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -3551,13 +3551,22 @@ ngx_ssl_get_server_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
{
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
- const char *servername;
+ size_t len;
+ const char *name;
+
+ name = SSL_get_servername(c->ssl->connection, TLSEXT_NAMETYPE_host_name);
+
+ if (name) {
+ len = ngx_strlen(name);
+
+ s->len = len;
+ s->data = ngx_pnalloc(pool, len);
+ if (s->data == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(s->data, name, len);
- servername = SSL_get_servername(c->ssl->connection,
- TLSEXT_NAMETYPE_host_name);
- if (servername) {
- s->data = (u_char *) servername;
- s->len = ngx_strlen(servername);
return NGX_OK;
}