Skip to content

libpcp_web: fix double-free in pmwebapi_labelsetdup - #2687

Merged
natoscott merged 2 commits into
performancecopilot:mainfrom
natoscott:fix-labelsetdup-double-free
Aug 9, 2026
Merged

libpcp_web: fix double-free in pmwebapi_labelsetdup#2687
natoscott merged 2 commits into
performancecopilot:mainfrom
natoscott:fix-labelsetdup-double-free

Conversation

@natoscott

Copy link
Copy Markdown
Member

pmwebapi_labelsetdup() performs a shallow struct copy (*dup = *lp) and then selectively deep-copies json and labels — but only when nlabels > 0. Two problems:

  1. When nlabels <= 0 (or json is NULL), the dup shares the json pointer with the source. When pmDiscoverInvokeLabelsCallBacks frees the source labelset after invoking callbacks, the stored duplicate retains the dangling pointer. The next label discovery cycle frees the old duplicate, double-freeing the json allocation.

  2. The compound flag and hash pointer were never handled — if set, the dup shares the opaque hash with the source, again leading to a double-free via pmFreeLabelSets.

Fix both by clearing compound/hash immediately after the struct copy and, for the nlabels <= 0 / NULL-json case, NULLing json, jsonlen and labels before returning. This matches what __pmDupLabelSets in libpcp already does correctly for the same cases.

Resolves a pmproxy SIGABRT (double-free) in archive discovery:
pmFreeLabelSets ← pmSeriesDiscoverLabels ← pmDiscoverInvokeLabelsCallBacks

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com

Fixes: #2686

pmwebapi_labelsetdup() performs a shallow struct copy (*dup = *lp)
and then selectively deep-copies json and labels — but only when
nlabels > 0.  Two problems:

1. When nlabels <= 0 (or json is NULL), the dup shares the json
   pointer with the source.  When pmDiscoverInvokeLabelsCallBacks
   frees the source labelset after invoking callbacks, the stored
   duplicate retains the dangling pointer.  The next label discovery
   cycle frees the old duplicate, double-freeing the json allocation.

2. The compound flag and hash pointer were never handled — if set,
   the dup shares the opaque hash with the source, again leading
   to a double-free via pmFreeLabelSets.

Fix both by clearing compound/hash immediately after the struct copy
and, for the nlabels <= 0 / NULL-json case, NULLing json, jsonlen
and labels before returning.  This matches what __pmDupLabelSets in
libpcp already does correctly for the same cases.

Resolves a pmproxy SIGABRT (double-free) in archive discovery:
  pmFreeLabelSets ← pmSeriesDiscoverLabels ← pmDiscoverInvokeLabelsCallBacks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Fixes: performancecopilot#2686
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Repository UI (inherited), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 12c481c7-c191-40f0-ba0e-ea73129e84e0

📥 Commits

Reviewing files that changed from the base of the PR and between 26d4ca5 and c7ed4fc.

📒 Files selected for processing (1)
  • src/libpcp_web/src/util.c
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/libpcp_web/src/util.c

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling when duplicating label sets with no labels or missing data.
    • Ensured duplicated label sets start with clean state information, preventing stale metadata from being carried over.
    • Preserved existing duplication behavior for valid, populated label sets.
    • Increased reliability when processing label-based metadata and JSON responses.
    • Empty or invalid inputs now produce a properly initialized empty label set.

Walkthrough

pmwebapi_labelsetdup now resets duplicate state and safely handles nonpositive label counts or null JSON pointers. Valid inputs continue to duplicate the JSON data and label array.

Changes

Label set duplication

Layer / File(s) Summary
Duplicate label set initialization
src/libpcp_web/src/util.c
pmwebapi_labelsetdup clears hash and compound. It returns an initialized empty label set for empty or missing JSON data. Valid inputs retain JSON and label-array duplication.

Possibly related PRs

Poem

A rabbit reset each label in the set,
Cleared stale state and left no debt.
With empty JSON, an empty set stayed,
While valid copies safely hopped away.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: fixing a double-free in pmwebapi_labelsetdup.
Description check ✅ Passed The description explains the double-free cause, the pointer ownership fix, and the affected pmproxy crash.
Linked Issues check ✅ Passed The changes address issue #2686 by preventing the pmproxy double-free crash during archive discovery.
Out of Scope Changes check ✅ Passed The changes are limited to labelset duplication state and pointer handling required to fix issue #2686.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/libpcp_web/src/util.c`:
- Around line 885-890: Reset dup->nlabels to 0 in the empty-duplicate branch of
the label duplication function before returning dup, alongside clearing json,
jsonlen, and labels. This must cover both lp->nlabels <= 0 and lp->json == NULL
cases so the returned duplicate cannot appear populated when labels is NULL.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Repository UI (inherited), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: bcecb745-92eb-4948-88cd-6d7a38a58af4

📥 Commits

Reviewing files that changed from the base of the PR and between 918d12b and 26d4ca5.

📒 Files selected for processing (1)
  • src/libpcp_web/src/util.c

Comment thread src/libpcp_web/src/util.c
When lp->json is NULL but lp->nlabels > 0, the shallow copy
left dup->nlabels positive with dup->labels set to NULL.
Reset nlabels to 0 so consumers cannot dereference a NULL
labels pointer.

Reported-by: coderabbitai

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@natoscott
natoscott merged commit 6173537 into performancecopilot:main Aug 9, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] pmproxy crash in the PCP Web library

1 participant