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