Skip to content

Fix scitoken_status_free: missing C-linkage symbol and status type confusion - #212

Open
djw8605 wants to merge 1 commit into
scitokens:masterfrom
djw8605:fix/status-free-symbol
Open

Fix scitoken_status_free: missing C-linkage symbol and status type confusion#212
djw8605 wants to merge 1 commit into
scitokens:masterfrom
djw8605:fix/status-free-symbol

Conversation

@djw8605

@djw8605 djw8605 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Problem

Three related bugs in the async-status C API:

  1. The C symbol doesn't exist. scitokens.h declares void scitoken_status_free(SciTokenStatus *status) inside extern "C", but scitokens.cpp defines scitoken_status_free(SciTokenStatus status) — a different parameter type. C++ treats that as a separate overload with C++ linkage, so the library only exports the mangled _Z20scitoken_status_freePv. Any C consumer using the public header gets an undefined symbol at link time. On Linux it's worse: the mangled name doesn't match the scitoken* glob in configs/export-symbols, so the function isn't exported in any form. (Verified with nm before/after.)

  2. Type confusion on free. The implementation deletes the handle as scitokens::AsyncStatus*, but statuses returned by scitoken_deserialize_start are SciTokenAsyncStatus* — an unrelated type holding two unique_ptrs. Deleting through the wrong type runs ~AsyncStatus over unrelated memory (its std::unique_lock members get destroyed reading garbage — potential unlock of a wild mutex pointer) and leaks the real members.

  3. Accessor type confusion for enforcer statuses. scitoken_status_get_timeout_val / _get_read_fd_set / etc. cast the handle to SciTokenAsyncStatus*, but enforcer_generate_acls_start returned a raw AsyncStatus* — so using the select()-loop accessors with the enforcer async API read garbage.

Fix

  • Match the declared signature; also null the caller's handle and make null input a no-op.
  • Wrap enforcer async statuses in SciTokenAsyncStatus (start) and unwrap on continue, so every SciTokenStatus handle exposed through the C API is the same concrete type. This simultaneously fixes the free path and the scitoken_status_get_* accessors for enforcer statuses.
  • Reject a null status_out in scitoken_deserialize_start instead of dereferencing it.

Testing

  • New regression test frees an async status mid-flight (and a null handle); the test calling the function at all verifies the C-linkage symbol resolves — it did not before this change.
  • nm libSciTokens.dylib now shows T _scitoken_status_free (unmangled).
  • ctest unit, env_config, and monitoring suites pass.

🤖 Generated with Claude Code

The header declares scitoken_status_free(SciTokenStatus *) inside
extern "C", but the implementation defined an overload taking
SciTokenStatus by value.  C++ treats that as a distinct function with
C++ linkage, so the library never emitted the C-linkage symbol at all:
C consumers failed to link, and on Linux the mangled name is not
matched by the scitoken* glob in the export map either.

The implementation also deleted the handle as scitokens::AsyncStatus,
but statuses returned by scitoken_deserialize_start are
SciTokenAsyncStatus -- an unrelated type -- so freeing one would run
the wrong destructor over unrelated memory (including unique_lock
members interpreted from garbage).

Fix by matching the declared signature (also nulling the caller's
handle), wrapping the enforcer async statuses in SciTokenAsyncStatus
so every SciTokenStatus handle exposed through the C API is the same
concrete type (this also makes the scitoken_status_get_* accessors,
which already cast to SciTokenAsyncStatus, correct for enforcer
statuses), and rejecting a null status_out in
scitoken_deserialize_start instead of dereferencing it.

Adds a regression test that frees an async status and verifies the
C-linkage symbol resolves.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@djw8605 djw8605 added the ai-gen label Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant