pcp/pcp-6.3.7-OOB-pmLogLoadLabelSet.patch
Jan Kurik d6aade7578
Backport PCP security CVE fixes and hardening for 6.3.7-11
Backport applicable private-pcp security fixes to PCP 6.3.7 for RHEL 9.9.
CVE-2026-16531 is not applicable because the pmproxy logger servlet is
absent in this release.

Resolves: RHEL-213747 CVE-2026-16530
Resolves: RHEL-213736 CVE-2026-16529
Resolves: RHEL-213711 CVE-2026-16527
Resolves: RHEL-213687 CVE-2026-16526
Resolves: RHEL-213658 CVE-2026-16524
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-13 08:10:41 +02:00

65 lines
2.4 KiB
Diff

From ccd1bb1679 Mon Sep 17 00:00:00 2001
From: Nathan Scott <nathans@redhat.com>
Subject: [PATCH] libpcp: fix OOB read in __pmLogLoadLabelSet (CWE-125)
__pmLogLoadLabelSet() reads timestamp, type, ident, and nsets fields
from tbuf at sequential offsets without checking that rlen is large
enough to contain them. When the pmproxy logger servlet delivers a
TYPE_LABEL record with hdr.len=13 (minimum accepted by the dispatcher),
rlen=1 and the function reads 20-24 bytes from a 1-byte buffer.
Fix: add minimum-length guard at the top of __pmLogLoadLabelSet()
using LABELSET_V3_MINRLEN / LABELSET_V2_MINRLEN macros derived from
the on-disk __pmExtLabelSet_v3/v2 struct sizes (minus the len+type
header that rlen excludes).
Test coverage will be added in a consolidated pducrash.c extension
covering vulns 9-13.
Reported-by: Francisco Alisson Bezerra, TIM Security Red Team
Reported-by: Lucas Gabriel Alves, TIM Security Red Team
Reported-by: Massimiliano Brolli, TIM Security Red Team
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---
diff --git a/src/libpcp/src/e_labels.c b/src/libpcp/src/e_labels.c
index 8e94a112b0..169817266b 100644
--- a/src/libpcp/src/e_labels.c
+++ b/src/libpcp/src/e_labels.c
@@ -56,6 +56,10 @@ typedef struct {
/* will be expanded if nsets > 0 */
} __pmExtLabelSet_v2;
+/* Minimum rlen (record body without len+type header) to read fixed fields */
+#define LABELSET_V3_MINRLEN (sizeof(__pmExtLabelSet_v3) - 2 * sizeof(__int32_t))
+#define LABELSET_V2_MINRLEN (sizeof(__pmExtLabelSet_v2) - 2 * sizeof(__int32_t))
+
/*
* pack a set of labels into a physical metadata record
* - lcp required to provide archive version
@@ -215,6 +219,23 @@ __pmLogLoadLabelSet(char *tbuf, int rlen, int rtype, __pmTimestamp *stamp,
*nsetsp = 0;
*labelsetsp = NULL;
+ if (rtype == TYPE_LABEL_V2) {
+ if (rlen < (int)LABELSET_V2_MINRLEN) {
+ if (pmDebugOptions.logmeta)
+ fprintf(stderr, "%s: v2 rlen=%d too small (min=%d)\n",
+ __FUNCTION__, rlen, (int)LABELSET_V2_MINRLEN);
+ return PM_ERR_LOGREC;
+ }
+ }
+ else {
+ if (rlen < (int)LABELSET_V3_MINRLEN) {
+ if (pmDebugOptions.logmeta)
+ fprintf(stderr, "%s: v3 rlen=%d too small (min=%d)\n",
+ __FUNCTION__, rlen, (int)LABELSET_V3_MINRLEN);
+ return PM_ERR_LOGREC;
+ }
+ }
+
k = 0;
if (rtype == TYPE_LABEL_V2) {
__pmLoadTimeval((__int32_t *)&tbuf[k], stamp);