Skip to content
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

Return non-null pointer from malloc(0) #3580

Merged
merged 1 commit into from
May 8, 2024

Conversation

tiif
Copy link
Contributor

@tiif tiif commented May 7, 2024

Use non-null pointer for malloc(0) as mentioned in #3576 to detect leaks and double free of malloc(0) addresses.

@tiif
Copy link
Contributor Author

tiif commented May 7, 2024

@rustbot ready

@rustbot rustbot added the S-waiting-on-review Status: Waiting for a review to complete label May 7, 2024
@RalfJung
Copy link
Member

RalfJung commented May 7, 2024 via email

src/shims/alloc.rs Outdated Show resolved Hide resolved
@tiif
Copy link
Contributor Author

tiif commented May 7, 2024

I am trying to create a use-after-free test, but the test below surprisingly not throwing any error?

    unsafe {
        let ptr = libc::malloc(0);
        libc::free(ptr);
        let _ = *ptr;
    }

@RalfJung
Copy link
Member

RalfJung commented May 7, 2024

Yes, that's how let _ = behaves. It creates the place but doesn't read from it. And yes this is surprising. :) We should really document this better... somewhere...

Use let _val = *ptr;.

@tiif
Copy link
Contributor Author

tiif commented May 7, 2024

I see, right now this error shows up, how is pointer dereference related to Copy?

error[E0507]: cannot move out of `*ptr` which is behind a raw pointer
 --> ./tests/fail-dep/libc/malloc_zero_use_after_free.rs:5:20
  |
5 |         let _val = *ptr;
  |                    ^^^^ move occurs because `*ptr` has type `libc::c_void`, which does not implement the `Copy` trait
  |
help: consider removing the dereference here
  |
5 -         let _val = *ptr;
5 +         let _val = ptr;
  |

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0507`.
error: test failed, to rerun pass `--test ui`

full test:

fn main() {
    unsafe {
        let ptr = libc::malloc(0);
        libc::free(ptr);
        let _val = *ptr;
    }
}

@RalfJung
Copy link
Member

RalfJung commented May 7, 2024 via email

@tiif
Copy link
Contributor Author

tiif commented May 7, 2024

c_void is not Copy so you cannot just do a deref. But anyway this will not give the desired error as ZST accesses are NOPs. I should not have said use after free, sorry. I meant memory leak and double free.

Ah I see, thanks!

@RalfJung
Copy link
Member

RalfJung commented May 7, 2024

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: Waiting for the PR author to address review comments and removed S-waiting-on-review Status: Waiting for a review to complete labels May 7, 2024
@rustbot
Copy link
Collaborator

rustbot commented May 8, 2024

There are merge commits (commits with multiple parents) in your changes. We have a no merge policy so these commits will need to be removed for this pull request to be merged.

You can start a rebase with the following commands:

$ # rebase
$ git pull --rebase https://github.com/rust-lang/miri.git master
$ git push --force-with-lease

The following commits are merge commits:

src/shims/alloc.rs Outdated Show resolved Hide resolved
@tiif
Copy link
Contributor Author

tiif commented May 8, 2024

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Waiting for a review to complete and removed S-waiting-on-author Status: Waiting for the PR author to address review comments labels May 8, 2024
Comment on lines 50 to 52
if size == 0 {
return Align::from_bytes(1).unwrap();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works, but please move it up above the comment that says we will round down.

Also, you can use Align::ONE to avoid an unwrap here.

@RalfJung
Copy link
Member

RalfJung commented May 8, 2024

Awesome. :) Please squash the commits.

@tiif tiif force-pushed the feat/malloc0-non-null-pointer branch from 6489104 to 3a2524a Compare May 8, 2024 20:35
@RalfJung
Copy link
Member

RalfJung commented May 8, 2024

@bors r+

@bors
Copy link
Collaborator

bors commented May 8, 2024

📌 Commit 3a2524a has been approved by RalfJung

It is now in the queue for this repository.

@bors
Copy link
Collaborator

bors commented May 8, 2024

⌛ Testing commit 3a2524a with merge 6714e03...

@bors
Copy link
Collaborator

bors commented May 8, 2024

☀️ Test successful - checks-actions
Approved by: RalfJung
Pushing 6714e03 to master...

@bors bors merged commit 6714e03 into rust-lang:master May 8, 2024
8 checks passed
@tiif tiif deleted the feat/malloc0-non-null-pointer branch May 8, 2024 21:30
@RalfJung RalfJung changed the title Implement non-null pointer for malloc(0) Return non-null pointer from malloc(0) May 9, 2024
@RalfJung
Copy link
Member

RalfJung commented May 9, 2024

I just realized this also affects the Windows HeapAlloc function. @ChrisDenton I didn't find anything in the docs about HeapAlloc with size 0... is it okay for that to return a non-null pointer that must be freed later?

@ChrisDenton
Copy link
Contributor

Sure that's fine. There's no documented restriction on allocating zero bytes and HeapAlloc in practice does in fact return a non-null pointer if you ask for 0 bytes. Though tbh it's not something I'd be in the habit of doing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Waiting for a review to complete
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants