[Vulnerability Report] phosphor-logging / openpower-pels: Silent Log Task Dropping due to Timer Overlaps in HostNotifier
Bhargava Naidu Gulla <[email protected]> Tue, 2 Jun 2026 16:06:00 -0700
| Newsgroups | org.ozlabs.lists.openbmc |
|---|---|
| Message-ID | <CAEPZvmNu--4-Fm0Kq1SVkkNByOB3SDR3MxRQ9Y1w4j28gUBAcg@mail.gmail.com> |
Hi OpenBMC Security Team,
I would like to report a race condition and state corruption vulnerability
inside the Host Notifier state machine of the openpower-pels extension.
Overview of the Vulnerability:
Rapid, concurrent, or noisy host state transitions can corrupt in-flight
task tracking for Platform Event Log (PEL) notifications. This results in
event log notifications being silently dropped, preventing critical system
error logs from being delivered to the host operating system.
Affected File and Location:
File: extensions/openpower-pels/host_notifier.cpp
Line: 234
Root Cause:
The `hostStateChange(true)` method arms the `_hostUpTimer` but does not
disable or cancel already active timers (such as `_retryTimer` or
`_hostFullTimer`).
When the first timer expires, it invokes `doNewLogNotify()`, which launches
an asynchronous PLDM file transmission task and sets the tracking variable:
_inProgressPEL = pelID;
Because `doNewLogNotify()` lacks a command-in-progress guard check
(`_inProgressPEL != 0`), if the concurrent overlapping second timer expires
before the first PLDM command's asynchronous response is received, it
blindly executes `doNewLogNotify()` again. This second execution sends
another PLDM command and overwrites `_inProgressPEL` with a new ID. The
tracking for the first PEL is permanently dropped, and subsequent status
responses are mismatched.
Proof of Concept:
1. Force the HostNotifier into a retry state where the `_retryTimer` is
currently armed due to a full or blocked state.
2. Rapidly trigger a D-Bus host state property change, invoking
`hostStateChange(true)`. This arms `_hostUpTimer` in parallel.
3. The `_retryTimer` expires first, starting a PLDM send task for PEL ID A
and setting `_inProgressPEL = A`.
4. The `_hostUpTimer` expires next before the D-Bus/PLDM response for PEL A
returns, and fires `doNewLogNotify()` again, sending a task for PEL ID B
and overwriting `_inProgressPEL = B`.
5. Observe that tracking for PEL ID A is dropped from the queue and
permanently orphaned.
Proposed Patch:
Add an active command guard check at the beginning of
`HostNotifier::doNewLogNotify()`:
if (_inProgressPEL != 0 || _hostIface->cmdInProgress())
{
return;
}
Legal Name for Attribution: Bhargava Naidu Gulla