You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
AudioMediaPort callback teardown race and stale detached frame metadata #5308
AudioMediaPort clears the callback back-pointer under its group lock in the base destructor. That is too late to protect callback-visible members of a derived class during teardown: a callback may still be in progress, or dispatch may still be possible, while derived state is being destroyed. There is no exposed callback fence for a C++ subclass to drain callbacks before teardown begins.
A related problem exists after the back-pointer is cleared: get_frame() returns PJ_SUCCESS without setting the caller's frame->type or frame->size. Stale AUDIO/nonzero-size metadata can therefore survive the detached read.
Create a derived AudioMediaPort whose get/put callback uses derived state.
Hold an in-flight callback while another thread initiates teardown.
Derived-member teardown occurs before AudioMediaPort::~AudioMediaPort() reaches its callback-detachment lock.
For the detached-frame problem, invoke the raw port's get_frame() after the back-pointer has been cleared, with an input frame seeded as AUDIO and nonzero size. The current NULL-back-pointer branch leaves both fields unchanged.
Draft #5307 includes an isolated regression test using the actual raw media port, without a sound device or SIP call. It covers held get and put callbacks, an explicit pre-teardown fence, completion ordering, repeated detach, and stale-frame sentinels. Restoring the old frame-return behavior makes the new test fail. Removing the fence lock also makes it fail. These are targeted negative controls; an unpatched sanitizer-detected use-after-free is not claimed.
Expected: an explicit way to fence callbacks while the complete object/state is valid, and detached reads that return NONE with size zero. Recursive lock owners cannot wait for themselves; this is not a request for generic concurrent destructor safety.
Validated on macOS arm64 with Apple Clang 21. GNU make and CMake shared PJSUA2 tests pass with #5307. The production change is limited to an additive protected C++ fence and detached frame metadata; no application-specific code is involved.
Activity
pjsua2: Expose AudioMediaPort callback fencing to applications (pjsip…
pjsua2: Prevent uninitialized frame reads after callback detach (pjsi…