-
Notifications
You must be signed in to change notification settings - Fork 13.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
clamp allocations of size 0 to 1 or pass size to free #11998
Comments
We could consider |
Okay, I came up with a better solution. With optimizations, the address of zero-size types is already irrelevant:
This is not a problem, because LLVM's NoAlias concept only means that there is no memory dependency between two pointers (there will never be a write through one seen through the other). Therefore, we can simply return a pointer with the address 1 instead of 0, so it doesn't break the non-null guarantee! However, this is going to involve changing the drop glue for zero-size types to omit the call to free. |
I will begin a patch for this tomorrow. |
@wowus: We do need to decide on the best way to do this though. Passing the size to static EMPTY: () = ();
static EMPTY_PTR: *mut u8 = &EMPTY as *() as *mut u8;
fn alloc(size: uint) -> *mut u8 {
if size == 0 {
EMPTY_PTR
} else {
...
}
}
fn free(ptr: *mut u8, size: uint) {
if size != 0 {
libc::free(ptr);
}
} The Alternatively, |
A solid step towards fixing #11998. Eventually, the size may always be passed to `exchange_free` but this will not be required to fix the bug.
@thestinger: what else needs to be done to get this issue closed? Did you effectively fix it with your PR? |
@wowus: The I don't know if this should also be fixed for |
cc me |
I don't consider these to be the only two solutions. I think we can also guarantee that any allocation which has zero-size will never be dereferenced or freed and just some non-zero value. This will require that when converting |
@nikomatsakis: I did that as part of 1778b63 and #13267. |
@thestinger Indeed. I commented a bit eagerly, I suppose. I read the whole thread now and have some questions:
OTOH, if we can add size checks to free and "fix it once", that is preferable. In any case, I expect we will continue to supply exact sizes to malloc/free (you've convinced me that this makes sense), though I think not all allocators will necessarily care. |
And again I'm late, I suppose, since it seems like the idea of not calling free from the caller is roughly what you did in 898669c. |
Check whether out of bound when access a known length array with a constant index fixes [Issue#11762](rust-lang/rust-clippy#11762) Issue#11762 points that `Array references with known length are not flagged when indexed out of bounds`. To fix this problem, it is needed to add check for `Expr::Index`. We expand this issue include reference and direct accessing a array. When we access a array with a constant index `off`, and already know the length `size`, if `off >= size`, these code will throw an error, instead rustc's lint checking them or runtime panic happening. changelog: [`out_of_bound_indexing`]: Add check for illegal accessing known length array with a constant index
A call to
malloc(0)
may return a null pointer or it may return a unique pointer to an allocation. Rust cannot callmalloc(0)
as then the check for null to determine if the allocation has failed will not work. I special-cased it to always return null for zero-size allocations to avoid this error case.However, this has exposed a new issue. If the exchange allocator returns a null pointer, then the assumption of unique pointers being non-null does not hold. For example,
Some(~())
is considered to beNone
.The only solution I can think of is clamping allocations to a minimum size of 1.
The text was updated successfully, but these errors were encountered: