Description:
mysql_registry_no_lock_imp::register_service_nolock() publishes
imp.get() into service_registry and interface_mapping before ownership
is released.
Relevant sequence:
1. service_registry.emplace(imp->name_c_str(), imp.get())
2. interface_mapping.emplace(imp->interface(), imp.get())
3. service_registry.emplace_hint(addition_result.first,
imp->service_name_c_str(), imp.get())
If step 3 throws, the catch only erases the first service_registry
entry. The unique_ptr then destroys mysql_service_implementation, but
interface_mapping still contains the freed pointer.
The stale pointer can later be dereferenced during component unload:
dynamic_loader.cc:1338 calls
mysql_registry_imp::get_service_implementation_reference_count(...)
which reaches registry_no_lock.cc:82:
return iter->second->get_reference_count();
How to repeat:
I do not currently have a deterministic in-tree trigger without
allocation fault injection. The realistic throw point is std::bad_alloc
during the second service_registry insertion.
Suggested fix:
Either delay interface_mapping publication until all service_registry
insertions succeed, or roll back the interface_mapping entry in the
catch path before imp is destroyed.
Description: mysql_registry_no_lock_imp::register_service_nolock() publishes imp.get() into service_registry and interface_mapping before ownership is released. Relevant sequence: 1. service_registry.emplace(imp->name_c_str(), imp.get()) 2. interface_mapping.emplace(imp->interface(), imp.get()) 3. service_registry.emplace_hint(addition_result.first, imp->service_name_c_str(), imp.get()) If step 3 throws, the catch only erases the first service_registry entry. The unique_ptr then destroys mysql_service_implementation, but interface_mapping still contains the freed pointer. The stale pointer can later be dereferenced during component unload: dynamic_loader.cc:1338 calls mysql_registry_imp::get_service_implementation_reference_count(...) which reaches registry_no_lock.cc:82: return iter->second->get_reference_count(); How to repeat: I do not currently have a deterministic in-tree trigger without allocation fault injection. The realistic throw point is std::bad_alloc during the second service_registry insertion. Suggested fix: Either delay interface_mapping publication until all service_registry insertions succeed, or roll back the interface_mapping entry in the catch path before imp is destroyed.