From d0c213f1817f2649ad08cd98c906445033306bfa Mon Sep 17 00:00:00 2001 From: Levi Neely <141506390+lneely@users.noreply.github.com> Date: Sun, 8 Mar 2026 14:55:21 +0100 Subject: [PATCH] Add overflow-safe allocation wrapper pmem_calloc_safe() (#369) * Add overflow-safe allocation wrappers to pmem module * Replace malloc(nmemb*size) with pmem_calloc_safe in high-risk sites --------- Co-authored-by: Levi Neely --- pclsync/papi.c | 9 +++--- pclsync/pbusinessaccount.c | 57 ++++++++++++++++++++++++++++++++------ pclsync/pmem.c | 9 ++++++ pclsync/pmem.h | 2 ++ pclsync/ptools.c | 16 +++++++++-- 5 files changed, 78 insertions(+), 15 deletions(-) diff --git a/pclsync/papi.c b/pclsync/papi.c index 853c9e8..a4f243a 100644 --- a/pclsync/papi.c +++ b/pclsync/papi.c @@ -39,6 +39,7 @@ #include "psynclib.h" #include "ptimer.h" #include "pdbg.h" +#include "pmem.h" /* commented definitions are unused, but kept because they may be @@ -313,7 +314,7 @@ static binresult *do_parse_result(unsigned char **restrict indata, arr = NULL; cnt = 0; alloc = 128; - arr = (binresult **)malloc(sizeof(binresult *) * alloc); + arr = (binresult **)pmem_calloc_safe(alloc, sizeof(binresult *)); if (!arr) return NULL; while (**indata != RPARAM_END) { @@ -346,7 +347,7 @@ static binresult *do_parse_result(unsigned char **restrict indata, arr = NULL; cnt = 0; alloc = 32; - arr = (struct _hashpair *)malloc(sizeof(struct _hashpair) * alloc); + arr = (struct _hashpair *)pmem_calloc_safe(alloc, sizeof(struct _hashpair)); if (!arr) return NULL; while (**indata != RPARAM_END) { @@ -398,10 +399,10 @@ static binresult *parse_result(unsigned char *data, size_t datalen) { retlen = calc_ret_len(&datac, &datalenc, &strcnt); if (retlen == -1) return NULL; - datac = malloc(sizeof(unsigned char) * retlen); + datac = pmem_calloc_safe(retlen, sizeof(unsigned char)); if (!datac) return NULL; - strings = malloc(sizeof(binresult *) * strcnt); + strings = pmem_calloc_safe(strcnt, sizeof(binresult *)); if (!strings) { free(datac); return NULL; diff --git a/pclsync/pbusinessaccount.c b/pclsync/pbusinessaccount.c index d561494..99a5fe2 100644 --- a/pclsync/pbusinessaccount.c +++ b/pclsync/pbusinessaccount.c @@ -32,6 +32,7 @@ #include "pnetlibs.h" #include "psys.h" #include "psql.h" +#include "pmem.h" #include @@ -103,12 +104,18 @@ int do_psync_account_stopshare(psync_shareid_t usershareids[], int nusershareid, if (unlikely(numparam == 1)) return -3; - t = (binparam *)malloc(numparam * sizeof(binparam)); + t = (binparam *)pmem_calloc_safe(numparam, sizeof(binparam)); + if (!t) + return -1; init_param_str(t, "auth", psync_my_auth); if (nusershareid) { - ids1 = (char *)malloc(nusershareid * FOLDERID_ENTRY_SIZE); + ids1 = (char *)pmem_calloc_safe(nusershareid, FOLDERID_ENTRY_SIZE); + if (!ids1) { + free(t); + return -1; + } idsp = ids1; for (i = 0; i < nusershareid; ++i) { k = sprintf(idsp, "%lld", (long long)usershareids[i]); @@ -124,7 +131,13 @@ int do_psync_account_stopshare(psync_shareid_t usershareids[], int nusershareid, } if (nteamshareid) { - ids2 = (char *)malloc(nteamshareid * FOLDERID_ENTRY_SIZE); + ids2 = (char *)pmem_calloc_safe(nteamshareid, FOLDERID_ENTRY_SIZE); + if (!ids2) { + if (nusershareid) + free(ids1); + free(t); + return -1; + } idsp = ids2; for (i = 0; i < nteamshareid; ++i) { k = sprintf(idsp, "%lld", (long long)teamshareids[i]); @@ -209,14 +222,25 @@ int do_psync_account_modifyshare(psync_shareid_t usrshrids[], uint32_t uperms[], if (unlikely(numparam == 1)) return -3; - t = (binparam *)malloc(numparam * sizeof(binparam)); + t = (binparam *)pmem_calloc_safe(numparam, sizeof(binparam)); + if (!t) + return -1; init_param_str(t, "auth", psync_my_auth); if (nushid) { - ids1 = (char *)malloc(nushid * FOLDERID_ENTRY_SIZE); + ids1 = (char *)pmem_calloc_safe(nushid, FOLDERID_ENTRY_SIZE); + if (!ids1) { + free(t); + return -1; + } idsp = ids1; - perms1 = (char *)malloc(nushid * FOLDERID_ENTRY_SIZE); + perms1 = (char *)pmem_calloc_safe(nushid, FOLDERID_ENTRY_SIZE); + if (!perms1) { + free(ids1); + free(t); + return -1; + } permsp = perms1; for (i = 0; i < nushid; ++i) { k = sprintf(idsp, "%lld", (long long)usrshrids[i]); @@ -241,9 +265,26 @@ int do_psync_account_modifyshare(psync_shareid_t usrshrids[], uint32_t uperms[], } if (ntmshid) { - ids2 = (char *)malloc(ntmshid * FOLDERID_ENTRY_SIZE); + ids2 = (char *)pmem_calloc_safe(ntmshid, FOLDERID_ENTRY_SIZE); + if (!ids2) { + if (nushid) { + free(perms1); + free(ids1); + } + free(t); + return -1; + } idsp = ids2; - perms2 = (char *)malloc(ntmshid * FOLDERID_ENTRY_SIZE); + perms2 = (char *)pmem_calloc_safe(ntmshid, FOLDERID_ENTRY_SIZE); + if (!perms2) { + free(ids2); + if (nushid) { + free(perms1); + free(ids1); + } + free(t); + return -1; + } permsp = perms2; for (i = 0; i < ntmshid; ++i) { diff --git a/pclsync/pmem.c b/pclsync/pmem.c index e751eaa..af5f074 100644 --- a/pclsync/pmem.c +++ b/pclsync/pmem.c @@ -1,4 +1,6 @@ #include +#include +#include #include "pcompiler.h" #include "psql.h" @@ -60,3 +62,10 @@ int pmem_munlock(void *ptr, size_t size) { void pmem_reset(void *ptr, size_t size) { madvise(ptr, size, MADV_DONTNEED); } + +void *pmem_calloc_safe(size_t nmemb, size_t size) { + if (nmemb != 0 && size > SIZE_MAX / nmemb) { + return NULL; + } + return calloc(nmemb, size); +} diff --git a/pclsync/pmem.h b/pclsync/pmem.h index 394ba1e..685c15d 100644 --- a/pclsync/pmem.h +++ b/pclsync/pmem.h @@ -2,6 +2,7 @@ #define __PMEM_H #include +#include void *pmem_mmap(size_t size); void *pmem_mmap_safe(size_t size); @@ -9,5 +10,6 @@ int pmem_munmap(void *ptr, size_t size); int pmem_mlock(void *ptr, size_t size); int pmem_munlock(void *ptr, size_t size); void pmem_reset(void *ptr, size_t size); +void *pmem_calloc_safe(size_t nmemb, size_t size); #endif \ No newline at end of file diff --git a/pclsync/ptools.c b/pclsync/ptools.c index 115021c..eeaf35f 100644 --- a/pclsync/ptools.c +++ b/pclsync/ptools.c @@ -50,6 +50,7 @@ #include "psettings.h" #include "psql.h" #include "ptools.h" +#include "pmem.h" #define PTOOLS_MAX_PARAMS 30 @@ -135,7 +136,10 @@ int ptools_create_backend_event(const char *binapi, const char *category, paramsLocal[5] = (binparam)PAPI_NUM(EPARAM_TIME, etime); if (pCnt > 0) { - keyParams = (char *)malloc(258 * pCnt); + keyParams = (char *)pmem_calloc_safe(pCnt, 258); + if (!keyParams) { + return -1; + } keyParams[0] = 0; for (i = 0; i < pCnt; i++) { @@ -371,7 +375,10 @@ int ptools_backend_call(const char *binapi, const char *wsPath, if (strlen(payloadName) > 0) { payload = (binresult *)papi_find_result2(res, payloadName, PARAM_HASH); - *resData = (binresult *)malloc(payload->length * sizeof(binresult)); + *resData = (binresult *)pmem_calloc_safe(payload->length, sizeof(binresult)); + if (!*resData) { + return -1; + } memcpy(*resData, payload, (payload->length * sizeof(binresult))); } } @@ -450,7 +457,10 @@ void ptools_send_psyncs_event(const char *binapi, const char *auth) { int intRes; int syncCnt = 0; - errMsg = (char *)malloc(1024 * sizeof(char)); + errMsg = (char *)pmem_calloc_safe(1024, sizeof(char)); + if (!errMsg) { + return; + } errMsg[0] = 0; time(&rawtime);