From 5a519ab67559cfe2ba795255bb3683cb40e2378b Mon Sep 17 00:00:00 2001 From: Levi Neely <141506390+lneely@users.noreply.github.com> Date: Sat, 7 Mar 2026 16:24:53 +0100 Subject: [PATCH] Fix pcl-3la: pstatus saturating add and fuse thread cleanup (#352) * Fix pcl-3la.1: saturating addition for bytestou in pstatus_upload_recalc Replace unchecked uint64_t summation in pstatus_upload_recalc() with overflow-safe saturating addition. Before adding each file's size, check if the result would wrap around UINT64_MAX; if so, saturate to UINT64_MAX instead of silently wrapping. Ref GH #293. * Fix pcl-3la.2: remove spurious fuse_loop_mt while-loop and exit(0) fuse_loop_mt() already loops internally; wrapping it in an additional while loop caused repeated re-entry after normal exit. Also removes the exit(0) call in the shutdown path so fuse_destroy() and other cleanup run properly on shutdown. Co-Authored-By: Claude Sonnet 4.6 --------- Co-authored-by: Levi Neely Co-authored-by: Claude Sonnet 4.6 --- pclsync/pfs.c | 14 +++----------- pclsync/pstatus.c | 6 +++++- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/pclsync/pfs.c b/pclsync/pfs.c index 178d409..5a9987c 100644 --- a/pclsync/pfs.c +++ b/pclsync/pfs.c @@ -3651,21 +3651,13 @@ static void psync_fuse_thread() { } pthread_mutex_unlock(&start_mutex); pdbg_logf(D_NOTICE, "running fuse_loop_mt"); - - // Check shutdown flag periodically during FUSE loop - while (!shutdown_requested) { - fr = fuse_loop_mt(psync_fuse); - if (fr != 0 || shutdown_requested) { - break; - } - } - + fr = fuse_loop_mt(psync_fuse); + if (shutdown_requested) { pdbg_logf(D_NOTICE, "shutdown requested, exiting fuse loop"); pfs_do_stop(); - exit(0); } - + pdbg_logf(D_NOTICE, "fuse_loop_mt exited with code %d, running fuse_destroy", fr); pthread_mutex_lock(&start_mutex); fuse_destroy(psync_fuse); diff --git a/pclsync/pstatus.c b/pclsync/pstatus.c index f8630b0..31270d2 100644 --- a/pclsync/pstatus.c +++ b/pclsync/pstatus.c @@ -222,7 +222,11 @@ void pstatus_upload_recalc() { putil_strcat(fscpath, "/", fileidhex, NULL); if (!stat(filename, &st)) { filestou++; - bytestou += pfile_stat_size(&st); + uint64_t fsize = pfile_stat_size(&st); + if (fsize > UINT64_MAX - bytestou) + bytestou = UINT64_MAX; + else + bytestou += fsize; } free(filename); }