performancecopilot/pcp

pmcd segfaults when running with hardened_malloc

hambingen opened this issue · 1 comments

Description of the Issue

Running pmcd with hardened_malloc leads to a crash of the daemon with SIGSEGV. This can be traced back to a buffer overflow when executing the __pmServerAddInterface function within auxserver.c of libpcp that could lead to out-of-bounds writes. Crashes have only been observed when using hardened memory allocators that enforce stricter bounds checking than standard glibc.

Steps to Reproduce the resulting bug

  1. Install any recent version of pcp (tested with GitHub main branch in Fedora 40 and packaged version pcp-6.2.0-3.el9_4 in AlmaLinux 9.4).
  2. Install the hardened_malloc memory allocator library (tested with hardened_malloc-12-9.fc40 from https://copr.fedorainfracloud.org/coprs/secureblue/hardened_malloc/ and hardened_malloc-12-3.el9_2.security from https://sig-security.rocky.page/packages/hardened_malloc).
  3. 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.
  4. 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

Security Implications

This issue could lead to memory corruption or crashes.

Proposed Fix

A fix has been proposed as PR #2067. It adjusts the realloc call to correctly size the allocation for intflist as (nintf + 1) * sizeof(char *).

Closing as fix has been merged.