Re: [Vulnerability Report] phosphor-logging / openpower-pels: Silent Log Task Dropping due to Timer Overlaps in HostNotifier

Andrew Jeffery <[email protected]> Wed, 03 Jun 2026 09:35:32 +0930
Newsgroups org.ozlabs.lists.openbmc
Message-ID <29fcface8daf3e542bdae518bbbe3ef2eb83c9c7.camel@codeconstruct.com.au>
Hi Bhargava,

In the future, security vulnerability reports should be sent to:

   [email protected]

as per:

   https://github.com/openbmc/docs/blob/master/security/how-to-report-a-security-vulnerability.md

Andrew

On Tue, 2026-06-02 at 16:06 -0700, Bhargava Naidu Gulla wrote:
> 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