diff options
author | Maxim Dounin <mdounin@mdounin.ru> | 2017-08-22 17:36:12 +0300 |
---|---|---|
committer | Maxim Dounin <mdounin@mdounin.ru> | 2017-08-22 17:36:12 +0300 |
commit | ed0cc4d52308b75ab217724392994e6828af4fda (patch) | |
tree | 72a91d2bcff58902adcfb7ab344225ec33d6bef5 /src | |
parent | 50a0f25c60bcc0fb46efcab00985c200c08c2b2f (diff) | |
download | nginx-ed0cc4d52308b75ab217724392994e6828af4fda.tar.gz nginx-ed0cc4d52308b75ab217724392994e6828af4fda.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/event/ngx_event_openssl.c | 21 |
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; } |