summaryrefslogtreecommitdiff
path: root/qa/src/pducrash.c
diff options
context:
space:
mode:
Diffstat (limited to 'qa/src/pducrash.c')
-rw-r--r--qa/src/pducrash.c1278
1 files changed, 1278 insertions, 0 deletions
diff --git a/qa/src/pducrash.c b/qa/src/pducrash.c
new file mode 100644
index 0000000..91af348
--- /dev/null
+++ b/qa/src/pducrash.c
@@ -0,0 +1,1278 @@
+/*
+ * Feed all manner of horrendous PDUs into the decode routines
+ * to see what level of havoc can be caused. Builds up custom
+ * PDU structs (not possible using the __pmSend* routines) and
+ * calls the __pmDecode* routines.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/trace.h>
+#include <pcp/trace_dev.h>
+
+#include "localconfig.h"
+
+#if PCP_VER >= 3800
+static void
+decode_auth(const char *name)
+{
+ char *value;
+ int sts, attr, length;
+ struct auth {
+ __pmPDUHdr hdr;
+ int attr;
+ char value[0];
+ } *auth;
+
+ auth = (struct auth *)malloc(sizeof(*auth));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(auth, 0, sizeof(*auth));
+ sts = __pmDecodeAuth((__pmPDU *)auth, &attr, &value, &length);
+ fprintf(stderr, " __pmDecodeAuth: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking negative length\n", name);
+ memset(auth, 0, sizeof(*auth));
+ auth->hdr.len = -512;
+ auth->hdr.type = PDU_AUTH;
+ auth->attr = htonl(PCP_ATTR_USERID);
+ sts = __pmDecodeAuth((__pmPDU *)auth, &attr, &value, &length);
+ fprintf(stderr, " __pmDecodeAuth: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking empty value\n", name);
+ memset(auth, 0, sizeof(*auth));
+ auth->hdr.len = sizeof(*auth);
+ auth->hdr.type = PDU_AUTH;
+ auth->attr = htonl(PCP_ATTR_USERID);
+ sts = __pmDecodeAuth((__pmPDU *)auth, &attr, &value, &length);
+ fprintf(stderr, " __pmDecodeAuth: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking access beyond limit\n", name);
+ memset(auth, 0, sizeof(*auth));
+ auth->hdr.len = INT_MAX;
+ auth->hdr.type = PDU_AUTH;
+ auth->attr = htonl(PCP_ATTR_USERID);
+ sts = __pmDecodeAuth((__pmPDU *)auth, &attr, &value, &length);
+ fprintf(stderr, " __pmDecodeAuth: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ free(auth);
+}
+#else
+static void decode_auth(const char *name) { (void)name; }
+#endif
+
+static void
+decode_creds(const char *name)
+{
+ __pmCred *outcreds;
+ int sts, count, sender;
+ struct creds {
+ __pmPDUHdr hdr;
+ int numcreds;
+ __pmCred credslist[0];
+ } *creds;
+
+ creds = (struct creds *)malloc(sizeof(*creds));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(creds, 0, sizeof(*creds));
+ sts = __pmDecodeCreds((__pmPDU *)creds, &sender, &count, &outcreds);
+ fprintf(stderr, " __pmDecodeCreds: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outcreds); }
+
+ fprintf(stderr, "[%s] checking large numcred field\n", name);
+ memset(creds, 0, sizeof(*creds));
+ creds->hdr.len = sizeof(*creds);
+ creds->hdr.type = PDU_CREDS;
+ creds->numcreds = htonl(INT_MAX - 1);
+ sts = __pmDecodeCreds((__pmPDU *)creds, &sender, &count, &outcreds);
+ fprintf(stderr, " __pmDecodeCreds: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outcreds); }
+
+ fprintf(stderr, "[%s] checking negative numcred field\n", name);
+ memset(creds, 0, sizeof(*creds));
+ creds->hdr.len = sizeof(*creds);
+ creds->hdr.type = PDU_CREDS;
+ creds->numcreds = htonl(-2);
+ sts = __pmDecodeCreds((__pmPDU *)creds, &sender, &count, &outcreds);
+ fprintf(stderr, " __pmDecodeCreds: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outcreds); }
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(creds, 0, sizeof(*creds));
+ creds->hdr.len = sizeof(*creds);
+ creds->hdr.type = PDU_CREDS;
+ creds->numcreds = htonl(2);
+ sts = __pmDecodeCreds((__pmPDU *)creds, &sender, &count, &outcreds);
+ fprintf(stderr, " __pmDecodeCreds: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outcreds); }
+
+ free(creds);
+}
+
+static void
+decode_error(const char *name)
+{
+ int sts, code, data;
+ struct error {
+ __pmPDUHdr hdr;
+ } *error;
+ struct xerror {
+ __pmPDUHdr hdr;
+ int code[1];
+ } *xerror;
+
+ error = (struct error *)malloc(sizeof(*error));
+ xerror = (struct xerror *)malloc(sizeof(*xerror));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(error, 0, sizeof(*error));
+ sts = __pmDecodeError((__pmPDU *)error, &code);
+ fprintf(stderr, " __pmDecodeError: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking all-zeroes extended structure\n", name);
+ memset(xerror, 0, sizeof(*xerror));
+ sts = __pmDecodeXtendError((__pmPDU *)xerror, &code, &data);
+ fprintf(stderr, " __pmDecodeXtendError: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(error, 0, sizeof(*error));
+ error->hdr.len = sizeof(*error);
+ error->hdr.type = PDU_ERROR;
+ sts = __pmDecodeError((__pmPDU *)error, &code);
+ fprintf(stderr, " __pmDecodeError: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking access beyond extended buffer\n", name);
+ memset(xerror, 0, sizeof(*xerror));
+ xerror->hdr.len = sizeof(*xerror);
+ xerror->hdr.type = PDU_ERROR;
+ sts = __pmDecodeXtendError((__pmPDU *)xerror, &code, &data);
+ fprintf(stderr, " __pmDecodeXtendError: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ free(xerror);
+ free(error);
+}
+
+static void
+decode_profile(const char *name)
+{
+ __pmProfile *outprofs;
+ int sts, ctxnum;
+ struct profile {
+ __pmPDUHdr hdr;
+ int unused[2];
+ int numprof;
+ int padding;
+ } *profile;
+ struct instprof {
+ struct profile profile;
+ pmInDom indom;
+ int state;
+ int numinst;
+ int padding;
+ } *instprof;
+
+ profile = (struct profile *)malloc(sizeof(*profile));
+ instprof = (struct instprof *)malloc(sizeof(*instprof));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(profile, 0, sizeof(*profile));
+ sts = __pmDecodeProfile((__pmPDU *)profile, &ctxnum, &outprofs);
+ fprintf(stderr, " __pmDecodeProfile: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outprofs); }
+
+ fprintf(stderr, "[%s] checking large numprof field\n", name);
+ memset(profile, 0, sizeof(*profile));
+ profile->hdr.len = sizeof(*profile);
+ profile->hdr.type = PDU_PROFILE;
+ profile->numprof = htonl(INT_MAX - 42);
+ sts = __pmDecodeProfile((__pmPDU *)profile, &ctxnum, &outprofs);
+ fprintf(stderr, " __pmDecodeProfile: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outprofs); }
+
+ fprintf(stderr, "[%s] checking negative numprof field\n", name);
+ memset(profile, 0, sizeof(*profile));
+ profile->hdr.len = sizeof(*profile);
+ profile->hdr.type = PDU_PROFILE;
+ profile->numprof = htonl(-2);
+ sts = __pmDecodeProfile((__pmPDU *)profile, &ctxnum, &outprofs);
+ fprintf(stderr, " __pmDecodeProfile: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outprofs); }
+
+ fprintf(stderr, "[%s] checking access beyond basic buffer\n", name);
+ memset(profile, 0, sizeof(*profile));
+ profile->hdr.len = sizeof(*profile);
+ profile->hdr.type = PDU_PROFILE;
+ profile->numprof = htonl(2);
+ sts = __pmDecodeProfile((__pmPDU *)profile, &ctxnum, &outprofs);
+ fprintf(stderr, " __pmDecodeProfile: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outprofs); }
+
+ fprintf(stderr, "[%s] checking large numinst field\n", name);
+ memset(instprof, 0, sizeof(*instprof));
+ instprof->profile.hdr.len = sizeof(*instprof);
+ instprof->profile.hdr.type = PDU_PROFILE;
+ instprof->profile.numprof = htonl(1);
+ instprof->numinst = htonl(INT_MAX - 3);
+ sts = __pmDecodeProfile((__pmPDU *)instprof, &ctxnum, &outprofs);
+ fprintf(stderr, " __pmDecodeProfile: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outprofs); }
+
+ fprintf(stderr, "[%s] checking negative numinst field\n", name);
+ memset(instprof, 0, sizeof(*instprof));
+ instprof->profile.hdr.len = sizeof(*instprof);
+ instprof->profile.hdr.type = PDU_PROFILE;
+ instprof->profile.numprof = htonl(1);
+ instprof->numinst = htonl(-3);
+ sts = __pmDecodeProfile((__pmPDU *)instprof, &ctxnum, &outprofs);
+ fprintf(stderr, " __pmDecodeProfile: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outprofs); }
+
+ fprintf(stderr, "[%s] checking access beyond extended buffer\n", name);
+ memset(instprof, 0, sizeof(*instprof));
+ instprof->profile.hdr.len = sizeof(*instprof);
+ instprof->profile.hdr.type = PDU_PROFILE;
+ instprof->profile.numprof = htonl(1);
+ instprof->numinst = htonl(2);
+ sts = __pmDecodeProfile((__pmPDU *)instprof, &ctxnum, &outprofs);
+ fprintf(stderr, " __pmDecodeProfile: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outprofs); }
+
+ free(instprof);
+ free(profile);
+}
+
+static void
+decode_fetch(const char *name)
+{
+ __pmTimeval when;
+ pmID *pmidlist;
+ int sts, ctx, count;
+ struct fetch {
+ __pmPDUHdr hdr;
+ int ctxnum;
+ __pmTimeval when;
+ int numpmid;
+ pmID pmidlist[0];
+ } *fetch;
+
+ fetch = (struct fetch *)malloc(sizeof(*fetch));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(fetch, 0, sizeof(*fetch));
+ sts = __pmDecodeFetch((__pmPDU *)fetch, &ctx, &when, &count, &pmidlist);
+ fprintf(stderr, " __pmDecodeFetch: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(pmidlist); }
+
+ fprintf(stderr, "[%s] checking large numpmid field\n", name);
+ memset(fetch, 0, sizeof(*fetch));
+ fetch->hdr.len = sizeof(*fetch);
+ fetch->hdr.type = PDU_FETCH;
+ fetch->numpmid = htonl(INT_MAX - 1);
+ sts = __pmDecodeFetch((__pmPDU *)fetch, &ctx, &when, &count, &pmidlist);
+ fprintf(stderr, " __pmDecodeFetch: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(pmidlist); }
+
+ fprintf(stderr, "[%s] checking negative numpmid field\n", name);
+ memset(fetch, 0, sizeof(*fetch));
+ fetch->hdr.len = sizeof(*fetch);
+ fetch->hdr.type = PDU_FETCH;
+ fetch->numpmid = htonl(-2);
+ sts = __pmDecodeFetch((__pmPDU *)fetch, &ctx, &when, &count, &pmidlist);
+ fprintf(stderr, " __pmDecodeFetch: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(pmidlist); }
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(fetch, 0, sizeof(*fetch));
+ fetch->hdr.len = sizeof(*fetch);
+ fetch->hdr.type = PDU_FETCH;
+ fetch->numpmid = htonl(2);
+ sts = __pmDecodeFetch((__pmPDU *)fetch, &ctx, &when, &count, &pmidlist);
+ fprintf(stderr, " __pmDecodeFetch: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(pmidlist); }
+
+ free(fetch);
+}
+
+static void
+decode_desc_req(const char *name)
+{
+ pmID pmid;
+ int sts;
+ struct desc_req {
+ __pmPDUHdr hdr;
+ } *desc_req;
+
+ desc_req = (struct desc_req *)malloc(sizeof(*desc_req));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(desc_req, 0, sizeof(*desc_req));
+ sts = __pmDecodeDescReq((__pmPDU *)desc_req, &pmid);
+ fprintf(stderr, " __pmDecodeDescReq: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(desc_req, 0, sizeof(*desc_req));
+ desc_req->hdr.len = sizeof(*desc_req);
+ desc_req->hdr.type = PDU_DESC_REQ;
+ sts = __pmDecodeDescReq((__pmPDU *)desc_req, &pmid);
+ fprintf(stderr, " __pmDecodeDescReq: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ free(desc_req);
+}
+
+static void
+decode_desc(const char *name)
+{
+ pmDesc pmdesc;
+ int sts;
+ struct desc {
+ __pmPDUHdr hdr;
+ } *desc;
+
+ desc = (struct desc *)malloc(sizeof(*desc));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(desc, 0, sizeof(*desc));
+ sts = __pmDecodeDesc((__pmPDU *)desc, &pmdesc);
+ fprintf(stderr, " __pmDecodeDesc: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(desc, 0, sizeof(*desc));
+ desc->hdr.len = sizeof(*desc);
+ desc->hdr.type = PDU_DESC;
+ sts = __pmDecodeDesc((__pmPDU *)desc, &pmdesc);
+ fprintf(stderr, " __pmDecodeDesc: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ free(desc);
+}
+
+static void
+decode_instance_req(const char *name)
+{
+ __pmTimeval when;
+ pmInDom indom;
+ int inst, sts;
+ char *resname;
+ struct instance_req {
+ __pmPDUHdr hdr;
+ pmInDom indom;
+ __pmTimeval when;
+ int inst;
+ int namelen;
+ char name[0];
+ } *instance_req, *xinstance_req;
+
+ instance_req = (struct instance_req *)malloc(sizeof(*instance_req));
+ xinstance_req = (struct instance_req *)malloc(sizeof(*xinstance_req)+16);
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(instance_req, 0, sizeof(*instance_req));
+ sts = __pmDecodeInstanceReq((__pmPDU *)instance_req, &when, &indom, &inst, &resname);
+ fprintf(stderr, " __pmDecodeInstanceReq: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(resname); }
+
+ fprintf(stderr, "[%s] checking large namelen field\n", name);
+ memset(instance_req, 0, sizeof(*instance_req));
+ instance_req->hdr.len = sizeof(*instance_req);
+ instance_req->hdr.type = PDU_INSTANCE_REQ;
+ instance_req->namelen = htonl(INT_MAX - 1);
+ sts = __pmDecodeInstanceReq((__pmPDU *)instance_req, &when, &indom, &inst, &resname);
+ fprintf(stderr, " __pmDecodeInstanceReq: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(resname); }
+
+ fprintf(stderr, "[%s] checking negative namelen field\n", name);
+ memset(instance_req, 0, sizeof(*instance_req));
+ instance_req->hdr.len = sizeof(*instance_req);
+ instance_req->hdr.type = PDU_INSTANCE_REQ;
+ instance_req->namelen = htonl(-2);
+ sts = __pmDecodeInstanceReq((__pmPDU *)instance_req, &when, &indom, &inst, &resname);
+ fprintf(stderr, " __pmDecodeInstanceReq: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(resname); }
+
+ fprintf(stderr, "[%s] checking access beyond basic buffer\n", name);
+ memset(instance_req, 0, sizeof(*instance_req));
+ instance_req->hdr.len = sizeof(*instance_req);
+ instance_req->hdr.type = PDU_INSTANCE_REQ;
+ instance_req->namelen = htonl(1);
+ sts = __pmDecodeInstanceReq((__pmPDU *)instance_req, &when, &indom, &inst, &resname);
+ fprintf(stderr, " __pmDecodeInstanceReq: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(resname); }
+
+ fprintf(stderr, "[%s] checking access beyond extended buffer\n", name);
+ memset(xinstance_req, 0, sizeof(*xinstance_req) + 16);
+ xinstance_req->hdr.len = sizeof(*xinstance_req) + 16;
+ xinstance_req->hdr.type = PDU_INSTANCE_REQ;
+ xinstance_req->namelen = htonl(32);
+ sts = __pmDecodeInstanceReq((__pmPDU *)xinstance_req, &when, &indom, &inst, &resname);
+ fprintf(stderr, " __pmDecodeInstanceReq: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) {free(resname); }
+
+ free(xinstance_req);
+ free(instance_req);
+}
+
+static void
+decode_instance(const char *name)
+{
+ __pmInResult *inresult;
+ int sts;
+ struct instance {
+ __pmPDUHdr hdr;
+ pmInDom indom;
+ int numinst;
+ __pmPDU rest[0];
+ } *instance;
+ struct instlist {
+ struct instance instance;
+ int inst;
+ int namelen;
+ char name[0];
+ } *instlist;
+
+ instance = (struct instance *)malloc(sizeof(*instance));
+ instlist = (struct instlist *)malloc(sizeof(*instlist));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(instance, 0, sizeof(*instance));
+ sts = __pmDecodeInstance((__pmPDU *)instance, &inresult);
+ fprintf(stderr, " __pmDecodeInstance: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) __pmFreeInResult(inresult);
+
+ fprintf(stderr, "[%s] checking large numinst field\n", name);
+ memset(instance, 0, sizeof(*instance));
+ instance->hdr.len = sizeof(*instance);
+ instance->hdr.type = PDU_INSTANCE;
+ instance->numinst = htonl(INT_MAX - 42);
+ sts = __pmDecodeInstance((__pmPDU *)instance, &inresult);
+ fprintf(stderr, " __pmDecodeInstance: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) __pmFreeInResult(inresult);
+
+ fprintf(stderr, "[%s] checking negative numinst field\n", name);
+ memset(instance, 0, sizeof(*instance));
+ instance->hdr.len = sizeof(*instance);
+ instance->hdr.type = PDU_INSTANCE;
+ instance->numinst = htonl(-2);
+ sts = __pmDecodeInstance((__pmPDU *)instance, &inresult);
+ fprintf(stderr, " __pmDecodeInstance: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) __pmFreeInResult(inresult);
+
+ fprintf(stderr, "[%s] checking access beyond basic buffer\n", name);
+ memset(instance, 0, sizeof(*instance));
+ instance->hdr.len = sizeof(*instance);
+ instance->hdr.type = PDU_INSTANCE;
+ instance->numinst = htonl(1);
+ sts = __pmDecodeInstance((__pmPDU *)instance, &inresult);
+ fprintf(stderr, " __pmDecodeInstance: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) __pmFreeInResult(inresult);
+
+ fprintf(stderr, "[%s] checking large namelen field\n", name);
+ memset(instlist, 0, sizeof(*instlist));
+ instlist->instance.hdr.len = sizeof(*instlist);
+ instlist->instance.hdr.type = PDU_INSTANCE;
+ instlist->instance.numinst = htonl(1);
+ instlist->namelen = htonl(INT_MAX - 5);
+ sts = __pmDecodeInstance((__pmPDU *)instlist, &inresult);
+ fprintf(stderr, " __pmDecodeInstance: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) __pmFreeInResult(inresult);
+
+ fprintf(stderr, "[%s] checking negative namelen field\n", name);
+ memset(instlist, 0, sizeof(*instlist));
+ instlist->instance.hdr.len = sizeof(*instlist);
+ instlist->instance.hdr.type = PDU_INSTANCE;
+ instlist->instance.numinst = htonl(1);
+ instlist->namelen = htonl(-2);
+ sts = __pmDecodeInstance((__pmPDU *)instlist, &inresult);
+ fprintf(stderr, " __pmDecodeInstance: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) __pmFreeInResult(inresult);
+
+ fprintf(stderr, "[%s] checking access beyond extended buffer\n", name);
+ memset(instlist, 0, sizeof(*instlist));
+ instlist->instance.hdr.len = sizeof(*instlist);
+ instlist->instance.hdr.type = PDU_INSTANCE;
+ instlist->instance.numinst = htonl(1);
+ instlist->namelen = htonl(32);
+ sts = __pmDecodeInstance((__pmPDU *)instlist, &inresult);
+ fprintf(stderr, " __pmDecodeInstance: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) __pmFreeInResult(inresult);
+
+ free(instlist);
+ free(instance);
+}
+
+static void
+decode_pmns_ids(const char *name)
+{
+ pmID idarray[10];
+ int idsts, sts;
+ struct idlist {
+ __pmPDUHdr hdr;
+ int sts;
+ int numids;
+ pmID idlist[0];
+ } *idlist;
+
+ idlist = (struct idlist *)malloc(sizeof(*idlist));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(idlist, 0, sizeof(*idlist));
+ sts = __pmDecodeIDList((__pmPDU *)idlist, 10, idarray, &idsts);
+ fprintf(stderr, " __pmDecodeIDList: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking large numids field\n", name);
+ memset(idlist, 0, sizeof(*idlist));
+ idlist->hdr.len = sizeof(*idlist);
+ idlist->hdr.type = PDU_PMNS_IDS;
+ idlist->numids = htonl(INT_MAX - 1);
+ sts = __pmDecodeIDList((__pmPDU *)idlist, 10, idarray, &idsts);
+ fprintf(stderr, " __pmDecodeIDList: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking negative numids field\n", name);
+ memset(idlist, 0, sizeof(*idlist));
+ idlist->hdr.len = sizeof(*idlist);
+ idlist->hdr.type = PDU_PMNS_IDS;
+ idlist->numids = htonl(-2);
+ sts = __pmDecodeIDList((__pmPDU *)idlist, 10, idarray, &idsts);
+ fprintf(stderr, " __pmDecodeIDList: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(idlist, 0, sizeof(*idlist));
+ idlist->hdr.len = sizeof(*idlist);
+ idlist->hdr.type = PDU_PMNS_IDS;
+ idlist->numids = htonl(2);
+ sts = __pmDecodeIDList((__pmPDU *)idlist, 10, idarray, &idsts);
+ fprintf(stderr, " __pmDecodeIDList: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ free(idlist);
+}
+
+static void
+decode_pmns_names(const char *name)
+{
+ int sts, numnames, *status;
+ char **names;
+ struct namelist {
+ __pmPDUHdr hdr;
+ int nstrbytes;
+ int numstatus;
+ int numnames;
+ pmID names[0];
+ } *namelist;
+ struct namestatus {
+ struct namelist namelist;
+ int status;
+ int namelen;
+ char name[0];
+ } *namestatus;
+
+ namelist = (struct namelist *)malloc(sizeof(*namelist));
+ namestatus = (struct namestatus *)malloc(sizeof(*namestatus));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(namelist, 0, sizeof(*namelist));
+ sts = __pmDecodeNameList((__pmPDU *)namelist, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking large numnames field\n", name);
+ memset(namelist, 0, sizeof(*namelist));
+ namelist->hdr.len = sizeof(*namelist);
+ namelist->hdr.type = PDU_PMNS_NAMES;
+ namelist->numnames = htonl(INT_MAX - 42);
+ sts = __pmDecodeNameList((__pmPDU *)namelist, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ fprintf(stderr, "[%s] checking negative numnames field\n", name);
+ memset(namelist, 0, sizeof(*namelist));
+ namelist->hdr.len = sizeof(*namelist);
+ namelist->hdr.type = PDU_PMNS_NAMES;
+ namelist->numnames = htonl(-42);
+ sts = __pmDecodeNameList((__pmPDU *)namelist, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ fprintf(stderr, "[%s] checking large nstrbytes field\n", name);
+ memset(namelist, 0, sizeof(*namelist));
+ namelist->hdr.len = sizeof(*namelist);
+ namelist->hdr.type = PDU_PMNS_NAMES;
+ namelist->numnames = htonl(42);
+ namelist->nstrbytes = htonl(INT_MAX - 42);
+ sts = __pmDecodeNameList((__pmPDU *)namelist, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ fprintf(stderr, "[%s] checking negative nstrbytes field\n", name);
+ memset(namelist, 0, sizeof(*namelist));
+ namelist->hdr.len = sizeof(*namelist);
+ namelist->hdr.type = PDU_PMNS_NAMES;
+ namelist->numnames = htonl(42);
+ namelist->nstrbytes = htonl(-42);
+ sts = __pmDecodeNameList((__pmPDU *)namelist, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ fprintf(stderr, "[%s] checking access beyond basic buffer\n", name);
+ memset(namelist, 0, sizeof(*namelist));
+ namelist->hdr.len = sizeof(*namelist);
+ namelist->hdr.type = PDU_PMNS_NAMES;
+ namelist->numnames = htonl(1);
+ sts = __pmDecodeNameList((__pmPDU *)namelist, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ fprintf(stderr, "[%s] checking large namelen field\n", name);
+ memset(namestatus, 0, sizeof(*namestatus));
+ namestatus->namelist.hdr.len = sizeof(*namestatus);
+ namestatus->namelist.hdr.type = PDU_PMNS_NAMES;
+ namestatus->namelist.numnames = htonl(1);
+ namestatus->namelen = htonl(INT_MAX - 5);
+ sts = __pmDecodeNameList((__pmPDU *)namestatus, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ fprintf(stderr, "[%s] checking negative namelen field\n", name);
+ memset(namestatus, 0, sizeof(*namestatus));
+ namestatus->namelist.hdr.len = sizeof(*namestatus);
+ namestatus->namelist.hdr.type = PDU_PMNS_NAMES;
+ namestatus->namelist.numnames = htonl(1);
+ namestatus->namelen = htonl(-2);
+ sts = __pmDecodeNameList((__pmPDU *)namestatus, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ fprintf(stderr, "[%s] checking access beyond extended buffer\n", name);
+ memset(namestatus, 0, sizeof(*namestatus));
+ namestatus->namelist.hdr.len = sizeof(*namestatus);
+ namestatus->namelist.hdr.type = PDU_PMNS_NAMES;
+ namestatus->namelist.numnames = htonl(1);
+ namestatus->namelen = htonl(32);
+ sts = __pmDecodeNameList((__pmPDU *)namestatus, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ fprintf(stderr, "[%s] checking large namelen field (+statuslist)\n", name);
+ memset(namestatus, 0, sizeof(*namestatus));
+ namestatus->namelist.hdr.len = sizeof(*namestatus);
+ namestatus->namelist.hdr.type = PDU_PMNS_NAMES;
+ namestatus->namelist.numnames = namestatus->namelist.numstatus = htonl(1);
+ namestatus->namelen = htonl(INT_MAX - 5);
+ sts = __pmDecodeNameList((__pmPDU *)namestatus, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ fprintf(stderr, "[%s] checking negative namelen field (+statuslist)\n", name);
+ memset(namestatus, 0, sizeof(*namestatus));
+ namestatus->namelist.hdr.len = sizeof(*namestatus);
+ namestatus->namelist.hdr.type = PDU_PMNS_NAMES;
+ namestatus->namelist.numnames = namestatus->namelist.numstatus = htonl(1);
+ namestatus->namelen = htonl(-2);
+ sts = __pmDecodeNameList((__pmPDU *)namestatus, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ fprintf(stderr, "[%s] checking access beyond extended buffer (+statuslist)\n", name);
+ memset(namestatus, 0, sizeof(*namestatus));
+ namestatus->namelist.hdr.len = sizeof(*namestatus);
+ namestatus->namelist.hdr.type = PDU_PMNS_NAMES;
+ namestatus->namelist.numnames = namestatus->namelist.numstatus = htonl(1);
+ namestatus->namelen = htonl(32);
+ sts = __pmDecodeNameList((__pmPDU *)namestatus, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ free(namestatus);
+ free(namelist);
+}
+
+/* Wraps __pmDecodeChildReq and __pmDecodeTraversePMNSReq interfaces */
+static void
+decode_name_request(const char *name, const char *caller, int pdutype)
+{
+ char *resnames;
+ int sts, restype;
+ struct name_req {
+ __pmPDUHdr hdr;
+ int subtype;
+ int namelen;
+ char name[0];
+ } *name_req, *xname_req;
+
+ name_req = (struct name_req *)malloc(sizeof(*name_req));
+ xname_req = (struct name_req *)malloc(sizeof(*name_req) + 16);
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(name_req, 0, sizeof(*name_req));
+ sts = (pdutype == PDU_PMNS_TRAVERSE) ?
+ __pmDecodeTraversePMNSReq((__pmPDU *)name_req, &resnames) :
+ __pmDecodeChildReq((__pmPDU *)name_req, &resnames, &restype);
+ fprintf(stderr, " __pmDecode%sReq: sts = %d (%s)\n", caller, sts, pmErrStr(sts));
+ if (sts >= 0) { free(resnames); }
+
+ fprintf(stderr, "[%s] checking large namelen field\n", name);
+ memset(name_req, 0, sizeof(*name_req));
+ name_req->hdr.len = sizeof(*name_req);
+ name_req->hdr.type = pdutype;
+ name_req->namelen = htonl(INT_MAX - 1);
+ sts = (pdutype == PDU_PMNS_TRAVERSE) ?
+ __pmDecodeTraversePMNSReq((__pmPDU *)name_req, &resnames) :
+ __pmDecodeChildReq((__pmPDU *)name_req, &resnames, &restype);
+ fprintf(stderr, " __pmDecode%sReq: sts = %d (%s)\n", caller, sts, pmErrStr(sts));
+ if (sts >= 0) { free(resnames); }
+
+ fprintf(stderr, "[%s] checking negative namelen field\n", name);
+ memset(name_req, 0, sizeof(*name_req));
+ name_req->hdr.len = sizeof(*name_req);
+ name_req->hdr.type = pdutype;
+ name_req->namelen = htonl(-2);
+ sts = (pdutype == PDU_PMNS_TRAVERSE) ?
+ __pmDecodeTraversePMNSReq((__pmPDU *)name_req, &resnames) :
+ __pmDecodeChildReq((__pmPDU *)name_req, &resnames, &restype);
+ fprintf(stderr, " __pmDecode%sReq: sts = %d (%s)\n", caller, sts, pmErrStr(sts));
+ if (sts >= 0) { free(resnames); }
+
+ fprintf(stderr, "[%s] checking access beyond basic buffer\n", name);
+ memset(name_req, 0, sizeof(*name_req));
+ name_req->hdr.len = sizeof(*name_req);
+ name_req->hdr.type = pdutype;
+ name_req->namelen = htonl(1);
+ sts = (pdutype == PDU_PMNS_TRAVERSE) ?
+ __pmDecodeTraversePMNSReq((__pmPDU *)name_req, &resnames) :
+ __pmDecodeChildReq((__pmPDU *)name_req, &resnames, &restype);
+ fprintf(stderr, " __pmDecode%sReq: sts = %d (%s)\n", caller, sts, pmErrStr(sts));
+ if (sts >= 0) { free(resnames); }
+
+ fprintf(stderr, "[%s] checking access beyond extended buffer\n", name);
+ memset(xname_req, 0, sizeof(*xname_req));
+ xname_req->hdr.len = sizeof(*xname_req) + 16;
+ xname_req->hdr.type = pdutype;
+ xname_req->namelen = htonl(32);
+ sts = (pdutype == PDU_PMNS_TRAVERSE) ?
+ __pmDecodeTraversePMNSReq((__pmPDU *)xname_req, &resnames) :
+ __pmDecodeChildReq((__pmPDU *)xname_req, &resnames, &restype);
+ fprintf(stderr, " __pmDecode%sReq: sts = %d (%s)\n", caller, sts, pmErrStr(sts));
+ if (sts >= 0) { free(resnames); }
+
+ free(xname_req);
+ free(name_req);
+}
+
+static void
+decode_pmns_child(const char *name)
+{
+ decode_name_request(name, "Child", PDU_PMNS_CHILD);
+}
+
+static void
+decode_pmns_traverse(const char *name)
+{
+ decode_name_request(name, "TraversePMNS", PDU_PMNS_TRAVERSE);
+}
+
+static void
+decode_log_control(const char *name)
+{
+ pmResult *result;
+ int sts, ctl, state, delta;
+ struct log_ctl {
+ __pmPDUHdr hdr;
+ int el[3];
+ int numpmid;
+ __pmPDU data[0];
+ } *log_ctl;
+ struct logvlist {
+ struct log_ctl log_ctl;
+ pmID pmid;
+ int numval;
+ __pmValue_PDU vlist[0];
+ } *logvlist;
+
+ log_ctl = (struct log_ctl *)malloc(sizeof(*log_ctl));
+ logvlist = (struct logvlist *)malloc(sizeof(*logvlist));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(log_ctl, 0, sizeof(*log_ctl));
+ sts = __pmDecodeLogControl((__pmPDU *)log_ctl, &result, &ctl, &state, &delta);
+ fprintf(stderr, " __pmDecodeLogControl: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(result);
+
+ fprintf(stderr, "[%s] checking large numpmid field\n", name);
+ memset(log_ctl, 0, sizeof(*log_ctl));
+ log_ctl->hdr.len = sizeof(*log_ctl);
+ log_ctl->hdr.type = PDU_LOG_CONTROL;
+ log_ctl->numpmid = htonl(INT_MAX - 42);
+ sts = __pmDecodeLogControl((__pmPDU *)log_ctl, &result, &ctl, &state, &delta);
+ fprintf(stderr, " __pmDecodeLogControl: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(result);
+
+ fprintf(stderr, "[%s] checking negative numpmid field\n", name);
+ memset(log_ctl, 0, sizeof(*log_ctl));
+ log_ctl->hdr.len = sizeof(*log_ctl);
+ log_ctl->hdr.type = PDU_LOG_CONTROL;
+ log_ctl->numpmid = htonl(-42);
+ sts = __pmDecodeLogControl((__pmPDU *)log_ctl, &result, &ctl, &state, &delta);
+ fprintf(stderr, " __pmDecodeLogControl: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(result);
+
+ fprintf(stderr, "[%s] checking access beyond basic buffer\n", name);
+ memset(log_ctl, 0, sizeof(*log_ctl));
+ log_ctl->hdr.len = sizeof(*log_ctl);
+ log_ctl->hdr.type = PDU_LOG_CONTROL;
+ log_ctl->numpmid = htonl(2);
+ sts = __pmDecodeLogControl((__pmPDU *)log_ctl, &result, &ctl, &state, &delta);
+ fprintf(stderr, " __pmDecodeLogControl: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(result);
+
+ fprintf(stderr, "[%s] checking large numval field\n", name);
+ memset(logvlist, 0, sizeof(*logvlist));
+ logvlist->log_ctl.hdr.len = sizeof(*logvlist);
+ logvlist->log_ctl.hdr.type = PDU_LOG_CONTROL;
+ logvlist->log_ctl.numpmid = htonl(1);
+ logvlist->numval = htonl(INT_MAX - 3);
+ sts = __pmDecodeLogControl((__pmPDU *)logvlist, &result, &ctl, &state, &delta);
+ fprintf(stderr, " __pmDecodeLogControl: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(result);
+
+ fprintf(stderr, "[%s] checking access beyond extended buffer\n", name);
+ memset(logvlist, 0, sizeof(*logvlist));
+ logvlist->log_ctl.hdr.len = sizeof(*logvlist);
+ logvlist->log_ctl.hdr.type = PDU_LOG_CONTROL;
+ logvlist->log_ctl.numpmid = htonl(1);
+ logvlist->numval = htonl(2);
+ sts = __pmDecodeLogControl((__pmPDU *)logvlist, &result, &ctl, &state, &delta);
+ fprintf(stderr, " __pmDecodeLogControl: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(result);
+
+ free(log_ctl);
+ free(logvlist);
+}
+
+static void
+decode_log_status(const char *name)
+{
+ __pmLoggerStatus *log;
+ int sts;
+ struct log_sts {
+ __pmPDUHdr hdr;
+ int pad;
+ __pmLoggerStatus sts;
+ } *log_sts;
+
+ log_sts = (struct log_sts *)malloc(sizeof(*log_sts));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(log_sts, 0, sizeof(*log_sts));
+ sts = __pmDecodeLogStatus((__pmPDU *)log_sts, &log);
+ fprintf(stderr, " __pmDecodeLogStatus: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(log_sts, 0, sizeof(*log_sts));
+ log_sts->hdr.len = sizeof(*log_sts) - 4;
+ log_sts->hdr.type = PDU_LOG_STATUS;
+ sts = __pmDecodeLogStatus((__pmPDU *)log_sts, &log);
+ fprintf(stderr, " __pmDecodeLogStatus: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ free(log_sts);
+}
+
+static void
+decode_log_request(const char *name)
+{
+ int type, sts;
+ struct log_req {
+ __pmPDUHdr hdr;
+ } *log_req;
+
+ log_req = (struct log_req *)malloc(sizeof(*log_req));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(log_req, 0, sizeof(*log_req));
+ sts = __pmDecodeLogRequest((__pmPDU *)log_req, &type);
+ fprintf(stderr, " __pmDecodeLogRequest: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(log_req, 0, sizeof(*log_req));
+ log_req->hdr.len = sizeof(*log_req);
+ log_req->hdr.type = PDU_LOG_REQUEST;
+ sts = __pmDecodeLogRequest((__pmPDU *)log_req, &type);
+ fprintf(stderr, " __pmDecodeLogRequest: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ free(log_req);
+}
+
+static void
+decode_result(const char *name)
+{
+ int sts;
+ pmResult *resp;
+ struct result {
+ __pmPDUHdr hdr;
+ __pmTimeval stamp;
+ int numpmid;
+ __pmPDU data[0];
+ } *result;
+ struct resultlist {
+ struct result result;
+ pmID pmid;
+ int numval;
+ int valfmt;
+ __pmValue_PDU vlist[0];
+ } *resultlist;
+ struct resultdynlist {
+ struct resultlist vlist;
+ __pmValue_PDU values;
+ pmValueBlock block[0];
+ } *resultdynlist;
+
+ result = (struct result *)malloc(sizeof(*result));
+ resultlist = (struct resultlist *)malloc(sizeof(*resultlist));
+ resultdynlist = (struct resultdynlist *)malloc(sizeof(*resultdynlist));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(result, 0, sizeof(*result));
+ sts = __pmDecodeResult((__pmPDU *)result, &resp);
+ fprintf(stderr, " __pmDecodeResult: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(resp);
+
+ fprintf(stderr, "[%s] checking large numpmid field\n", name);
+ memset(result, 0, sizeof(*result));
+ result->hdr.len = sizeof(*result);
+ result->hdr.type = PDU_RESULT;
+ result->numpmid = htonl(INT_MAX - 42);
+ sts = __pmDecodeResult((__pmPDU *)result, &resp);
+ fprintf(stderr, " __pmDecodeResult: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(resp);
+
+ fprintf(stderr, "[%s] checking negative numpmid field\n", name);
+ memset(result, 0, sizeof(*result));
+ result->hdr.len = sizeof(*result);
+ result->hdr.type = PDU_RESULT;
+ result->numpmid = htonl(-42);
+ sts = __pmDecodeResult((__pmPDU *)result, &resp);
+ fprintf(stderr, " __pmDecodeResult: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(resp);
+
+ fprintf(stderr, "[%s] checking access beyond basic buffer\n", name);
+ memset(result, 0, sizeof(*result));
+ result->hdr.len = sizeof(*result);
+ result->hdr.type = PDU_RESULT;
+ result->numpmid = htonl(4);
+ sts = __pmDecodeResult((__pmPDU *)result, &resp);
+ fprintf(stderr, " __pmDecodeResult: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(resp);
+
+ fprintf(stderr, "[%s] checking large numval field\n", name);
+ memset(resultlist, 0, sizeof(*resultlist));
+ resultlist->result.hdr.len = sizeof(*resultlist);
+ resultlist->result.hdr.type = PDU_RESULT;
+ resultlist->result.numpmid = htonl(1);
+ resultlist->numval = htonl(INT_MAX - 3);
+ sts = __pmDecodeResult((__pmPDU *)resultlist, &resp);
+ fprintf(stderr, " __pmDecodeResult: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(resp);
+
+ fprintf(stderr, "[%s] checking negative numval field\n", name);
+ memset(resultlist, 0, sizeof(*resultlist));
+ resultlist->result.hdr.len = sizeof(*resultlist);
+ resultlist->result.hdr.type = PDU_RESULT;
+ resultlist->result.numpmid = htonl(1);
+ resultlist->numval = htonl(-3);
+ sts = __pmDecodeResult((__pmPDU *)resultlist, &resp);
+ fprintf(stderr, " __pmDecodeResult: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(resp);
+
+ fprintf(stderr, "[%s] checking access beyond extended buffer\n", name);
+ memset(resultlist, 0, sizeof(*resultlist));
+ resultlist->result.hdr.len = sizeof(*resultlist);
+ resultlist->result.hdr.type = PDU_LOG_CONTROL;
+ resultlist->result.numpmid = htonl(1);
+ resultlist->numval = htonl(2);
+ sts = __pmDecodeResult((__pmPDU *)resultlist, &resp);
+ fprintf(stderr, " __pmDecodeResult: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(resp);
+
+ fprintf(stderr, "[%s] checking insitu valfmt field\n", name);
+ memset(resultlist, 0, sizeof(*resultlist));
+ resultlist->result.hdr.len = sizeof(*resultlist);
+ resultlist->result.hdr.type = PDU_RESULT;
+ resultlist->result.numpmid = htonl(1);
+ resultlist->valfmt = htonl(PM_VAL_INSITU);
+ resultlist->numval = htonl(1);
+ sts = __pmDecodeResult((__pmPDU *)resultlist, &resp);
+ fprintf(stderr, " __pmDecodeResult: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(resp);
+
+ fprintf(stderr, "[%s] checking non-insitu valfmt field\n", name);
+ memset(resultlist, 0, sizeof(*resultlist));
+ resultlist->result.hdr.len = sizeof(*resultlist);
+ resultlist->result.hdr.type = PDU_RESULT;
+ resultlist->result.numpmid = htonl(1);
+ resultlist->valfmt = htonl(PM_VAL_DPTR);
+ resultlist->numval = htonl(1);
+ sts = __pmDecodeResult((__pmPDU *)resultlist, &resp);
+ fprintf(stderr, " __pmDecodeResult: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(resp);
+
+ fprintf(stderr, "[%s] checking access beyond non-insitu valfmt field\n", name);
+ memset(resultdynlist, 0, sizeof(*resultdynlist));
+ resultdynlist->vlist.result.hdr.len = sizeof(*resultdynlist);
+ resultdynlist->vlist.result.hdr.type = PDU_RESULT;
+ resultdynlist->vlist.result.numpmid = htonl(1);
+ resultdynlist->vlist.valfmt = htonl(PM_VAL_DPTR);
+ resultdynlist->vlist.numval = htonl(1);
+ resultdynlist->values.value.lval = htonl(10);
+ sts = __pmDecodeResult((__pmPDU *)resultdynlist, &resp);
+ fprintf(stderr, " __pmDecodeResult: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(resp);
+
+ free(resultdynlist);
+ free(resultlist);
+ free(result);
+}
+
+static void
+decode_text_req(const char *name)
+{
+ int ident, type, sts;
+ struct text_req {
+ __pmPDUHdr hdr;
+ int val[1];
+ } *text_req;
+
+ text_req = (struct text_req *)malloc(sizeof(*text_req));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(text_req, 0, sizeof(*text_req));
+ sts = __pmDecodeTextReq((__pmPDU *)text_req, &ident, &type);
+ fprintf(stderr, " __pmDecodeTextReq: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(text_req, 0, sizeof(*text_req));
+ text_req->hdr.len = sizeof(*text_req);
+ text_req->hdr.type = PDU_TEXT_REQ;
+ sts = __pmDecodeTextReq((__pmPDU *)text_req, &ident, &type);
+ fprintf(stderr, " __pmDecodeTextReq: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ free(text_req);
+}
+
+static void
+decode_text(const char *name)
+{
+ int ident, sts;
+ char *buffer;
+ struct text {
+ __pmPDUHdr hdr;
+ int ident;
+ int buflen;
+ char buffer[0];
+ } *text;
+
+ text = (struct text *)malloc(sizeof(*text));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(text, 0, sizeof(*text));
+ sts = __pmDecodeText((__pmPDU *)text, &ident, &buffer);
+ fprintf(stderr, " __pmDecodeText: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(buffer); }
+
+ fprintf(stderr, "[%s] checking large buflen field\n", name);
+ memset(text, 0, sizeof(*text));
+ text->hdr.len = sizeof(*text);
+ text->hdr.type = PDU_TEXT;
+ text->buflen = htonl(INT_MAX - 1);
+ sts = __pmDecodeText((__pmPDU *)text, &ident, &buffer);
+ fprintf(stderr, " __pmDecodeText: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(buffer); }
+
+ fprintf(stderr, "[%s] checking negative buflen field\n", name);
+ memset(text, 0, sizeof(*text));
+ text->hdr.len = sizeof(*text);
+ text->hdr.type = PDU_TEXT;
+ text->buflen = htonl(-2);
+ sts = __pmDecodeText((__pmPDU *)text, &ident, &buffer);
+ fprintf(stderr, " __pmDecodeText: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(buffer); }
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(text, 0, sizeof(*text));
+ text->hdr.len = sizeof(*text);
+ text->hdr.type = PDU_TEXT;
+ text->buflen = htonl(2);
+ sts = __pmDecodeText((__pmPDU *)text, &ident, &buffer);
+ fprintf(stderr, " __pmDecodeText: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(buffer); }
+
+ free(text);
+}
+
+static void
+decode_trace_ack(const char *name)
+{
+ int sts, ack;
+ struct trace_ack {
+ __pmTracePDUHdr hdr;
+ } *trace_ack;
+
+ trace_ack = (struct trace_ack *)malloc(sizeof(*trace_ack));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(trace_ack, 0, sizeof(*trace_ack));
+ sts = __pmtracedecodeack((__pmPDU *)trace_ack, &ack);
+ fprintf(stderr, " __pmtracedecodeack: sts = %d (%s)\n", sts, pmtraceerrstr(sts));
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(trace_ack, 0, sizeof(*trace_ack));
+ trace_ack->hdr.len = sizeof(*trace_ack);
+ trace_ack->hdr.type = TRACE_PDU_ACK;
+ sts = __pmtracedecodeack((__pmPDU *)trace_ack, &ack);
+ fprintf(stderr, " __pmtracedecodeack: sts = %d (%s)\n", sts, pmtraceerrstr(sts));
+
+ free(trace_ack);
+}
+
+static void
+decode_trace_data(const char *name)
+{
+ int sts, len, type, p, *ip;
+ char *tag;
+ double data;
+ struct trace_data {
+ __pmTracePDUHdr hdr;
+ struct {
+#ifdef HAVE_BITFIELDS_LTOR
+ unsigned int version : 8;
+ unsigned int taglen : 8;
+ unsigned int tagtype : 8;
+ unsigned int protocol : 1;
+ unsigned int pad : 7;
+#else
+ unsigned int pad : 7;
+ unsigned int protocol : 1;
+ unsigned int tagtype : 8;
+ unsigned int taglen : 8;
+ unsigned int version : 8;
+#endif
+ } bits;
+ double value;
+ char tag[0];
+ } *trace_data;
+
+ trace_data = (struct trace_data *)malloc(sizeof(*trace_data));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(trace_data, 0, sizeof(*trace_data));
+ sts = __pmtracedecodedata((__pmPDU *)trace_data, &tag, &len, &type, &p, &data);
+ fprintf(stderr, " __pmtracedecodedata: sts = %d (%s)\n", sts, pmtraceerrstr(sts));
+ if (sts >= 0) { free(tag); }
+
+ fprintf(stderr, "[%s] checking large taglen field\n", name);
+ memset(trace_data, 0, sizeof(*trace_data));
+ trace_data->hdr.len = sizeof(*trace_data);
+ trace_data->hdr.type = TRACE_PDU_DATA;
+ trace_data->bits.version = TRACE_PDU_VERSION;
+ trace_data->bits.taglen = CHAR_MAX - 1;
+ ip = (int *)&trace_data->bits;
+ *ip = htonl(*ip);
+ sts = __pmtracedecodedata((__pmPDU *)trace_data, &tag, &len, &type, &p, &data);
+ fprintf(stderr, " __pmtracedecodedata: sts = %d (%s)\n", sts, pmtraceerrstr(sts));
+ if (sts >= 0) { free(tag); }
+
+ fprintf(stderr, "[%s] checking negative taglen field\n", name);
+ memset(trace_data, 0, sizeof(*trace_data));
+ trace_data->hdr.len = sizeof(*trace_data);
+ trace_data->hdr.type = TRACE_PDU_DATA;
+ trace_data->bits.version = TRACE_PDU_VERSION;
+ trace_data->bits.taglen = -1;
+ ip = (int *)&trace_data->bits;
+ *ip = htonl(*ip);
+ sts = __pmtracedecodedata((__pmPDU *)trace_data, &tag, &len, &type, &p, &data);
+ fprintf(stderr, " __pmtracedecodedata: sts = %d (%s)\n", sts, pmtraceerrstr(sts));
+ if (sts >= 0) { free(tag); }
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(trace_data, 0, sizeof(*trace_data));
+ trace_data->hdr.len = sizeof(*trace_data);
+ trace_data->hdr.type = TRACE_PDU_DATA;
+ trace_data->bits.version = TRACE_PDU_VERSION;
+ trace_data->bits.taglen = 2;
+ ip = (int *)&trace_data->bits;
+ *ip = htonl(*ip);
+ sts = __pmtracedecodedata((__pmPDU *)trace_data, &tag, &len, &type, &p, &data);
+ fprintf(stderr, " __pmtracedecodedata: sts = %d (%s)\n", sts, pmtraceerrstr(sts));
+ if (sts >= 0) { free(tag); }
+
+ free(trace_data);
+}
+
+typedef void (*decode_t)(const char *);
+
+struct pdu {
+ const char *name;
+ decode_t decode;
+} pdus[] = {
+ { "cred", decode_creds },
+ { "error", decode_error },
+ { "profile", decode_profile },
+ { "fetch", decode_fetch },
+ { "desc_req", decode_desc_req },
+ { "desc", decode_desc },
+ { "instance_req", decode_instance_req },
+ { "instance", decode_instance },
+ { "pmns_ids", decode_pmns_ids },
+ { "pmns_names", decode_pmns_names },
+ { "pmns_child", decode_pmns_child },
+ { "pmns_traverse", decode_pmns_traverse },
+ { "log_control", decode_log_control },
+ { "log_status", decode_log_status },
+ { "log_request", decode_log_request },
+ { "result", decode_result },
+ { "text_req", decode_text_req },
+ { "text", decode_text },
+ { "trace_ack", decode_trace_ack },
+ { "trace_data", decode_trace_data },
+ { "auth", decode_auth },
+};
+
+int
+main(int argc, char **argv)
+{
+ int c, d;
+ int sts, errflag = 0;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:?")) != EOF) {
+ switch (c) {
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind < argc-1) {
+ fprintf(stderr, "Usage: %s [-D n]\n", pmProgname);
+ exit(1);
+ }
+
+ if (argc == optind) {
+ for (d = 0; d < sizeof(pdus)/sizeof(struct pdu); d++)
+ pdus[d].decode(pdus[d].name);
+ } else {
+ for (c = 0; c < (argc - optind); c++)
+ for (d = 0; d < sizeof(pdus)/sizeof(struct pdu); d++)
+ if (strcmp(argv[optind + c], pdus[d].name) == 0)
+ pdus[d].decode(pdus[d].name);
+ }
+ exit(0);
+}