File 0016-src-libpcp-src-p_result.c-rework-PDU-integrity-check.patch of Package pcp.37720

From e90ad45cf1c4bcc95c0a43f583643e01242891cf Mon Sep 17 00:00:00 2001
From: Ken McDonell <kenj@kenj.id.au>
Date: Sun, 25 Aug 2024 15:07:12 +1000
Subject: [PATCH 16/19] src/libpcp/src/p_result.c: rework PDU integrity checks
 in __pmEventArrayCheck()

1. rework the final check in this routine to work with all data types

2. add #1, #2, ... annotations in error messages with similar (in some
   cases identical) wording so we know which guard is being tripped.

(cherry picked from commit 383b8f615a93b8bda43dd6f6b44c3e21b06e9703)
---
 src/libpcp/src/p_result.c | 33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/src/libpcp/src/p_result.c b/src/libpcp/src/p_result.c
index b5a49df68..41481967b 100644
--- a/src/libpcp/src/p_result.c
+++ b/src/libpcp/src/p_result.c
@@ -338,7 +338,7 @@ __pmEventArrayCheck(pmValueBlock * const vb, int highres, int pmid, int value, s
 	base = (char *)&hreap->ea_record[0];
 	if (base > (char *)vb + check) {
 	    if (pmDebugOptions.pdu)
-		fprintf(stderr, "__pmEventArrayCheck: PM_ERR_IPC: pmid[%d] value[%d] highres event records past end of PDU buffer\n",
+		fprintf(stderr, "__pmEventArrayCheck #1: PM_ERR_IPC: pmid[%d] value[%d] highres event records past end of PDU buffer\n",
 			pmid, value);
 	    return PM_ERR_IPC;
 	}
@@ -349,7 +349,7 @@ __pmEventArrayCheck(pmValueBlock * const vb, int highres, int pmid, int value, s
 	base = (char *)&eap->ea_record[0];
 	if (base > (char *)vb + check) {
 	    if (pmDebugOptions.pdu)
-		fprintf(stderr, "__pmEventArrayCheck: PM_ERR_IPC: pmid[%d] value[%d] event records past end of PDU buffer\n",
+		fprintf(stderr, "__pmEventArrayCheck #2: PM_ERR_IPC: pmid[%d] value[%d] event records past end of PDU buffer\n",
 			pmid, value);
 	    return PM_ERR_IPC;
 	}
@@ -368,7 +368,7 @@ __pmEventArrayCheck(pmValueBlock * const vb, int highres, int pmid, int value, s
 		    sizeof(hrerp->er_nparams);
 	    if (size > remaining) {
 		if (pmDebugOptions.pdu)
-		    fprintf(stderr, "__pmEventArrayCheck: PM_ERR_IPC: pmid[%d] value[%d] record[%d] highres event record past end of PDU buffer\n",
+		    fprintf(stderr, "__pmEventArrayCheck #3: PM_ERR_IPC: pmid[%d] value[%d] record[%d] highres event record past end of PDU buffer\n",
 			    pmid, value, r);
 		return PM_ERR_IPC;
 	    }
@@ -381,7 +381,7 @@ __pmEventArrayCheck(pmValueBlock * const vb, int highres, int pmid, int value, s
 		    sizeof(erp->er_nparams);
 	    if (size > remaining) {
 		if (pmDebugOptions.pdu)
-		    fprintf(stderr, "__pmEventArrayCheck: PM_ERR_IPC: pmid[%d] value[%d] record[%d] event record past end of PDU buffer\n",
+		    fprintf(stderr, "__pmEventArrayCheck #4: PM_ERR_IPC: pmid[%d] value[%d] record[%d] event record past end of PDU buffer\n",
 			    pmid, value, r);
 		return PM_ERR_IPC;
 	    }
@@ -401,7 +401,7 @@ __pmEventArrayCheck(pmValueBlock * const vb, int highres, int pmid, int value, s
 
 	    if (sizeof(pmEventParameter) > remaining) {
 		if (pmDebugOptions.pdu)
-		    fprintf(stderr, "__pmEventArrayCheck: PM_ERR_IPC: pmid[%d] value[%d] record[%d] param[%d] event record past end of PDU buffer\n",
+		    fprintf(stderr, "__pmEventArrayCheck #5: PM_ERR_IPC: pmid[%d] value[%d] record[%d] param[%d] event record past end of PDU buffer\n",
 			    pmid, value, r, p);
 		return PM_ERR_IPC;
 	    }
@@ -415,24 +415,35 @@ __pmEventArrayCheck(pmValueBlock * const vb, int highres, int pmid, int value, s
 
 	    if (sizeof(pmID) + size > remaining) {
 		if (pmDebugOptions.pdu)
-		    fprintf(stderr, "__pmEventArrayCheck: PM_ERR_IPC: pmid[%d] value[%d] record[%d] param[%d] event record past end of PDU buffer\n",
+		    fprintf(stderr, "__pmEventArrayCheck #6: PM_ERR_IPC: pmid[%d] value[%d] record[%d] param[%d] event record past end of PDU buffer\n",
 			    pmid, value, r, p);
 		return PM_ERR_IPC;
 	    }
 
 	    base += sizeof(pmID) + PM_PDU_SIZE_BYTES(size);
 
-	    size = 8;	/* 64-bit types */
+	    /*
+	     * final check for the types below, ep_len should be 4 or
+	     * 8, but a malformed PDU could have smaller ep_len values
+	     * and then unpacking these types risk going past the end
+	     * of the  PDU buffer
+	     */
+	    size = 0;
 	    switch (type) {
 		case PM_TYPE_32:
 		case PM_TYPE_U32:
 		case PM_TYPE_FLOAT:
 		    size = 4;	/* 32-bit types */
 		    break;
+		case PM_TYPE_64:
+		case PM_TYPE_U64:
+		case PM_TYPE_DOUBLE:
+		    size = 8;	/* 64-bit types */
+		    break;
 	    }
-	    if (sizeof(pmID) + size > remaining) {
+	    if (size > 0 && sizeof(pmID) + size > remaining) {
 		if (pmDebugOptions.pdu)
-		    fprintf(stderr, "__pmEventArrayCheck: PM_ERR_IPC: pmid[%d] value[%d] record[%d] param[%d] event record past end of PDU buffer\n",
+		    fprintf(stderr, "__pmEventArrayCheck #7: PM_ERR_IPC: pmid[%d] value[%d] record[%d] param[%d] event record past end of PDU buffer\n",
 			    pmid, value, r, p);
 		return PM_ERR_IPC;
 	    }
@@ -968,7 +979,7 @@ __pmDecodeResult_ctx(__pmContext *ctxp, __pmPDU *pdubuf, __pmResult **result)
 	return sts;
     }
 
-    if (pmDebugOptions.pdu)
+    if (pmDebugOptions.pdu && pmDebugOptions.desperate)
 	__pmPrintResult_ctx(ctxp, stderr, pr);
 
     /*
@@ -1050,7 +1061,7 @@ __pmDecodeHighResResult_ctx(__pmContext *ctxp, __pmPDU *pdubuf, __pmResult **res
 	return sts;
     }
 
-    if (pmDebugOptions.pdu)
+    if (pmDebugOptions.pdu && pmDebugOptions.desperate)
 	__pmPrintResult_ctx(ctxp, stderr, pr);
 
     /*
-- 
2.43.0

openSUSE Build Service is sponsored by