pcp/0014-src-libpcp-src-p_result.c-hardening-of-the-result-PD.patch

94 lines
3.1 KiB
Diff

From 012a3c0efa3e17d803a91fd8a48adaac7f645f58 Mon Sep 17 00:00:00 2001
From: Nathan Scott <nathans@redhat.com>
Date: Fri, 9 Aug 2024 10:01:16 +1000
Subject: [PATCH 14/19] src/libpcp/src/p_result.c: hardening of the result PDU
handling
Updates to improve access to the result (store) PDU buffer; only
access the numpmid and timestamp fields after verifying the length
against the buffer size.
Addresses SUSE Issue B (part 2, the "similar issue note" for
__pmDecodeResult_ctx()).
(cherry picked from commit e152a1179c5eae01e33787a1e89bc07432fc5821)
---
src/libpcp/src/p_result.c | 39 ++++++++++++++++++++++-----------------
1 file changed, 22 insertions(+), 17 deletions(-)
diff --git a/src/libpcp/src/p_result.c b/src/libpcp/src/p_result.c
index 1500fe97c..071b52bba 100644
--- a/src/libpcp/src/p_result.c
+++ b/src/libpcp/src/p_result.c
@@ -763,6 +763,7 @@ __pmDecodeResult_ctx(__pmContext *ctxp, __pmPDU *pdubuf, __pmResult **result)
int sts;
int numpmid; /* number of metrics */
int len = pdubuf[0];
+ int v3archive;
__pmPDU *vset;
char *pduend; /* end pointer for incoming buffer */
size_t bytes, nopad;
@@ -773,38 +774,42 @@ __pmDecodeResult_ctx(__pmContext *ctxp, __pmPDU *pdubuf, __pmResult **result)
if (ctxp != NULL)
PM_ASSERT_IS_LOCKED(ctxp->c_lock);
- if (ctxp != NULL && ctxp->c_type == PM_CONTEXT_ARCHIVE && __pmLogVersion(ctxp->c_archctl->ac_log) == PM_LOG_VERS03) {
- /*
- * V3 archive
- */
- log_result_v3_t *lrp = (log_result_v3_t *)pdubuf;
+ v3archive = (ctxp && ctxp->c_type == PM_CONTEXT_ARCHIVE &&
+ __pmLogVersion(ctxp->c_archctl->ac_log) == PM_LOG_VERS03);
+ if (v3archive) {
pduend = (char *)pdubuf + len;
bytes = sizeof(log_result_v3_t) - sizeof(__int32_t);
+ }
+ else { /* over the wire PDU or V2 archive */
+ pduend = (char *)pdubuf + len;
+ bytes = sizeof(result_t) - sizeof(__pmPDU);
+ }
+
+ if (pduend - (char *)pdubuf < bytes) {
+ if (pmDebugOptions.pdu && pmDebugOptions.desperate)
+ fprintf(stderr, "%s: Bad: len=%d smaller than min %d\n",
+ "__pmDecodeResult", len, (int)bytes);
+ return PM_ERR_IPC;
+ }
+
+ /* delayed until after buffer size check has been completed */
+ if (v3archive) {
+ log_result_v3_t *lrp = (log_result_v3_t *)pdubuf;
+
nopad = bytes;
numpmid = ntohl(lrp->numpmid);
__pmLoadTimestamp((__int32_t *)&lrp->sec[0], &stamp);
vset = (__pmPDU *)lrp->data;
}
else {
- /*
- * over the wire PDU or V2 archive
- */
result_t *pp = (result_t *)pdubuf;
- pduend = (char *)pdubuf + len;
- bytes = sizeof(result_t) - sizeof(__pmPDU);
+
nopad = sizeof(pp->hdr) + sizeof(pp->timestamp) + sizeof(pp->numpmid);
numpmid = ntohl(pp->numpmid);
__pmLoadTimeval((__int32_t *)&pp->timestamp, &stamp);
vset = pp->data;
}
- if (pduend - (char *)pdubuf < bytes) {
- if (pmDebugOptions.pdu && pmDebugOptions.desperate)
- fprintf(stderr, "%s: Bad: len=%d smaller than min %d\n",
- "__pmDecodeResult", len, (int)bytes);
- return PM_ERR_IPC;
- }
-
if (numpmid < 0 || numpmid > len) {
if (pmDebugOptions.pdu && pmDebugOptions.desperate)
fprintf(stderr, "%s: Bad: numpmid=%d negative or not smaller "
--
2.43.0