[Vulnerability Report] phosphor-logging / openpower-pels: Heap Buffer Overflow in dumpHex due to Signed Integer Overflow
Bhargava Naidu Gulla <[email protected]> Tue, 2 Jun 2026 16:00:33 -0700
| Newsgroups | org.ozlabs.lists.openbmc |
|---|---|
| Message-ID | <CAEPZvmNY6svndXqFsF9fPm9HTkofeaJqL0FkKhDpmUYcZtEERA@mail.gmail.com> |
Hi OpenBMC Security Team,
I would like to report a heap buffer overflow vulnerability inside the
Platform Event Log (PEL) formatting utilities of the openpower-pels
extension.
Overview of the Vulnerability:
A malformed or exceptionally large log payload can trigger an integer
overflow in the parser's heap buffer size calculation, leading to an
insufficiently small heap allocation. The subsequent string formatting loop
then writes outside the buffer boundaries, causing heap memory corruption.
This can be exploited to crash the logging daemon (Denial of Service) or
potentially achieve arbitrary code execution.
Affected File and Location:
File: extensions/openpower-pels/json_utils.cpp
Line: 73
Root Cause:
The `dumpHex` utility allocates a dynamic buffer to format binary data into
hexadecimal string outputs:
std::unique_ptr<char[]> buffer{new char[std::max(70, 10 * (int)size)]()};
The function explicitly casts the unsigned `size_t size` parameter to a
signed 32-bit `int` before multiplying it by 10. If a large event payload
size is provided, the multiplication overflows the signed `int` limits and
wraps around into a negative or extremely small integer.
The `std::max` function evaluates this negative value and falls back to its
floor allocation of 70 bytes. However, the subsequent loop that
concatenates the hexadecimal symbols continues to run up to the *original*
un-truncated `size` using `strcat`, resulting in an out-of-bounds write
that corrupts adjacent heap memory.
Proof of Concept:
1. Submit an event log containing binary payload data whose size exceeds
`(INT_MAX / 10)` (approx 214 MB) to a utility that processes binary dumps
via `dumpHex`.
2. The signed integer casts wrap around during multiplication, allocating
only 70 bytes on the heap.
3. The formatting loop sequentially copies the hex output using `strcat` up
to the full 214 MB limit, corrupting the heap and crashing the process.
Proposed Patch:
Remove the explicit `(int)` cast and use safe unsigned `size_t` variables
for calculations:
std::unique_ptr<char[]> buffer{new char[std::max(static_cast<size_t>(70),
10 * size)]()};
Legal Name for Attribution: Bhargava Naidu Gulla