-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use-after-free when aborting already-closed exchange #19747
Comments
Abort and Close need to be reentrant |
The can't be "reentrant" because they mess with refcounts. |
Let me rephrase my word. We need a So my solution is:
After this change, I think people will always prefer |
That seems viable (with a better name for SafetyAbort; I'll think about the naming a bit; maybe this API should just be called As for whether we should use it from Three last thoughts for the moment:
|
Our "close all exchanges except this special one for this fabric" API messes up exchange refcounting, leading to use-after-free. The fix is to reuse, as much as possible, the normal "session is going away" flow to notify exchanges, and other session consumers, that the sessions are in fact going away. Fixes project-chip#19747
Our "close all exchanges except this special one for this fabric" API messes up exchange refcounting, leading to use-after-free. The fix is to reuse, as much as possible, the normal "session is going away" flow to notify exchanges, and other session consumers, that the sessions are in fact going away. Fixes project-chip#19747
Our "close all exchanges except this special one for this fabric" API messes up exchange refcounting, leading to use-after-free. The fix is to reuse, as much as possible, the normal "session is going away" flow to notify exchanges, and other session consumers, that the sessions are in fact going away. Fixes project-chip#19747
Our "close all exchanges except this special one for this fabric" API messes up exchange refcounting, leading to use-after-free. The fix is to reuse, as much as possible, the normal "session is going away" flow to notify exchanges, and other session consumers, that the sessions are in fact going away. Fixes project-chip#19747
* Fix crashes when closing all exchanges for fabric. Our "close all exchanges except this special one for this fabric" API messes up exchange refcounting, leading to use-after-free. The fix is to reuse, as much as possible, the normal "session is going away" flow to notify exchanges, and other session consumers, that the sessions are in fact going away. Fixes #19747 * Address review comments. * Updates to fix fallout from #19502. We need to allow messages on inactive sessions to reach the exchange manager, because such sessions need to be able to deliver an MRP ack to an exchange waiting for one. We also don't want to crash on an attempt to transition from Inactive to Defunct state; the transition should just be ignored. This way if we start trying to transitionin to Defunct on MRP delivery failures we will not start crashing if such a failure happens on an Inactive session. * Address review comment * Address review comments * Address Jerry's review comments.
Problem
I tried using the code added in #19328 in RemoveFabric, and ran into crashes in the following scenario:
AbortExchangesForFabricExceptOne
API from Add API to invalid sessions/exchanges for UpdateNOC command #19328 (in my case RemoveFabric).AbortExchangesForFabricExceptOne
ends up looping through all live exchanges, and the exchange waiting for an ack is live. It callsAbort()
on the exchanges.Abort()
does the following, in order:Release()
.In this case, after step 3 our object is dead because the last ref got dropped, and at step 4 we crash. But even if we held an extra ref on the stack to keep it alive through step 4, the unbalanced
Release()
in step 5 would mean we end up refcounting a dead object at some point.Proposed Solution
I think we need to do something smarter than calling
Abort
on all existing exchanges for the fabric, in terms of managing the exchange refcounts. In particular, I would propose we do the following:OnSessionReleased
on the exchange itself, which I think might be good enough: it might retain the reference to the session if it does not die (because the app is holding on to it), but future OnSessionReleased calls on it would be no-ops because it won't be in the retrans table anymore. In particular,OnSessionReleased
already handles the various refcounting scenarios correctly.Another possibility is that instead of having an API on the exchange manager here we have an API on secure session which is basically "notify all holders except this given one that you are going away", plus an API on exchange that:
@kghost @mrjerryjohns I actually kind of like that last idea... It funnels as much as possible through existing, tested, code paths in terms of the exchange-termination behavior.
The text was updated successfully, but these errors were encountered: