From 478c1a85a97616504813a703030bb9aa4f6f43e5 Mon Sep 17 00:00:00 2001 From: Levi Neely <141506390+lneely@users.noreply.github.com> Date: Tue, 10 Mar 2026 13:01:53 +0100 Subject: [PATCH] Bug fixes: heap-use-after-free in pmem_realloc, auto-create FUSE mountpoint (#374) * Fix heap-use-after-free in pmem_realloc realloc() frees the old block when it moves the allocation. hdr->subsystem was read after the realloc call, from potentially freed memory. Save it to old_subsystem before the call, matching the existing pattern for old_size. Co-Authored-By: Claude Sonnet 4.6 * Auto-create missing FUSE mountpoint directory Previously the mountpoint had to exist before starting pcloudcc; if it was missing the error was only visible in the debug log. Restore the prior behavior of automatically creating the directory when it does not exist, logging a notice when creation succeeds or a critical error if it fails. Co-Authored-By: Claude Sonnet 4.6 --------- Co-authored-by: Levi Neely Co-authored-by: Claude Sonnet 4.6 --- pclsync/pfs.c | 10 ++++++++-- pclsync/pmem.c | 7 ++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/pclsync/pfs.c b/pclsync/pfs.c index 394c20b..be0195c 100644 --- a/pclsync/pfs.c +++ b/pclsync/pfs.c @@ -29,6 +29,8 @@ */ #include +#include +#include #include #include #include @@ -3516,9 +3518,13 @@ static char *psync_fuse_get_mountpoint() { "Mount point %s has a stale FUSE mount (Transport endpoint is not connected). " "Please unmount it first with: fusermount -u %s", mp, mp); } else if (stat_errno == ENOENT) { + if (mkdir(mp, 0755) == 0) { + pdbg_logf(D_NOTICE, "Mount point %s did not exist, created it.", mp); + return mp; + } pdbg_logf(D_CRITICAL, - "Mount point %s does not exist. " - "Please create the directory first with: mkdir -p %s", mp, mp); + "Mount point %s does not exist and could not be created: %s", + mp, strerror(errno)); } else { pdbg_logf(D_CRITICAL, "Cannot access mount point %s (errno=%d: %s). " diff --git a/pclsync/pmem.c b/pclsync/pmem.c index 363e5b4..2a90458 100644 --- a/pclsync/pmem.c +++ b/pclsync/pmem.c @@ -118,13 +118,14 @@ void *pmem_realloc(pmem_subsystem_t subsystem, void *ptr, size_t size) { hdr = ((pmem_header_t *)ptr) - 1; old_size = hdr->size; - + pmem_subsystem_t old_subsystem = hdr->subsystem; + new_hdr = (pmem_header_t *)realloc(hdr, total_size); if (!new_hdr) { return NULL; } - - __atomic_sub_fetch(&subsystem_stats[hdr->subsystem], old_size, __ATOMIC_RELAXED); + + __atomic_sub_fetch(&subsystem_stats[old_subsystem], old_size, __ATOMIC_RELAXED); __atomic_add_fetch(&subsystem_stats[subsystem], size, __ATOMIC_RELAXED); new_hdr->size = size;