pcloudcc-lneely/tests/unit-tests
Levi Neely 7595c485bf
Fix bad-free heap corruption in ppathstatus and psyncer (#392)
* Fix bad-free heap corruption in ppathstatus and psyncer (#391)

Both ppathstatus.c and psyncer.c used bare free() via
ptree_for_each_element_call_safe to bulk-free tree nodes that were
allocated with pmem_malloc.  pmem_malloc prepends a pmem_header_t to
every allocation, so the returned pointer is an interior pointer to the
underlying glibc chunk.  Passing it to free() makes glibc read a garbage
size field from the pmem header and abort with "free(): invalid size".

This is the same class of bug fixed earlier in pintervaltree.c and
pfscrypto.c.  The crash manifests reliably with larger files because
more sync-queue and path-status churn occurs, increasing the likelihood
that one of these bulk-free paths is hit while a non-empty tree exists.

Fix: add free_folder_tasks_node() (ppathstatus.c) and
free_synced_down_folder() (psyncer.c) helpers that call pmem_free, and
use them as the ptree_for_each_element_call_safe callback in all three
affected call sites.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix bad-free in pfs.c and ppagecache.c (pcl-26j)

Two more call sites passed bare free() as a callback to tree/list
traversal macros, but the nodes were allocated via pmem_malloc which
prepends a pmem_header_t. Freeing the data pointer directly skips the
header and corrupts the heap.

- pfs.c: ptree_for_each_element_call_safe on sectorsinlog used free()
  on psync_sector_inlog_t; replaced with free_sector_inlog_node() that
  calls pmem_free(PMEM_SUBSYS_OTHER, e).
- ppagecache.c: psync_list_for_each_element_call on request->ranges
  used free() on psync_request_range_t; replaced with
  free_request_range() that calls pmem_free(PMEM_SUBSYS_CACHE, range).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Add unit and smoke tests for pcl-26j bad-free (ppagecache, pfs, psyncer)

Unit test (test_pcl26j_free): exercises all four fixed call sites —
psync_request_range_t, synced_down_folder, folder_tasks_t, and
psync_sector_inlog_t — using --wrap=malloc/free to verify that
pmem_free() passes the header pointer to free(), not the data pointer.
Includes a harness self-check that confirms bare free(data_ptr) is
detected. Would have failed against pre-fix code.

Smoke test (smoke-test-large-read.sh): builds pcloudcc with ASAN,
starts the daemon, streams a large file (>=50 MB) from the FUSE mount
to /dev/null to force multi-range psync_request_range_t allocation and
teardown via psync_pagecache_free_request, then scans the ASAN log for
any bad-free reports.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 12:12:50 +01:00
..
test_pcl26j_free.c Fix bad-free heap corruption in ppathstatus and psyncer (#392) 2026-03-24 12:12:50 +01:00
test_pdbg_path.c Add GitHub Actions CI workflow for unit tests (#379) 2026-03-10 17:48:42 +01:00
test_pdiff_helpers.c Phase 4 testability refactor: pdiff, plocalscan, ppagecache helper extraction (#386) 2026-03-11 20:35:05 +01:00
test_pfs_helpers.c Testability refactor: extract helpers, add stress/send tests, ppagecache/pfs extraction (#383) (#385) 2026-03-11 19:24:39 +01:00
test_pfs_lock_ordering.c Fix pcl-zqv.5.7: eliminate deadlock in pfs_get_both_locks (#339) 2026-03-03 19:33:56 +01:00
test_pfstasks_db.c Add testability infrastructure: unit tests, extracted modules, CI integration (#381) 2026-03-11 07:52:35 +01:00
test_pfstasks_tree.c Add testability infrastructure: unit tests, extracted modules, CI integration (#381) 2026-03-11 07:52:35 +01:00
test_pfsupload.c Add testability infrastructure: unit tests, extracted modules, CI integration (#381) 2026-03-11 07:52:35 +01:00
test_pintervaltree.c Add testability infrastructure: unit tests, extracted modules, CI integration (#381) 2026-03-11 07:52:35 +01:00
test_plocalscan_helpers.c Phase 4 testability refactor: pdiff, plocalscan, ppagecache helper extraction (#386) 2026-03-11 20:35:05 +01:00
test_plocks.c Add testability infrastructure: unit tests, extracted modules, CI integration (#381) 2026-03-11 07:52:35 +01:00
test_ppagecache.c Phase 4 testability refactor: pdiff, plocalscan, ppagecache helper extraction (#386) 2026-03-11 20:35:05 +01:00
test_prun.c Add GitHub Actions CI workflow for unit tests (#379) 2026-03-10 17:48:42 +01:00
test_ptask_free.c Add testability infrastructure: unit tests, extracted modules, CI integration (#381) 2026-03-11 07:52:35 +01:00
test_ptools_errptr.c Add testability infrastructure: unit tests, extracted modules, CI integration (#381) 2026-03-11 07:52:35 +01:00
test_ptools_params.c Fix pcl-a1j: buffer overflow in ptools_create_backend_event() via unchecked sprintf and strcat (#355) 2026-03-07 18:35:43 +01:00
test_ptree.c Add testability infrastructure: unit tests, extracted modules, CI integration (#381) 2026-03-11 07:52:35 +01:00
test_read_response.cpp Add GitHub Actions CI workflow for unit tests (#379) 2026-03-10 17:48:42 +01:00