Add patches for pmieconf/pmlogmv command injection, libpcp PDU decode OOB guards, timezone validation, pmdaroot peer credentials, and pmproxy REST CERT_REQD and logger authentication hardening. Resolves: RHEL-213756 CVE-2026-16531 Resolves: RHEL-213746 CVE-2026-16530 Resolves: RHEL-213726 CVE-2026-16529 Resolves: RHEL-213717 CVE-2026-16527 Resolves: RHEL-213692 CVE-2026-16526 Resolves: RHEL-213661 CVE-2026-16524 Co-authored-by: Cursor <cursoragent@cursor.com>
103 lines
3.7 KiB
Diff
103 lines
3.7 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 342cb9163d..0e18c72aed 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
|
|
@@ -210,6 +214,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);
|
|
diff --git a/src/libpcp3/src/e_labels.c b/src/libpcp3/src/e_labels.c
|
|
index 8e94a112b0..169817266b 100644
|
|
--- a/src/libpcp3/src/e_labels.c
|
|
+++ b/src/libpcp3/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);
|