The per-worker ticket key mirror is allocated with three slots
(ngx_array_push_n(keys, 3)), matching the shared memory
ticket_keys[3] array and the decrypt callback, which scans all
keys->nelts slots by key name. Key rotation, however, synced
only two slots from shared memory, leaving the third slot's
name, hmac_key, and aes_key uninitialized.
A ticket whose key name matched the uninitialized slot (which
holds unspecified pool memory, all zero in the best case) could
therefore be HMAC-verified and decrypted with uninitialized key
material, allowing a forged session.
Sync all keys->nelts slots, as ngx_ssl_ticket_keys_cleanup()
already assumes.
Reported by PhiNode Labs.
/* sync keys to the worker process memory */
ngx_memcpy(keys->elts, cache->ticket_keys,
- 2 * sizeof(ngx_ssl_ticket_key_t));
+ keys->nelts * sizeof(ngx_ssl_ticket_key_t));
ngx_shmtx_unlock(&shpool->mutex);