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
Unsoundness #100
Comments
Thanks for the report! I should've known there was something I missed in #94. In the short term this can be fixed by checking the @smol-rs/admins I won't have time to fix this until the weekend, any thoughts here? |
Ours was simple and straight forward too before 3.0.
True. I wonder if we should revert back to 2.x API. That API was quite stable and lacked all these footguns and unsoundness behaviors. I'm fine with some allocations if that's the cost. |
The 2.X API, while admittedly simpler, pretty recklessly abused heap allocations. The fact that the 3.0 API doubled its speed should be pretty good evidence of this. Therefore I would oppose going back to the 2.X API. There is very little overhead in the 3.X API. Some overhead was introduced in #94, but I only ever measured it as a 7% performance drop. The Although I do think |
I'd like to clarify that |
This commit makes it so EventListener::listen() does not overwrite existing listeners if they already exist. If the listener is already registered in an event listener list, it removes the listener from that list before registering the new listener. This soundness bug was missed during #94. This is a patch-compatible fix for #100. We may also want an API-level fix for #100 as well. This is up for further discussion. Signed-off-by: John Nunley <dev@notgull.net>
This commit makes it so EventListener::listen() does not overwrite existing listeners if they already exist. If the listener is already registered in an event listener list, it removes the listener from that list before registering the new listener. This soundness bug was missed during #94. This is a patch-compatible fix for #100. We may also want an API-level fix for #100 as well. This is up for further discussion. Signed-off-by: John Nunley <dev@notgull.net>
Please elaborate on that. In general, it appears a bit weird to me that |
I elaborate more in this comment.
Unfortunately we can't create an already-pinned
Closures can't really be used in |
why? I'd understand if that were about closures returning |
Sure but as a Rust crate, it should priorities soundness, safety and correctness above all IMO.
In general, yes but it depends on two other factors: what was the performance like w/o this reduction (i-e the actual gain) and the price to pay for this. If the price is having easy footguns and strange API (as @fogti also pointed out), then we have to be critical of the performance gain being worth it.
I think that would be a lot better than having a footgun. |
This commit makes it so EventListener::listen() does not overwrite existing listeners if they already exist. If the listener is already registered in an event listener list, it removes the listener from that list before registering the new listener. This soundness bug was missed during #94. This is a patch-compatible fix for #100. We may also want an API-level fix for #100 as well. This is up for further discussion. Signed-off-by: John Nunley <dev@notgull.net>
Yes, all of the APIs proposed have problems. The 2.x API had serious performance implications and the 3.x API had the footgun. If we're considering another API break, I'd rather use one that takes advantage of Rust's type system. Maybe:
Regarding the issue, #101 is the short term fix for this problem |
That sounds like a great idea but how about the new trait is called Also a macro might be good for handling the |
Published the fix for this in v4.0.1 |
This commit makes it so EventListener::listen() does not overwrite existing listeners if they already exist. If the listener is already registered in an event listener list, it removes the listener from that list before registering the new listener. This soundness bug was missed during #94. This is a patch-compatible fix for #100. We may also want an API-level fix for #100 as well. This is up for further discussion. Signed-off-by: John Nunley <dev@notgull.net>
This commit makes it so EventListener::listen() does not overwrite existing listeners if they already exist. If the listener is already registered in an event listener list, it removes the listener from that list before registering the new listener. This soundness bug was missed during #94. This is a patch-compatible fix for #100. We may also want an API-level fix for #100 as well. This is up for further discussion. Signed-off-by: John Nunley <dev@notgull.net>
event-listener
in its current state (531c106) is unsound. It's possible to trigger a use-after-free bug completely with safe Rust.PoC:
cargo miri run
:The issue is that
EventListener::listen(mut self: Pin<&mut Self>, event: &Event<T>)
doesn't deal with the case when theEventListener
is already currently linked/associated with another/or sameEvent
. It just unconditionally overwrites the content of the EventListener'sListener
.In my opinion, the general api design of
Event/EventListener
is rather unnecessarily complex and introduces more overhead than needed. Tokio'sNotify
api is much "better" in that regard. 🤷♂️The text was updated successfully, but these errors were encountered: