Skip to content

fix: guard RSA refCnt decrement with held lock#435

Draft
MarkAtwood wants to merge 1 commit into
wolfSSL:masterfrom
MarkAtwood:fix/rsa-free-refcnt-lock
Draft

fix: guard RSA refCnt decrement with held lock#435
MarkAtwood wants to merge 1 commit into
wolfSSL:masterfrom
MarkAtwood:fix/rsa-free-refcnt-lock

Conversation

@MarkAtwood

@MarkAtwood MarkAtwood commented Jul 9, 2026

Copy link
Copy Markdown

Bug

In wp_rsa_free() (src/wp_rsa_kmgmt.c) the reference-count decrement cnt = --rsa->refCnt; runs unconditionally, outside the if (rc == 0) mutex-lock-success guard. If wc_LockMutex() fails, two threads can race the unlocked decrement, both observe cnt == 0, and double-free the object.

This is an asymmetry with the sibling wp_rsa_up_ref() in the same file, which correctly guards its increment behind a successfully-held lock.

Fix

Move the decrement inside the lock-success branch and default cnt = 1. On the rare lock failure the object is leaked rather than double-freed (leak-safe), and in the normal path the decrement is atomic with the held lock.

Verification

  • Compiled the patched translation unit (default multi-threaded build; --enable-singlethreaded defaults to no, so WP_SINGLE_THREADED is undefined): gcc -c src/wp_rsa_kmgmt.c -> exit 0, no errors.
  • Preprocessed output confirms the compiled body now performs the decrement only inside if (rc == 0).

Reported by static analysis (Fenrir finding 515). Severity is low: wolfSSL's pthread wc_LockMutex essentially never fails for a valid normal-type mutex, so this is a latent defect.

[fenrir-sweep:held]

Copilot AI review requested due to automatic review settings July 9, 2026 23:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot couldn't run its full agentic review because no GitHub Actions runner was available. Make sure your repository has a runner available to run Copilot's review, or add a copilot-setup-steps.yml file specifying one with the runs-on attribute. See the docs for more details.

Fixes a potential double-free race in wp_rsa_free() by ensuring the RSA reference count decrement occurs only while the mutex is successfully held, matching the locking pattern used by wp_rsa_up_ref().

Changes:

  • Initialize cnt to a non-zero default to avoid freeing on mutex lock failure (leak-safe fallback).
  • Move --rsa->refCnt inside the rc == 0 (lock acquired) branch.
  • Preserve unlock behavior only for the successful lock path.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@aidangarske aidangarske left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

🐺 Skoll Code Review

Overall recommendation: COMMENT
Findings: 1 total — 1 posted, 0 skipped

Posted findings

  • [Medium] Lock-failure refcount behavior lacks regression coveragesrc/wp_rsa_kmgmt.c:528-534

Review generated by Skoll.

Comment thread src/wp_rsa_kmgmt.c
{
if (rsa != NULL) {
int cnt;
int cnt = 1; /* non-zero default: on lock failure do not free (leak-safe) */

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

🟡 [Medium] Lock-failure refcount behavior lacks regression coverage
💡 SUGGEST test

The PR changes the multi-threaded lock-failure path so wp_rsa_free() leaves cnt nonzero and skips both the unlocked decrement and object destruction. That is the intended safer behavior, but I found no test or fault-injection coverage for the changed branch. The PR verification notes only compilation and preprocessing, so a future refactor could move --rsa->refCnt back outside the successful-lock guard without a regression test catching it.

Suggestion:

Suggested change
int cnt = 1; /* non-zero default: on lock failure do not free (leak-safe) */
Add a focused fault-injection or mocked-mutex test that forces `wc_LockMutex(&rsa->mutex)` to fail and verifies `wp_rsa_free()` does not decrement `refCnt` or free the RSA object on that path.

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.

5 participants