Description
Summary
During memcached shutdown the settings object fields ssl_cipher_list and ssl_minimum_protocol can have free() called on them when they have already been free'd, if the memcached.json configuration file was dynamically re-loaded at some point.
The exact behaviour of this depends on environmental factors; it might have no effect, it it might trigger an invalid memory access and crash the memcached process.
Assuming it did manifest as a crash, given the process is in the process of shutting down anyway; the only consequence of this is a crash logged in dmesg; and ns_server seeing it as an unclean shutdown instead of clean.
Details
Backtrace of double-free (as reported by Valgrind):
Releasing callbacks
|
Releasing settings
|
==1574== Invalid free() / delete / delete[] / realloc()
|
==1574== at 0x4C2AD1D: free (vg_replace_malloc.c:530)
|
==1574== by 0x42B664: free_settings(settings*) (config_parse.cc:1760)
|
==1574== by 0x416C01: memcached_main (memcached.cc:2710)
|
==1574== by 0x7A9DC04: (below main) (in /usr/lib64/libc-2.17.so)
|
==1574== Address 0xbcd3ea0 is 0 bytes inside a block of size 5 free'd
|
==1574== at 0x4C2AD1D: free (vg_replace_malloc.c:530)
|
==1574== by 0x42B664: free_settings(settings*) (config_parse.cc:1760)
|
==1574== by 0x42B983: reload_config_file() (config_parse.cc:1737)
|
==1574== by 0x43C068: config_reload_executor(McbpConnection*, void*) (mcbp_executors.cc:4138)
|
==1574== by 0x442B25: process_bin_packet (mcbp_executors.cc:4657)
|
==1574== by 0x442B25: mcbp_complete_nread(McbpConnection*) (mcbp_executors.cc:4766)
|
==1574== by 0x44A4AE: conn_nread(McbpConnection*) (statemachine_mcbp.cc:316)
|
==1574== by 0x430E77: execute (statemachine_mcbp.h:43)
|
==1574== by 0x430E77: McbpConnection::runStateMachinery() (connection_mcbp.cc:1031)
|
==1574== by 0x430EBA: McbpConnection::runEventLoop(short) (connection_mcbp.cc:1307)
|
==1574== by 0x43471F: run_event_loop (connections.cc:148)
|
==1574== by 0x411F66: event_handler(int, short, void*) (memcached.cc:848)
|
==1574== by 0x66E54D7: event_persist_closure (event.c:1319)
|
==1574== by 0x66E54D7: event_process_active_single_queue (event.c:1363)
|
==1574== by 0x66E54D7: event_process_active (event.c:1438)
|
==1574== by 0x66E54D7: event_base_loop (event.c:1639)
|
==1574== by 0x420643: worker_libevent(void*) (thread.cc:232)
|
==1574== Block was alloc'd at
|
==1574== at 0x4C29C23: malloc (vg_replace_malloc.c:299)
|
==1574== by 0x5CA073D: cb_malloc (cb_malloc.cc:57)
|
==1574== by 0x5CA0789: cb_strdup (cb_malloc.cc:82)
|
==1574== by 0x42A1AB: get_string_value (config_parse.cc:188)
|
==1574== by 0x42A1AB: get_ssl_cipher_list(cJSON*, settings*, char**) (config_parse.cc:339)
|
==1574== by 0x42B8FC: parse_JSON_config (config_parse.cc:1619)
|
==1574== by 0x42B8FC: parse_config_file (config_parse.cc:1651)
|
==1574== by 0x42B8FC: reload_config_file() (config_parse.cc:1706)
|
==1574== by 0x43C068: config_reload_executor(McbpConnection*, void*) (mcbp_executors.cc:4138)
|
==1574== by 0x442B25: process_bin_packet (mcbp_executors.cc:4657)
|
==1574== by 0x442B25: mcbp_complete_nread(McbpConnection*) (mcbp_executors.cc:4766)
|
==1574== by 0x44A4AE: conn_nread(McbpConnection*) (statemachine_mcbp.cc:316)
|
==1574== by 0x430E77: execute (statemachine_mcbp.h:43)
|
==1574== by 0x430E77: McbpConnection::runStateMachinery() (connection_mcbp.cc:1031)
|
==1574== by 0x430EBA: McbpConnection::runEventLoop(short) (connection_mcbp.cc:1307)
|
==1574== by 0x43471F: run_event_loop (connections.cc:148)
|
==1574== by 0x411F66: event_handler(int, short, void*) (memcached.cc:848)
|
==1574==
|
Note that only versions prior to 5.0.0 are affected by this; the settings management code was refactored in 5.0.0 (http://review.couchbase.org/64898) which effectively fixed this bug.