-
Notifications
You must be signed in to change notification settings - Fork 15
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
Some usage of Allocator::deallocate() is UB #233
Comments
I raised the question in Zulip https://rust-lang.zulipchat.com/#narrow/channel/122651-general/topic/Is.20this.20deallocation.20UB.3F/near/478350147. My conclusion is more strongly that the Allocator should only deal in pointers (that is, even my "fixed" example is questionable). I can play around with the code to see if this is reasonably feasible. |
In general I'm on board with removing the deallocate functions and coming up with something better/safer 👍 |
I played around for a bit with pointers main...inahga:zlib-rs:inahga/dealloc-safe, and it looks quite tractable (though I don't guarantee what I wrote works 😄). Mostly mechanical changes. I do suggest simply having the allocator deal in raw pointers. |
@folkertdev I believe you have resolved this? Looking at usage of deallocate() looks like we're only deallocating from the pointer from allocate() 🎉. Was there anything else you were going to do related to this issue? |
no this is done, fixed by |
I believe any situation where we take a reference and directly deallocate it is undefined behavior.
Consider deflate::Window::drop_in:
We are correct to
take(&mut self.buf)
, so that we don't leave a dangling reference inside the struct. But, we then assign the reference tobuf
, then deallocate it afterwards. After thedeallocate()
call,buf
is now dangling. It is indeed dropped immediately after, but references must not be dangling while they're live.We can trivially tweak this into:
Now
buf
will be dropped at the end of thelet
scope, so it won't have the chance to become dangling.But, the allocator API lends itself to this UB, since it returns references. It may be better for the allocator to only issue pointers, and structs should store pointers and cast to short-lived references only when required (i.e. whenever you can guarantee that the pointer outlives the reference). AFAICT other allocating structures in the standard library, e.g.
Vec
, more or less follow this pattern.This isn't caught by Miri. I'm not 100% sure why, but it seems to be a limitation of its memory model .
The text was updated successfully, but these errors were encountered: