[Vulnerability Report] phosphor-logging / openpower-pels: Arbitrary File Read and Deletion via RAWPEL Path Injection

Bhargava Naidu Gulla <[email protected]> Tue, 2 Jun 2026 15:57:17 -0700
Newsgroups org.ozlabs.lists.openbmc
Message-ID <CAEPZvmNngpE6P2Mje7_Kj18wXVzuMX7SA4wPwDGbwsmh=PgVNQ@mail.gmail.com>
Hi OpenBMC Security Team,

I would like to report a critical vulnerability inside the Platform Event
Log (PEL) Manager component of the openpower-pels extension.

Overview of the Vulnerability:
An unprivileged local user or D-Bus client can read and permanently delete
arbitrary files on the BMC filesystem. Because the phosphor-logging daemon
runs with elevated (root) privileges, an attacker can exploit this to
delete critical system configurations, resulting in a system-wide Denial of
Service (DoS) or privilege escalation. Furthermore, sensitive file contents
can be leaked to accessible diagnostic logs if the file is not a valid PEL
format.

Affected File and Location:
File: extensions/openpower-pels/manager.cpp
Lines: 82 & 127

Root Cause:
The `Manager::create` D-Bus interface parses a `RAWPEL` value from the
user-supplied `AdditionalData` dictionary. This value is directly treated
as an absolute file path `rawPelPath` and passed to `Manager::addRawPEL`
without any path sanitization, sandboxing, or directory traversal checks.

The daemon immediately:
1. Performs an `std::filesystem::exists` check.
2. Opens the file using `std::ifstream`.
3. Irrevocably deletes the targeted file using `std::filesystem::remove`.

If the read file content is not a formally valid PEL structure, the parser
dumps the read contents verbatim into the internal `badPEL` diagnostic file
(/var/lib/phosphor-logging/extensions/pels/badPEL) which is world-readable.

Proof of Concept:
1. Execute the `Create` method on the Logging interface via D-Bus:
   busctl call xyz.openbmc_project.Logging /xyz/openbmc_project/logging
xyz.openbmc_project.Logging.Create Create ssa{ss} 'message' 'severity' 1
'RAWPEL' '/etc/shadow'
2. The daemon immediately reads the contents of `/etc/shadow` and deletes
it from the filesystem.
3. Because `/etc/shadow` is not a valid PEL, the daemon copies its read
bytes directly to `/var/lib/phosphor-logging/extensions/pels/badPEL` for
diagnostics, leaking the shadow file contents to local users.

Proposed Patch:
Validate that the incoming path resides strictly inside an allowlisted
temporary staging directory, and sanitize it against directory traversal:

void Manager::addRawPEL(const std::string& rawPelPath, uint32_t obmcLogID)
{
    std::filesystem::path inputPath(rawPelPath);
    // Restrict the path resolution strictly inside a secure, designated
folder
    std::filesystem::path sandboxedPath =
std::filesystem::path("/tmp/pels") / inputPath.filename();

    if (std::filesystem::exists(sandboxedPath))
    {
        std::ifstream file(sandboxedPath, std::ios::in | std::ios::binary);
        // ...
        std::error_code ec;
        std::filesystem::remove(sandboxedPath, ec);
    }
}

Legal Name for Attribution: Bhargava Naidu Gulla