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 | |
| parent | 50a0f25c60bcc0fb46efcab00985c200c08c2b2f (diff) | |
| download | nginx-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.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; } |
