File 0014-src-libpcp-src-p_result.c-hardening-of-the-result-PD.patch of Package pcp.35852

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

openSUSE Build Service is sponsored by