From 5ad532b692341f558778ab32d8449852ed7900b5 Mon Sep 17 00:00:00 2001 From: Levi Neely <141506390+lneely@users.noreply.github.com> Date: Sun, 8 Mar 2026 13:11:41 +0100 Subject: [PATCH] Add NULL check audit to high-risk allocations (#366) Co-authored-by: Levi Neely --- pclsync/papi.c | 28 +++++++++- pclsync/pfstasks.c | 120 +++++++++++++++++++++++++++++++++++++++++++ pclsync/pnetlibs.c | 95 +++++++++++++++++++++++++++++++++- pclsync/ppagecache.c | 80 ++++++++++++++++++++++++++++- 4 files changed, 319 insertions(+), 4 deletions(-) diff --git a/pclsync/papi.c b/pclsync/papi.c index ced472f..853c9e8 100644 --- a/pclsync/papi.c +++ b/pclsync/papi.c @@ -314,10 +314,18 @@ static binresult *do_parse_result(unsigned char **restrict indata, cnt = 0; alloc = 128; arr = (binresult **)malloc(sizeof(binresult *) * alloc); + if (!arr) + return NULL; while (**indata != RPARAM_END) { if (cnt == alloc) { + binresult **tmp; alloc *= 2; - arr = (binresult **)realloc(arr, sizeof(binresult *) * alloc); + tmp = (binresult **)realloc(arr, sizeof(binresult *) * alloc); + if (!tmp) { + free(arr); + return NULL; + } + arr = tmp; } arr[cnt++] = do_parse_result(indata, odata, strings, nextstrid); } @@ -339,11 +347,19 @@ static binresult *do_parse_result(unsigned char **restrict indata, cnt = 0; alloc = 32; arr = (struct _hashpair *)malloc(sizeof(struct _hashpair) * alloc); + if (!arr) + return NULL; while (**indata != RPARAM_END) { if (cnt == alloc) { + struct _hashpair *tmp; alloc *= 2; - arr = (struct _hashpair *)realloc(arr, sizeof(struct _hashpair) * + tmp = (struct _hashpair *)realloc(arr, sizeof(struct _hashpair) * alloc); + if (!tmp) { + free(arr); + return NULL; + } + arr = tmp; } key = do_parse_result(indata, odata, strings, nextstrid); arr[cnt].value = do_parse_result(indata, odata, strings, nextstrid); @@ -383,7 +399,13 @@ static binresult *parse_result(unsigned char *data, size_t datalen) { if (retlen == -1) return NULL; datac = malloc(sizeof(unsigned char) * retlen); + if (!datac) + return NULL; strings = malloc(sizeof(binresult *) * strcnt); + if (!strings) { + free(datac); + return NULL; + } strcnt = 0; res = do_parse_result(&data, &datac, strings, &strcnt); free(strings); @@ -535,6 +557,8 @@ unsigned char *papi_prepare(const char *command, size_t cmdlen, if (pdbg_unlikely(plen > 0xffff)) return NULL; sdata = data = (unsigned char *)malloc(plen + 2 + additionalalloc); + if (!data) + return NULL; memcpy(data, &plen, 2); data += 2; if (datalen != -1) { diff --git a/pclsync/pfstasks.c b/pclsync/pfstasks.c index 1ff8d19..ba87534 100644 --- a/pclsync/pfstasks.c +++ b/pclsync/pfstasks.c @@ -123,6 +123,8 @@ pfs_task_get_or_create_folder_tasks_locked(psync_fsfolderid_t folderid) { } folder = malloc(sizeof(psync_fstask_folder_t)); + if (!folder) + return NULL; memset(folder, 0, sizeof(psync_fstask_folder_t)); if (d < 0) @@ -445,6 +447,10 @@ int pfs_task_mkdir(psync_fsfolderid_t folderid, const char *name, len++; task = (psync_fstask_mkdir_t *)malloc( offsetof(psync_fstask_mkdir_t, name) + len); + if (!task) { + pfs_task_release_folder_tasks_locked(folder); + return -ENOMEM; + } task->taskid = taskid; task->ctime = task->mtime = ctime; task->folderid = -(psync_fsfolderid_t)taskid; @@ -649,6 +655,10 @@ int pfs_task_rmdir(psync_fsfolderid_t folderid, uint32_t parentflags, len++; task = (psync_fstask_rmdir_t *)malloc( offsetof(psync_fstask_rmdir_t, name) + len); + if (!task) { + pfs_task_release_folder_tasks_locked(folder); + return -ENOMEM; + } task->taskid = taskid; task->folderid = cfolderid; memcpy(task->name, name, len); @@ -696,6 +706,8 @@ psync_fstask_creat_t *pfs_task_add_creat(psync_fstask_folder_t *folder, len++; un = (psync_fstask_unlink_t *)malloc( offsetof(psync_fstask_unlink_t, name) + len); + if (!un) + return NULL; un->fileid = -(psync_fsfileid_t)taskid; un->taskid = taskid; memcpy(un->name, name, len); @@ -703,6 +715,11 @@ psync_fstask_creat_t *pfs_task_add_creat(psync_fstask_folder_t *folder, &folder->unlinks, offsetof(psync_fstask_unlink_t, name), &un->tree); task = (psync_fstask_creat_t *)malloc( offsetof(psync_fstask_creat_t, name) + len); + if (!task) { + ptree_del(&folder->unlinks, &un->tree); + free(un); + return NULL; + } task->fileid = -(psync_fsfileid_t)taskid; task->rfileid = fileid; task->taskid = taskid; @@ -771,6 +788,8 @@ pfs_task_add_modified_file(psync_fstask_folder_t *folder, const char *name, len++; un = (psync_fstask_unlink_t *)malloc( offsetof(psync_fstask_unlink_t, name) + len); + if (!un) + return NULL; un->fileid = fileid; un->taskid = taskid; memcpy(un->name, name, len); @@ -778,6 +797,11 @@ pfs_task_add_modified_file(psync_fstask_folder_t *folder, const char *name, &folder->unlinks, offsetof(psync_fstask_unlink_t, name), &un->tree); task = (psync_fstask_creat_t *)malloc( offsetof(psync_fstask_creat_t, name) + len); + if (!task) { + ptree_del(&folder->unlinks, &un->tree); + free(un); + return NULL; + } task->fileid = -(psync_fsfileid_t)taskid; task->rfileid = fileid; task->taskid = taskid; @@ -860,6 +884,10 @@ int pfs_task_add_local_creat_static(psync_fsfolderid_t folderid, len++; un = (psync_fstask_unlink_t *)malloc( offsetof(psync_fstask_unlink_t, name) + len); + if (!un) { + ret = -ENOMEM; + goto ex; + } un->taskid = psync_local_taskid; un->fileid = 0; memcpy(un->name, name, len); @@ -868,6 +896,10 @@ int pfs_task_add_local_creat_static(psync_fsfolderid_t folderid, addlen = pfs_task_creat_local_offset(len - 1); cr = (psync_fstask_creat_t *)malloc(addlen + sizeof(psync_fstask_local_creat_t)); + if (!cr) { + ret = -ENOMEM; + goto ex; + } cr->fileid = 0; cr->rfileid = 0; cr->taskid = psync_local_taskid; @@ -1067,6 +1099,10 @@ int pfs_task_unlink(psync_fsfolderid_t folderid, const char *name) { len++; task = (psync_fstask_unlink_t *)malloc( offsetof(psync_fstask_unlink_t, name) + len); + if (!task) { + pfs_task_release_folder_tasks_locked(folder); + return -ENOMEM; + } task->taskid = taskid; task->fileid = fileid; memcpy(task->name, name, len); @@ -1090,6 +1126,8 @@ static void add_history_record(psync_fileid_t fileid, psync_folderid_t folderid, len = strlen(name) + 1; rec = (file_history_record *)malloc( offsetof(file_history_record, name) + len); + if (!rec) + return; rec->folderid = folderid; memcpy(rec->name, name, len); pcache_add(key, rec, PSYNC_FS_FILE_LOC_HIST_SEC, free, 1); @@ -1170,6 +1208,10 @@ int pfs_task_rename_file(psync_fsfileid_t fileid, nlen++; rm = (psync_fstask_unlink_t *)malloc( offsetof(psync_fstask_unlink_t, name) + nlen); + if (!rm) { + pfs_task_release_folder_tasks_locked(folder); + return -ENOMEM; + } rm->taskid = ftaskid; rm->fileid = fileid; memcpy(rm->name, name, nlen); @@ -1192,6 +1234,10 @@ int pfs_task_rename_file(psync_fsfileid_t fileid, } rm = (psync_fstask_unlink_t *)malloc( offsetof(psync_fstask_unlink_t, name) + nnlen); + if (!rm) { + pfs_task_release_folder_tasks_locked(folder); + return -ENOMEM; + } rm->fileid = fileid; rm->taskid = ttaskid; memcpy(rm->name, new_name, nnlen); @@ -1199,6 +1245,10 @@ int pfs_task_rename_file(psync_fsfileid_t fileid, &folder->unlinks, offsetof(psync_fstask_unlink_t, name), &rm->tree); cr = (psync_fstask_creat_t *)malloc( offsetof(psync_fstask_creat_t, name) + nnlen); + if (!cr) { + pfs_task_release_folder_tasks_locked(folder); + return -ENOMEM; + } cr->fileid = fileid; cr->rfileid = rfileid; cr->taskid = ttaskid; @@ -1393,6 +1443,10 @@ int pfs_task_rename_folder(psync_fsfolderid_t folderid, nlen++; rm = (psync_fstask_rmdir_t *)malloc( offsetof(psync_fstask_rmdir_t, name) + nlen); + if (!rm) { + pfs_task_release_folder_tasks_locked(folder); + return -ENOMEM; + } rm->taskid = ftaskid; rm->folderid = folderid; @@ -1415,6 +1469,10 @@ int pfs_task_rename_folder(psync_fsfolderid_t folderid, nnlen++; rm = (psync_fstask_rmdir_t *)malloc( offsetof(psync_fstask_rmdir_t, name) + nnlen); + if (!rm) { + pfs_task_release_folder_tasks_locked(folder); + return -ENOMEM; + } rm->taskid = ttaskid; rm->folderid = folderid; memcpy(rm->name, new_name, nnlen); @@ -1423,6 +1481,10 @@ int pfs_task_rename_folder(psync_fsfolderid_t folderid, mk = (psync_fstask_mkdir_t *)malloc( offsetof(psync_fstask_mkdir_t, name) + nnlen); + if (!mk) { + pfs_task_release_folder_tasks_locked(folder); + return -ENOMEM; + } mk->taskid = ttaskid; mk->folderid = folderid; mk->flags = targetflags; @@ -1762,6 +1824,10 @@ static void psync_init_task_mkdir(psync_variant_row row) { len++; task = (psync_fstask_mkdir_t *)malloc( offsetof(psync_fstask_mkdir_t, name) + len); + if (!task) { + pfs_task_release_folder_tasks_locked(folder); + return; + } task->taskid = taskid; task->ctime = task->mtime = ctime; task->folderid = -(psync_fsfolderid_t)taskid; @@ -1798,6 +1864,10 @@ static void psync_init_task_rmdir(psync_variant_row row) { len++; task = (psync_fstask_rmdir_t *)malloc( offsetof(psync_fstask_rmdir_t, name) + len); + if (!task) { + pfs_task_release_folder_tasks_locked(folder); + return; + } task->taskid = taskid; task->folderid = cfolderid; memcpy(task->name, name, len); @@ -1822,6 +1892,10 @@ static void psync_init_task_creat(psync_variant_row row) { len++; un = (psync_fstask_unlink_t *)malloc( offsetof(psync_fstask_unlink_t, name) + len); + if (!un) { + pfs_task_release_folder_tasks_locked(folder); + return; + } un->fileid = -(psync_fsfileid_t)taskid; un->taskid = taskid; memcpy(un->name, name, len); @@ -1829,6 +1903,10 @@ static void psync_init_task_creat(psync_variant_row row) { &folder->unlinks, offsetof(psync_fstask_unlink_t, name), &un->tree); task = (psync_fstask_creat_t *)malloc( offsetof(psync_fstask_creat_t, name) + len); + if (!task) { + pfs_task_release_folder_tasks_locked(folder); + return; + } task->fileid = -(psync_fsfileid_t)taskid; task->rfileid = psync_get_number(row[3]); task->taskid = taskid; @@ -1858,6 +1936,10 @@ static void psync_init_do_task_unlink(uint64_t taskid, namelen++; task = (psync_fstask_unlink_t *)malloc( offsetof(psync_fstask_unlink_t, name) + namelen); + if (!task) { + pfs_task_release_folder_tasks_locked(folder); + return; + } task->taskid = taskid; task->fileid = fileid; memcpy(task->name, name, namelen); @@ -1900,6 +1982,10 @@ static void psync_init_task_renfile_from(psync_variant_row row) { len++; rm = (psync_fstask_unlink_t *)malloc( offsetof(psync_fstask_unlink_t, name) + len); + if (!rm) { + pfs_task_release_folder_tasks_locked(folder); + return; + } rm->taskid = psync_get_number(row[0]); rm->fileid = psync_get_snumber(row[3]); memcpy(rm->name, name, len); @@ -1932,6 +2018,10 @@ static void psync_init_task_renfile_to(psync_variant_row row) { fileid = psync_get_snumber(row[3]); un = (psync_fstask_unlink_t *)malloc( offsetof(psync_fstask_unlink_t, name) + len); + if (!un) { + pfs_task_release_folder_tasks_locked(folder); + return; + } un->fileid = fileid; un->taskid = taskid; memcpy(un->name, name, len); @@ -1939,6 +2029,10 @@ static void psync_init_task_renfile_to(psync_variant_row row) { &folder->unlinks, offsetof(psync_fstask_creat_t, name), &un->tree); cr = (psync_fstask_creat_t *)malloc( offsetof(psync_fstask_creat_t, name) + len); + if (!cr) { + pfs_task_release_folder_tasks_locked(folder); + return; + } cr->fileid = fileid; cr->rfileid = psync_get_number(row[7]); cr->taskid = taskid; @@ -1969,6 +2063,10 @@ static void psync_init_task_renfolder_from(psync_variant_row row) { len++; rm = (psync_fstask_rmdir_t *)malloc( offsetof(psync_fstask_rmdir_t, name) + len); + if (!rm) { + pfs_task_release_folder_tasks_locked(folder); + return; + } rm->taskid = psync_get_number(row[0]); rm->folderid = psync_get_snumber(row[8]); memcpy(rm->name, name, len); @@ -1994,6 +2092,10 @@ static void psync_init_task_renfolder_to(psync_variant_row row) { folderid = psync_get_snumber(row[8]); rm = (psync_fstask_rmdir_t *)malloc( offsetof(psync_fstask_rmdir_t, name) + len); + if (!rm) { + pfs_task_release_folder_tasks_locked(folder); + return; + } rm->taskid = taskid; rm->folderid = folderid; memcpy(rm->name, name, len); @@ -2001,6 +2103,10 @@ static void psync_init_task_renfolder_to(psync_variant_row row) { &folder->rmdirs, offsetof(psync_fstask_rmdir_t, name), &rm->tree); mk = (psync_fstask_mkdir_t *)malloc( offsetof(psync_fstask_mkdir_t, name) + len); + if (!mk) { + pfs_task_release_folder_tasks_locked(folder); + return; + } mk->taskid = taskid; mk->folderid = folderid; mk->flags = psync_get_number(row[7]); @@ -2034,6 +2140,10 @@ static void psync_init_task_modify(psync_variant_row row) { len++; un = (psync_fstask_unlink_t *)malloc( offsetof(psync_fstask_unlink_t, name) + len); + if (!un) { + pfs_task_release_folder_tasks_locked(folder); + return; + } un->fileid = psync_get_snumber(row[3]); un->taskid = taskid; memcpy(un->name, name, len); @@ -2041,6 +2151,10 @@ static void psync_init_task_modify(psync_variant_row row) { &folder->unlinks, offsetof(psync_fstask_unlink_t, name), &un->tree); cr = (psync_fstask_creat_t *)malloc( offsetof(psync_fstask_creat_t, name) + len); + if (!cr) { + pfs_task_release_folder_tasks_locked(folder); + return; + } cr->fileid = -(psync_fsfileid_t)cr->taskid; cr->rfileid = psync_get_number(row[3]); cr->taskid = taskid; @@ -2113,6 +2227,8 @@ void pfs_task_add_banned_folder(psync_fsfolderid_t folderid, len = strlen(name) + 1; mk = (psync_fstask_mkdir_t *)malloc( offsetof(psync_fstask_mkdir_t, name) + len); + if (!mk) + return; mk->taskid = 0; mk->ctime = mk->mtime = 0; mk->folderid = 0; @@ -2121,6 +2237,10 @@ void pfs_task_add_banned_folder(psync_fsfolderid_t folderid, memcpy(mk->name, name, len); rm = (psync_fstask_rmdir_t *)malloc( offsetof(psync_fstask_rmdir_t, name) + len); + if (!rm) { + free(mk); + return; + } rm->taskid = 0; rm->folderid = 0; memcpy(rm->name, name, len); diff --git a/pclsync/pnetlibs.c b/pclsync/pnetlibs.c index 43cd7a0..1ff455a 100644 --- a/pclsync/pnetlibs.c +++ b/pclsync/pnetlibs.c @@ -413,6 +413,10 @@ int psync_get_local_file_checksum(const char *restrict filename, if (fd == INVALID_HANDLE_VALUE) return PSYNC_NET_PERMFAIL; buff = malloc(PSYNC_COPY_BUFFER_SIZE); + if (!buff) { + pfile_close(fd); + return PSYNC_NET_TEMPFAIL; + } retry: if (pdbg_unlikely(fstat(fd, &st))) goto err1; @@ -485,6 +489,10 @@ int psync_get_local_file_checksum_part(const char *restrict filename, if (pdbg_unlikely(fstat(fd, &st))) goto err1; buff = malloc(PSYNC_COPY_BUFFER_SIZE); + if (!buff) { + pfile_close(fd); + return PSYNC_NET_TEMPFAIL; + } psync_hash_init(&hctx); psync_hash_init(&hctxp); rsz = pfile_stat_size(&st); @@ -569,6 +577,11 @@ int psync_copy_local_file_if_checksum_matches(const char *source, goto err1; psync_hash_init(&hctx); buff = malloc(PSYNC_COPY_BUFFER_SIZE); + if (!buff) { + pfile_close(dfd); + pfile_close(sfd); + return PSYNC_NET_TEMPFAIL; + } while (fsize) { if (fsize > PSYNC_COPY_BUFFER_SIZE) rrd = PSYNC_COPY_BUFFER_SIZE; @@ -859,6 +872,10 @@ psync_http_socket *psync_http_connect(const char *host, const char *path, } else pdbg_logf(D_NOTICE, "got connection to %s from cache", host); readbuff = malloc(PSYNC_HTTP_RESP_BUFFER); + if (!readbuff) { + psock_close(sock); + goto err0; + } if (!addhdr) addhdr = ""; if (from || to) { @@ -953,6 +970,11 @@ ex: } hsock = (psync_http_socket *)malloc( offsetof(psync_http_socket, cachekey) + cl); + if (!hsock) { + free(readbuff); + psock_close(sock); + goto err0; + } hsock->sock = sock; hsock->readbuff = readbuff; hsock->contentlength = clen; @@ -1078,6 +1100,8 @@ connect_cache_tree_node_t *connect_cache_create_node(const char *host) { len = strlen(host) + 1; res = (connect_cache_tree_node_t *)malloc( offsetof(connect_cache_tree_node_t, host) + len); + if (!res) + return NULL; res->usessl = psync_setting_get_bool(_PS(usessl)); res->haswaiter = 0; res->ready = 0; @@ -1266,8 +1290,17 @@ psync_http_socket *psync_http_connect_multihost(const binresult *hosts, } hsock = (psync_http_socket *)malloc( offsetof(psync_http_socket, cachekey) + cl); + if (!hsock) { + psock_close(sock); + return NULL; + } hsock->sock = sock; hsock->readbuff = malloc(PSYNC_HTTP_RESP_BUFFER); + if (!hsock->readbuff) { + free(hsock); + psock_close(sock); + return NULL; + } ; hsock->contentlength = -1; hsock->readbytes = 0; @@ -1309,8 +1342,17 @@ psync_http_connect_multihost_from_cache(const binresult *hosts, return NULL; hsock = (psync_http_socket *)malloc( offsetof(psync_http_socket, cachekey) + cl); + if (!hsock) { + psock_close(sock); + return NULL; + } hsock->sock = sock; hsock->readbuff = malloc(PSYNC_HTTP_RESP_BUFFER); + if (!hsock->readbuff) { + free(hsock); + psock_close(sock); + return NULL; + } ; hsock->contentlength = -1; hsock->readbytes = 0; @@ -1508,6 +1550,8 @@ char *psync_url_decode(const char *s) { char unsigned ch1, ch2; slen = strlen(s); ret = p = (char *)malloc(slen + 1); + if (!ret) + return NULL; while (slen--) { if (*s == '+') *p = ' '; @@ -1591,6 +1635,8 @@ static int psync_net_get_checksums(psock_t *api, psync_fileid_t fileid, cs = (psync_file_checksums *)malloc( offsetof(psync_file_checksums, blocks) + (sizeof(psync_block_checksum) + sizeof(uint32_t)) * i); + if (!cs) + return PSYNC_NET_TEMPFAIL; cs->filesize = hdr.filesize; cs->blocksize = hdr.blocksize; cs->blockcnt = i; @@ -1655,6 +1701,8 @@ static int psync_net_get_upload_checksums(psock_t *api, cs = (psync_file_checksums *)malloc( offsetof(psync_file_checksums, blocks) + (sizeof(psync_block_checksum) + sizeof(uint32_t)) * i); + if (!cs) + return PSYNC_NET_TEMPFAIL; cs->filesize = hdr.filesize; cs->blocksize = hdr.blocksize; cs->blockcnt = i; @@ -1687,6 +1735,8 @@ static psync_block_checksum psync_block_checksum **ret; uint32_t i; ret=malloc(sizeof(psync_block_checksum *) * checksums->blockcnt); + if (!ret) + return NULL; for (i=0; iblockcnt; i++) ret[i]=&checksums->blocks[i]; qsort(ret, checksums->blockcnt, sizeof(psync_block_checksum *), @@ -1725,6 +1775,8 @@ psync_net_create_hash(const psync_file_checksums *checksums) { } h = (psync_file_checksum_hash *)malloc( offsetof(psync_file_checksum_hash, elements) + sizeof(uint32_t) * cnt); + if (!h) + return NULL; h->elementcnt = cnt; memset(h->elements, 0, sizeof(uint32_t) * cnt); for (i = 0; i < checksums->blockcnt; i++) { @@ -1942,6 +1994,10 @@ static void psync_net_check_file_for_blocks( buffersize = PSYNC_COPY_BUFFER_SIZE; hbuffersize = buffersize / 2; buff = malloc(buffersize); + if (!buff) { + pfile_close(fd); + return; + } rd = pfile_read(fd, buff, hbuffersize); if (unlikely(rd < (ssize_t)hbuffersize)) { if (rd < (ssize_t)checksums->blocksize) { @@ -2037,11 +2093,20 @@ int psync_net_download_ranges(psync_list *ranges, psync_fileid_t fileid, } hash = psync_net_create_hash(checksums); blockactions = malloc(sizeof(psync_block_action) * checksums->blockcnt); + if (!blockactions) { + free(checksums); + return PSYNC_NET_TEMPFAIL; + } memset(blockactions, 0, sizeof(psync_block_action) * checksums->blockcnt); for (i = 0; i < filecnt; i++) psync_net_check_file_for_blocks(files[i], checksums, hash, blockactions, i); free(hash); range = malloc(sizeof(psync_range_list_t)); + if (!range) { + free(blockactions); + free(checksums); + return PSYNC_NET_TEMPFAIL; + } range->len = checksums->blocksize; range->type = blockactions[0].type; if (range->type == PSYNC_RANGE_COPY) { @@ -2062,6 +2127,12 @@ int psync_net_download_ranges(psync_list *ranges, psync_fileid_t fileid, (range->filename != files[blockactions[i].idx] || range->off + range->len != blockactions[i].off))) { range = malloc(sizeof(psync_range_list_t)); + if (!range) { + psync_list_for_each_element_call(ranges, psync_range_list_t, list, free); + free(blockactions); + free(checksums); + return PSYNC_NET_TEMPFAIL; + } range->len = bs; range->type = blockactions[i].type; if (range->type == PSYNC_RANGE_COPY) { @@ -2078,6 +2149,8 @@ int psync_net_download_ranges(psync_list *ranges, psync_fileid_t fileid, return PSYNC_NET_OK; fulldownload: range = malloc(sizeof(psync_range_list_t)); + if (!range) + return PSYNC_NET_TEMPFAIL; range->off = 0; range->len = filesize; range->type = PSYNC_RANGE_TRANSFER; @@ -2110,6 +2183,8 @@ static int check_range_for_blocks(psync_file_checksums *checksums, buffersize = PSYNC_COPY_BUFFER_SIZE; hbuffersize = buffersize / 2; buff = malloc(buffersize); + if (!buff) + return PSYNC_NET_TEMPFAIL; rd = pfile_read(fd, buff, hbuffersize); if (unlikely(rd < (ssize_t)hbuffersize)) { free(buff); @@ -2149,6 +2224,12 @@ static int check_range_for_blocks(psync_file_checksums *checksums, ur->len += blen; else { ur = malloc(sizeof(psync_upload_range_list_t)); + if (!ur) { + free(buff); + pfile_close(fd); + psync_list_for_each_element_call(nr, psync_upload_range_list_t, list, free); + return -1; + } ur->uploadoffset = off + buffoff + outbyteoff; ur->off = (uint64_t)(blockidx - 1) * checksums->blocksize; ur->len = blen; @@ -2254,6 +2335,10 @@ static void merge_list_to_element(psync_upload_range_list_t *le, le->len -= ur->len; } else { n = malloc(sizeof(psync_upload_range_list_t)); + if (!n) { + psync_list_for_each_element_call(rlist, psync_upload_range_list_t, list, free); + return; + } n->uploadoffset = n->off = ur->uploadoffset + ur->len; pdbg_assertw(le->len > ur->uploadoffset - le->uploadoffset + ur->len); n->len = le->len - (ur->uploadoffset - le->uploadoffset) - ur->len; @@ -2460,6 +2545,8 @@ psync_file_lock_t *psync_lock_file(const char *path) { int cmp; len = strlen(path) + 1; lock = malloc(offsetof(psync_file_lock_t, filename) + len); + if (!lock) + return NULL; memcpy(lock->filename, path, len); pthread_mutex_lock(&file_lock_mutex); tr = file_lock_tree; @@ -2578,8 +2665,14 @@ int psync_send_pdbg_logf(int thread, const char *file, const char *function, ret = NULL; l = 511; do { + char *tmp; sz = l + 1; - ret = (char *)realloc(ret, sz); + tmp = (char *)realloc(ret, sz); + if (!tmp) { + free(ret); + return -1; + } + ret = tmp; va_start(ap, fmt); l = vsnprintf(ret, sz, format, ap); va_end(ap); diff --git a/pclsync/ppagecache.c b/pclsync/ppagecache.c index e2e4c37..26e0e5a 100644 --- a/pclsync/ppagecache.c +++ b/pclsync/ppagecache.c @@ -487,6 +487,8 @@ static int wait_shared_api() { int ret; capi = sharedapi; waiter = malloc(sizeof(shared_api_waiter_t)); + if (!waiter) + return -1; pthread_cond_init(&waiter->cond, NULL); waiter->api = NULL; psync_list_add_tail(&sharedapiwaiters, &waiter->list); @@ -701,6 +703,10 @@ static psync_urls_t *get_urls_for_request(psync_request_t *req) { return NULL; } urls = malloc(sizeof(psync_urls_t)); + if (!urls) { + pthread_mutex_unlock(&url_cache_mutex); + return NULL; + } urls->hash = req->hash; urls->refcnt = 0; urls->status = 0; @@ -791,6 +797,8 @@ static unsigned char *has_pages_in_db(uint64_t hash, uint64_t pageid, if (unlikely(!pagecnt)) return NULL; ret = malloc(sizeof(unsigned char) * pagecnt); + if (!ret) + return NULL; memset(ret, 0, pagecnt); fromid = 0; fcnt = 0; @@ -1358,6 +1366,10 @@ static void clean_cache() { clean_cache_in_progress = 1; psql_sync(); entries = (pagecache_entry *)malloc(cnt * sizeof(pagecache_entry)); + if (!entries) { + pthread_mutex_unlock(&clean_cache_mutex); + return; + } i = 0; e = 0; while (i < cnt) { @@ -2597,6 +2609,10 @@ static void check_or_request_page(uint64_t fileid, uint64_t hash, } if (!found) { pw = malloc(sizeof(psync_page_wait_t)); + if (!pw) { + unlock_wait(hash); + return; + } psync_list_add_tail(&wait_page_hash[h], &pw->list); psync_list_init(&pw->waiters); pw->hash = hash; @@ -2610,6 +2626,10 @@ static void check_or_request_page(uint64_t fileid, uint64_t hash, range->length += PSYNC_FS_PAGE_SIZE; else { range = malloc(sizeof(psync_request_range_t)); + if (!range) { + unlock_wait(hash); + return; + } psync_list_add_tail(ranges, &range->list); range->offset = pageid * PSYNC_FS_PAGE_SIZE; range->length = PSYNC_FS_PAGE_SIZE; @@ -2767,6 +2787,11 @@ static void psync_pagecache_read_unmodified_readahead( continue; // pdbg_logf(D_NOTICE, "read-aheading page %lu", first_page_id+i); pw = malloc(sizeof(psync_page_wait_t)); + if (!pw) { + unlock_wait(hash); + free(pages_in_db); + return; + } psync_list_add_tail(&wait_page_hash[h], &pw->list); psync_list_init(&pw->waiters); pw->hash = hash; @@ -2781,6 +2806,11 @@ static void psync_pagecache_read_unmodified_readahead( range->length += PSYNC_FS_PAGE_SIZE; else { range = malloc(sizeof(psync_request_range_t)); + if (!range) { + unlock_wait(hash); + free(pages_in_db); + return; + } psync_list_add_tail(ranges, &range->list); range->offset = (first_page_id + i) * PSYNC_FS_PAGE_SIZE; range->length = PSYNC_FS_PAGE_SIZE; @@ -2809,6 +2839,8 @@ add_page_waiter(psync_list *wait_list, psync_list *range_list, uint64_t hash, psync_request_range_t *range; unsigned long h; pwt = malloc(sizeof(psync_page_waiter_t)); + if (!pwt) + return NULL; pthread_cond_init(&pwt->cond, NULL); pwt->buff = buff; pwt->pageidx = pageidx; @@ -2823,6 +2855,12 @@ add_page_waiter(psync_list *wait_list, psync_list *range_list, uint64_t hash, pw->pageid == pageid) goto found; pdbg_logf(D_NOTICE, "page %lu not found", (unsigned long)pageid); pw = malloc(sizeof(psync_page_wait_t)); + if (!pw) { + psync_list_del(&pwt->listwaiter); + pthread_cond_destroy(&pwt->cond); + free(pwt); + return NULL; + } psync_list_add_tail(&wait_page_hash[h], &pw->list); psync_list_init(&pw->waiters); pw->hash = hash; @@ -2836,6 +2874,12 @@ add_page_waiter(psync_list *wait_list, psync_list *range_list, uint64_t hash, range->length += PSYNC_FS_PAGE_SIZE; else { range = malloc(sizeof(psync_request_range_t)); + if (!range) { + psync_list_del(&pwt->listwaiter); + pthread_cond_destroy(&pwt->cond); + free(pwt); + return NULL; + } psync_list_add_tail(range_list, &range->list); range->offset = pageid * PSYNC_FS_PAGE_SIZE; range->length = PSYNC_FS_PAGE_SIZE; @@ -2888,6 +2932,8 @@ int ppagecache_read_unmod_locked(psync_openfile_t *of, char *buf, first_page_id = poffset / PSYNC_FS_PAGE_SIZE; psync_list_init(&waiting); rq = malloc(sizeof(psync_request_t)); + if (!rq) + return 0; psync_list_init(&rq->ranges); lock_wait(hash); if (pagecnt > 1 && pagecnt <= sizeof(dbread) * 8 && psize == size) { @@ -3063,7 +3109,7 @@ int ppagecache_read_unmod_enc_locked(psync_openfile_t *of, psync_crypto_offsets_t offsets; uint64_t initialsize, hash, poffset, psize, first_page_id, aoffset, apageid, authupto; - unsigned long i, pageoff, pagecnt, apsize; + unsigned long i, j, pageoff, pagecnt, apsize; long rb; psync_request_t *rq; psync_crypto_auth_page *ap; @@ -3102,10 +3148,16 @@ int ppagecache_read_unmod_enc_locked(psync_openfile_t *of, pagecnt = psize / PSYNC_FS_PAGE_SIZE; first_page_id = poffset / PSYNC_FS_PAGE_SIZE; rq = malloc(sizeof(psync_request_t)); + if (!rq) + return 0; psync_list_init(&rq->ranges); psync_list_init(&waiting); psync_list_init(&auth_pages); dp = malloc(sizeof(psync_crypto_data_page) * pagecnt); + if (!dp) { + free(rq); + return 0; + } memset(dp, 0, sizeof(psync_crypto_data_page) * pagecnt); ap = NULL; lock_wait(hash); @@ -3118,6 +3170,14 @@ int ppagecache_read_unmod_enc_locked(psync_openfile_t *of, pfs_crpt_get_auth_off(first_page_id + i, 0, &offsets, &aoffset, &asize, &aoff); ap = malloc(sizeof(psync_crypto_auth_page)); + if (!ap) { + for (j = 0; j < i; j++) + if (dp[j].freebuff) + free(dp[j].buff); + free(dp); + free(rq); + return 0; + } ap->waiter = NULL; ap->parent = NULL; ap->firstpageid = (first_page_id + i) / PSYNC_CRYPTO_HASH_TREE_SECTORS * @@ -3138,6 +3198,14 @@ int ppagecache_read_unmod_enc_locked(psync_openfile_t *of, pfs_crpt_get_auth_off(first_page_id + i, l, &offsets, &aoffset, &asize, &aoff); cap = malloc(sizeof(psync_crypto_auth_page)); + if (!cap) { + for (j = 0; j < i; j++) + if (dp[j].freebuff) + free(dp[j].buff); + free(dp); + free(rq); + return 0; + } cap->waiter = NULL; cap->parent = NULL; cap->firstpageid = 0; @@ -3171,6 +3239,14 @@ int ppagecache_read_unmod_enc_locked(psync_openfile_t *of, pbuff = buf + i * PSYNC_FS_PAGE_SIZE - pageoff; if (!pbuff) { pbuff = malloc(sizeof(char) * apsize); + if (!pbuff) { + for (j = 0; j < i; j++) + if (dp[j].freebuff) + free(dp[j].buff); + free(dp); + free(rq); + return 0; + } dp[i].freebuff = 1; } dp[i].buff = pbuff; @@ -3361,6 +3437,8 @@ int ppagecache_readv_locked(psync_openfile_t *of, needkey = 0; pthread_mutex_unlock(&of->mutex); rq = malloc(sizeof(psync_request_t)); + if (!rq) + return 0; psync_list_init(&rq->ranges); psync_list_init(&waiting); for (i = 0; i < cnt; i++) {