Fix heap-use-after-free in IntelCpuSensor::Reinitialize callback lifetime
Concurrent Reinitialize() calls from a control thread could free an in-flight
callback out from under the io_context thread.
The callback was stored as a std::shared_ptr<absl::AnyInvocable> and
Reinitialize() reassigned it directly on the *calling* thread (in production,
SensorCollector::ReinitializeAndScheduleAllSensorsForConfigKey runs on a
different thread than the sensor's io_context). The retry chain reads and
invokes the callback via `std::move(*reinitialize_callback_)` on the io_context
thread without holding its own reference (the signature is not &&-qualified, so
the invocation does not consume the target). A second Reinitialize() reassigning
the member therefore drops the last shared_ptr reference and frees the callback
-- and its captures -- while the io_context thread is still reading/invoking it:
a heap-use-after-free, reproducible under ASAN.
Confine reinitialize_callback_ and attempt_num_ to the io_context thread:
- Store the callback as a plain absl::AnyInvocable (no shared_ptr).
- Reinitialize() posts all state mutation to the io_context thread and
supersedes any active retry chain by cancelling the pending timer and
completing the superseded callback with CancelledError before installing
the new one.
- The success path moves the callback into a local and clears the member
before invoking it, so the end of a chain is well defined.
- Aborted timer waits (operation_aborted) end the chain quietly instead of
invoking a now-superseded callback.
Add a regression test that reproduces the race under real production threading:
a dedicated caller thread hammers Reinitialize() while the sensor's retry chain
runs on the io_context thread. A bounded in-flight window keeps both threads
overlapping without letting the work queue grow unboundedly. The test aborts
with a heap-use-after-free under ASAN on the old implementation and passes with
this fix.
Google-Bug-Id:548033968
PiperOrigin-RevId: 967395453
Change-Id: I3a35abecf73df40b612bfa7c3d99430afa5273db
1 file changed