-
Notifications
You must be signed in to change notification settings - Fork 386
Avoid using a raw pointer in the proactor queue to avoid use after free. #2468
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1620,6 +1620,9 @@ class ACE_Export ACE_Handler | |
*/ | ||
virtual void handle_wakeup (); | ||
|
||
/// Call before destruction to ensure no more callbacks can happen. | ||
void deregister_callback (); | ||
|
||
/// Get the proactor associated with this handler. | ||
ACE_Proactor *proactor (); | ||
|
||
|
@@ -1649,10 +1652,18 @@ class ACE_Export ACE_Handler | |
{ | ||
public: | ||
Proxy (ACE_Handler *handler) : handler_ (handler) {} | ||
void reset () { this->handler_ = 0; } | ||
void reset () | ||
{ | ||
acquire (); | ||
this->handler_ = 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should use a guard for the acquire/release, no need for public acquire/release, use nullptr, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use std::atomic instead? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I considered using a guard here, but I ran into problems, when doing the actual callback to the ACE_Handler for the timeout. A possible solution was to allow the code that actually calls the ACE_Handler to lock the mutex. |
||
release (); | ||
} | ||
ACE_Handler *handler () { return this->handler_; } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is reading itself thread safe? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's why I added the acquire/release methods. Reading the pointer does not completely solve the problem, since I just end up with another raw pointer and the other core could again be in the process of destructing the object. The timeout code looks something like this:
I'm very open to a better solution. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is risky, keeping a lock during a callback. In taox11 we use shared/weak pointers There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess replacing the ACE_Handler* completely with some kind of shared_pointer could also solve the problem. I'd have to test it out with our code base. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would probably be the bigger change for users, since it requires them to use shared_pointers to manage the life time of their ACE_Handlers, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changing the public API is pretty impossible given the amount of users there. Your current solution doesn't seem to be complete, so not something to merge. A long time ago to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding reference counting similar to |
||
int acquire () { return mutex_.acquire (); } | ||
int release () { return mutex_.release (); } | ||
private: | ||
ACE_Handler *handler_; | ||
ACE_SYNCH_MUTEX mutex_; | ||
}; | ||
typedef ACE_Refcounted_Auto_Ptr<Proxy, ACE_SYNCH_MUTEX> Proxy_Ptr; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why move this to a new public method which is only used here?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be able to use it from derived classes. It could therefore be made protected.
The order of operations in destructors would only execute this after the destructor of the derived class had already been executed, enabling callbacks to a semy-destructed object.