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

miri: fix overflow detection for unsigned pointer offset #130239

Merged
merged 1 commit into from
Sep 12, 2024

Conversation

RalfJung
Copy link
Member

@RalfJung RalfJung commented Sep 11, 2024

This is the Miri part of #130229. This is already UB is planned to become UB in codegen so we better make Miri detect it; updating the docs may take time if we have to follow some approval process, but let's make Miri match reality ASAP.

r? @scottmcm

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 11, 2024
@rustbot
Copy link
Collaborator

rustbot commented Sep 11, 2024

Some changes occurred to the CTFE / Miri engine

cc @rust-lang/miri

The Miri subtree was changed

cc @rust-lang/miri

@compiler-errors
Copy link
Member

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Sep 11, 2024

📌 Commit 3842ea6 has been approved by compiler-errors

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 11, 2024
workingjubilee added a commit to workingjubilee/rustc that referenced this pull request Sep 11, 2024
… r=compiler-errors

miri: fix overflow detection for unsigned pointer offset

This is the Miri part of rust-lang#130229. This is already UB in codegen so we better make Miri detect it; updating the docs may take time if we have to follow some approval process, but let's make Miri match reality ASAP.

r? `@scottmcm`
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 11, 2024
…kingjubilee

Rollup of 11 pull requests

Successful merges:

 - rust-lang#119286 (show linker output even if the linker succeeds)
 - rust-lang#129103 (Don't warn empty branches unreachable for now)
 - rust-lang#129696 (update stdarch)
 - rust-lang#129835 (enable const-float-classify test, and test_next_up/down on 32bit x86)
 - rust-lang#129992 (Update compiler-builtins to 0.1.125)
 - rust-lang#130052 (Don't leave debug locations for constants sitting on the builder indefinitely)
 - rust-lang#130077 (Fix linking error when compiling for 32-bit watchOS)
 - rust-lang#130114 (Remove needless returns detected by clippy in the compiler)
 - rust-lang#130156 (Add test for S_OBJNAME & update test for LF_BUILDINFO cl and cmd)
 - rust-lang#130168 (maint: update docs for change_time ext and doc links)
 - rust-lang#130239 (miri: fix overflow detection for unsigned pointer offset)

r? `@ghost`
`@rustbot` modify labels: rollup
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 11, 2024
…kingjubilee

Rollup of 10 pull requests

Successful merges:

 - rust-lang#129103 (Don't warn empty branches unreachable for now)
 - rust-lang#129696 (update stdarch)
 - rust-lang#129835 (enable const-float-classify test, and test_next_up/down on 32bit x86)
 - rust-lang#130077 (Fix linking error when compiling for 32-bit watchOS)
 - rust-lang#130114 (Remove needless returns detected by clippy in the compiler)
 - rust-lang#130168 (maint: update docs for change_time ext and doc links)
 - rust-lang#130228 (notify Miri when intrinsics are changed)
 - rust-lang#130239 (miri: fix overflow detection for unsigned pointer offset)
 - rust-lang#130244 (Use the same span for attributes and Try expansion of ?)
 - rust-lang#130248 (Limit `libc::link` usage to `nto70` target only, not NTO OS)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 1425982 into rust-lang:master Sep 12, 2024
6 checks passed
@rustbot rustbot added this to the 1.83.0 milestone Sep 12, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Sep 12, 2024
Rollup merge of rust-lang#130239 - RalfJung:miri-ptr-offset-unsigned, r=compiler-errors

miri: fix overflow detection for unsigned pointer offset

This is the Miri part of rust-lang#130229. This is already UB in codegen so we better make Miri detect it; updating the docs may take time if we have to follow some approval process, but let's make Miri match reality ASAP.

r? ``@scottmcm``
@RalfJung RalfJung deleted the miri-ptr-offset-unsigned branch September 12, 2024 06:09
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Oct 1, 2024
…ottmcm

ptr::add/sub: do not claim equivalence with `offset(c as isize)`

In rust-lang#110837, the `offset` intrinsic got changed to also allow a `usize` offset parameter. The intention is that this will do an unsigned multiplication with the size, and we have UB if that overflows -- and we also have UB if the result is larger than `usize::MAX`, i.e., if a subsequent cast to `isize` would wrap. ~~The LLVM backend sets some attributes accordingly.~~

This updates the docs for `add`/`sub` to match that intent, in preparation for adjusting codegen to exploit this UB. We use this opportunity to clarify what the exact requirements are: we compute the offset using mathematical multiplication (so it's no problem to have an `isize * usize` multiplication, we just multiply integers), and the result must fit in an `isize`.
Cc `@rust-lang/opsem` `@nikic`

rust-lang#130239 updates Miri to detect this UB.

`sub` still has some cases of UB not reflected in the underlying intrinsic semantics (and Miri does not catch): when we subtract `usize::MAX`, then after casting to `isize` that's just `-1` so we end up adding one unit without noticing any UB, but actually the offset we gave does not fit in an `isize`. Miri will currently still not complain for such cases:
```rust
fn main() {
    let x = &[0i32; 2];
    let x = x.as_ptr();
    // This should be UB, we are subtracting way too much.
    unsafe { x.sub(usize::MAX).read() };
}
```
However, the LLVM IR we generate here also is UB-free. This is "just" library UB but not language UB.
Cc `@saethlin;` might be worth adding precondition checks against overflow on `offset`/`add`/`sub`?

Fixes rust-lang#130211
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Oct 1, 2024
Rollup merge of rust-lang#130229 - RalfJung:ptr-offset-unsigned, r=scottmcm

ptr::add/sub: do not claim equivalence with `offset(c as isize)`

In rust-lang#110837, the `offset` intrinsic got changed to also allow a `usize` offset parameter. The intention is that this will do an unsigned multiplication with the size, and we have UB if that overflows -- and we also have UB if the result is larger than `usize::MAX`, i.e., if a subsequent cast to `isize` would wrap. ~~The LLVM backend sets some attributes accordingly.~~

This updates the docs for `add`/`sub` to match that intent, in preparation for adjusting codegen to exploit this UB. We use this opportunity to clarify what the exact requirements are: we compute the offset using mathematical multiplication (so it's no problem to have an `isize * usize` multiplication, we just multiply integers), and the result must fit in an `isize`.
Cc `@rust-lang/opsem` `@nikic`

rust-lang#130239 updates Miri to detect this UB.

`sub` still has some cases of UB not reflected in the underlying intrinsic semantics (and Miri does not catch): when we subtract `usize::MAX`, then after casting to `isize` that's just `-1` so we end up adding one unit without noticing any UB, but actually the offset we gave does not fit in an `isize`. Miri will currently still not complain for such cases:
```rust
fn main() {
    let x = &[0i32; 2];
    let x = x.as_ptr();
    // This should be UB, we are subtracting way too much.
    unsafe { x.sub(usize::MAX).read() };
}
```
However, the LLVM IR we generate here also is UB-free. This is "just" library UB but not language UB.
Cc `@saethlin;` might be worth adding precondition checks against overflow on `offset`/`add`/`sub`?

Fixes rust-lang#130211
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants