-
Bug
-
Resolution: Unresolved
-
Minor
-
rhel-9.6
-
None
-
pcp-6.3.1-1.el9
-
No
-
Low
-
1
-
rhel-sst-pt-pcp
-
21
-
1
-
QE ack, Dev ack
-
False
-
-
No
-
PCP Sprint 11
-
Pass
-
Automated
-
x86_64
-
None
What were you trying to do that didn't work?
Run PCP, in particular pmcd.service with a hardened malloc API: https://sig-security.rocky.page/packages/hardened_malloc/
This bug arises from an incorrect memory allocation size when expanding the an array, leading to potential out-of-bounds writes. It has been reported to the upstream PCP maintainers.
What is the impact of this issue to you?
The pmcd.service fails with SIGSEV and doesn't recover, even after a reboot. This has a potential security impact.
This issue could lead to memory corruption, crashes, or potentially more severe exploits if the conditions allow for an attacker to control inputs. Given the nature of buffer overflows, this warrants careful handling and patching.
Please provide the package NVR for which the bug is seen:
pcp-6.2.0-3.el9_4.x86-64
How reproducible is this bug?:
see below.
Steps to reproduce
- Install pcp (tested packaged version pcp-6.2.0-3.el9_4.x86-64).
- Install the hardened_malloc memory allocator library (tested with hardened_malloc-12-3.el9_2.security from https://sig-security.rocky.page/packages/hardened_malloc).
- Run pmcd with hardened_malloc: edit /usr/lib/systemd/system/pmcd.service to state `Environment="LD_PRELOAD=/usr/lib64/libhardened_malloc.so”` under `[Service]`, execute 'systemctl daemon-reload' and 'systemctl restart pmcd.service'.
Expected results
pmcd.service starts.
Actual results
Notice pmcd crashing with the following messages:
systemd[1]: Starting Performance Metrics Collector Daemon…
systemd-coredump[2142]: [] Process 2140 (pmcd) of user 0 dumped core.
pmcd[2075]: /usr/libexec/pcp/lib/pmcd: line 548: 2140 Segmentation fault (core dumped) $PMCD $OPTS
root[2256]: pmcd_wait failed in /usr/libexec/pcp/lib/pmcd: exit status: 2
systemd[1]: pmcd.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
systemd[1]: pmcd.service: Failed with result 'exit-code’.
systemd[1]: Failed to start Performance Metrics Collector Daemon.
By running 'coredumpctl debug’ this can be traced back to the offending function:
Core was generated by `/usr/libexec/pcp/bin/pmcd -A'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00007f018f16a514 in __pmServerAddInterface (address=0x55cc4384c56a "INADDR_LOOPBACK")
at /usr/src/debug/pcp-6.2.0-3.el9_4.x86_64/src/libpcp/src/auxserver.c:251
251 intflist[nintf++] = intf;
(gdb) bt
#0 0x00007f018f16a514 in __pmServerAddInterface (address=0x55cc4384c56a "INADDR_LOOPBACK")
at /usr/src/debug/pcp-6.2.0-3.el9_4.x86_64/src/libpcp/src/auxserver.c:251
#1 0x000055cc4383b7f8 in main (argc=2, argv=0x7ffccaf45858) at /usr/src/debug/pcp-6.2.0-3.el9_4.x86_64/src/pmcd/src/pmcd.c:1051
An analysis of the source code lead to the following conclusion:
The `realloc` function is currently called with `nintf * sizeof(char *)` rather than `(nintf + 1) * sizeof(char *)`. This miscalculation can result in accessing memory beyond the allocated region, causing segmentation faults, especially when using hardened memory allocators like hardened_malloc. While this does not immediately crash with standard glibc, it remains a latent security risk.
Potential fix
I have prepared a patch that corrects the allocation size in the `__pmServerAddInterface` function and have tested it with both standard glibc and hardened_malloc memory allocators. The patch resolves the segmentation faults and ensures safe memory handling by using the previously assigned but unused variable `size`:
diff --git a/src/libpcp/src/auxserver.c b/src/libpcp/src/auxserver.c
index b008a6627..f42b5e4ec 100644
— a/src/libpcp/src/auxserver.c
+++ b/src/libpcp/src/auxserver.c
@@ -243,7 +243,7 @@ __pmServerAddInterface(const char *address)
char *intf;
/* one (of possibly several) IP addresses for client requests */
- intflist = (char **)realloc(intflist, nintf * sizeof(char *));
+ intflist = (char **)realloc(intflist, size);
if (intflist == NULL)
pmNoMem("AddInterface: cannot grow interface list", size, PM_FATAL_ERR);
if ((intf = strdup(address)) == NULL)
This patch has been proposed to the upstream maintainers of PCP.
- is related to
-
RHEL-61501 pmlogextract fails to correctly read V3 archives on s390x architecture
- Integration
- links to
-
RHBA-2024:139624 pcp update