-
Notifications
You must be signed in to change notification settings - Fork 488
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
replace 'UB on raw ptr deref' with UB on place projection/access #1387
Conversation
I am not sure if this counts as a "small" decision that t-opsem can just make without t-lang involvement, so I'll add both teams. This is an irreversible decision after all and a change to the core "list of UB", that seems quite fundamental. The justification for why we think this first example should not be UB is mostly that many people are confused about the entire place expression business, so they don't realize The justification for keeping the later 2 examples UB is that our current codegen actually does exploit both of them, so allowing them comes at a cost. The first example should be rather uncontroversial; the fact that every access has to be in-bounds and aligned has never been up for debate. The second example is probably less clear, but we do want to keep using @rfcbot fcp merge |
Team member @RalfJung has proposed to merge this. The next step is review by the rest of the tagged team members:
No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns. |
Fwiw I don't expect this example to have needed T-lang signoff, but there's no harm. @rfcbot reviewed |
@rfcbot reviewed |
rust-lang/rust#114330 implements this change in Miri. I found some other interesting cases that are allowed now. A mere "place mention" of a dangling place is no longer UB -- that is in line with fn deref_invalid_underscore() {
unsafe {
let _ = *ptr::invalid::<i32>(0);
let _ = *ptr::invalid::<i32>(1);
}
} If fn deref_partially_dangling() {
let x = (1, 13);
let xptr = &x as *const _ as *const (i32, i32, i32);
let val = unsafe { (*xptr).1 };
assert_eq!(val, 13);
} |
Ah, and here is another fun one that is allowed now: fn deref_too_big_slice() {
unsafe {
let slice: *const [u8] = mem::transmute((1usize, usize::MAX));
let _val = addr_of!(*slice);
}
}
|
Have we decided that the order of the fields in the tuple |
No we have not decided that, the proper version of that test would use a |
This makes good sense to me. Having |
@rfcbot reviewed |
1 similar comment
@rfcbot reviewed |
I agree with this and don't have any blocking concerns over this change specifically. But I am concerned that this will lead users to a mental model where place projections inside At a high level I would like us to strongly prefer simple rules for what is and isn't UB, wherever possible, and justify complexity as either inherently necessary or temporary. " From the description it sounded like this condition might be temporary (and is due to a current limitation in LLVM), but if we could wave a magic wand and fix the LLVM limitation, are we sure we would? |
I agree, generally, but I think this is a problem of documentation. Currently we have essentially no documentation for what valid uses of |
With any luck |
Those are the rules we currently have. I also think they are simpler. But many, many people have been caught off-guard by the fact that
You just have to separate alignment and inbounds:
|
If this is talking about the requirement that field projections follow the rules of the We considered weakening the requirements of |
🔔 This is now entering its final comment period, as per the review above. 🔔 psst @RalfJung, I wasn't able to add the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Update books ## rust-lang/reference 2 commits in 5262e1c3b43a2c489df8f6717683a44c7a2260fd..142b2ed77d33f37a9973772bd95e6144ed9dce43 2023-10-07 19:41:21 UTC to 2023-09-26 12:26:35 UTC - replace 'UB on raw ptr deref' with UB on place projection/access (rust-lang/reference#1387) - docs: Fix links to ECMA standards in `attributes.md` (rust-lang/reference#1408) ## rust-lang/rust-by-example 11 commits in c954202c1e1720cba5628f99543cc01188c7d6fc..8eb3a01ab74c567b7174784892fb807f2c632d6b 2023-09-26 12:38:17 UTC to 2023-09-26 12:29:10 UTC - fixed a typo in the lifetime.md (rust-lang/rust-by-example#1737) - Misleading textual statement in HOF (rust-lang/rust-by-example#1731) - Equalize title from respective file with title in SUMMARY.md (rust-lang/rust-by-example#1738) - Added explanation for compiling and executing match_args.rs. (rust-lang/rust-by-example#1739) - Wrapped long lines and put #[doc] in backquotes. (rust-lang/rust-by-example#1740) - Update read_lines example to flatten iterator (rust-lang/rust-by-example#1742) - Update while_let.md: address inconsistent use of fn main between 2 co… (rust-lang/rust-by-example#1744) - [TRIVIAL] Remove confusing `also` (rust-lang/rust-by-example#1746) - Fix and extend the explanation of outer vs inner attributes. (rust-lang/rust-by-example#1748) - Fix uncorresponded back quote (rust-lang/rust-by-example#1749) - Fix format in constants.md (rust-lang/rust-by-example#1741) ## rust-lang/rustc-dev-guide 3 commits in a13b7c28ed705891c681ce5417b3d1cdb12cecd1..b98af7d661e4744baab81fb8dc7a049e44a4a998 2023-10-05 19:48:35 UTC to 2023-09-27 22:57:27 UTC - update new trait solver docs (rust-lang/rustc-dev-guide#1802) - update rustc_driver examples (rust-lang/rustc-dev-guide#1803) - test headers: fix `compile-flags` example (rust-lang/rustc-dev-guide#1800)
Update books ## rust-lang/reference 2 commits in 5262e1c3b43a2c489df8f6717683a44c7a2260fd..142b2ed77d33f37a9973772bd95e6144ed9dce43 2023-10-07 19:41:21 UTC to 2023-09-26 12:26:35 UTC - replace 'UB on raw ptr deref' with UB on place projection/access (rust-lang/reference#1387) - docs: Fix links to ECMA standards in `attributes.md` (rust-lang/reference#1408) ## rust-lang/rust-by-example 11 commits in c954202c1e1720cba5628f99543cc01188c7d6fc..8eb3a01ab74c567b7174784892fb807f2c632d6b 2023-09-26 12:38:17 UTC to 2023-09-26 12:29:10 UTC - fixed a typo in the lifetime.md (rust-lang/rust-by-example#1737) - Misleading textual statement in HOF (rust-lang/rust-by-example#1731) - Equalize title from respective file with title in SUMMARY.md (rust-lang/rust-by-example#1738) - Added explanation for compiling and executing match_args.rs. (rust-lang/rust-by-example#1739) - Wrapped long lines and put #[doc] in backquotes. (rust-lang/rust-by-example#1740) - Update read_lines example to flatten iterator (rust-lang/rust-by-example#1742) - Update while_let.md: address inconsistent use of fn main between 2 co… (rust-lang/rust-by-example#1744) - [TRIVIAL] Remove confusing `also` (rust-lang/rust-by-example#1746) - Fix and extend the explanation of outer vs inner attributes. (rust-lang/rust-by-example#1748) - Fix uncorresponded back quote (rust-lang/rust-by-example#1749) - Fix format in constants.md (rust-lang/rust-by-example#1741) ## rust-lang/rustc-dev-guide 3 commits in a13b7c28ed705891c681ce5417b3d1cdb12cecd1..b98af7d661e4744baab81fb8dc7a049e44a4a998 2023-10-05 19:48:35 UTC to 2023-09-27 22:57:27 UTC - update new trait solver docs (rust-lang/rustc-dev-guide#1802) - update rustc_driver examples (rust-lang/rustc-dev-guide#1803) - test headers: fix `compile-flags` example (rust-lang/rustc-dev-guide#1800)
Update books ## rust-lang/reference 2 commits in 5262e1c3b43a2c489df8f6717683a44c7a2260fd..142b2ed77d33f37a9973772bd95e6144ed9dce43 2023-10-07 19:41:21 UTC to 2023-09-26 12:26:35 UTC - replace 'UB on raw ptr deref' with UB on place projection/access (rust-lang/reference#1387) - docs: Fix links to ECMA standards in `attributes.md` (rust-lang/reference#1408) ## rust-lang/rust-by-example 11 commits in c954202c1e1720cba5628f99543cc01188c7d6fc..8eb3a01ab74c567b7174784892fb807f2c632d6b 2023-09-26 12:38:17 UTC to 2023-09-26 12:29:10 UTC - fixed a typo in the lifetime.md (rust-lang/rust-by-example#1737) - Misleading textual statement in HOF (rust-lang/rust-by-example#1731) - Equalize title from respective file with title in SUMMARY.md (rust-lang/rust-by-example#1738) - Added explanation for compiling and executing match_args.rs. (rust-lang/rust-by-example#1739) - Wrapped long lines and put #[doc] in backquotes. (rust-lang/rust-by-example#1740) - Update read_lines example to flatten iterator (rust-lang/rust-by-example#1742) - Update while_let.md: address inconsistent use of fn main between 2 co… (rust-lang/rust-by-example#1744) - [TRIVIAL] Remove confusing `also` (rust-lang/rust-by-example#1746) - Fix and extend the explanation of outer vs inner attributes. (rust-lang/rust-by-example#1748) - Fix uncorresponded back quote (rust-lang/rust-by-example#1749) - Fix format in constants.md (rust-lang/rust-by-example#1741) ## rust-lang/rustc-dev-guide 3 commits in a13b7c28ed705891c681ce5417b3d1cdb12cecd1..b98af7d661e4744baab81fb8dc7a049e44a4a998 2023-10-05 19:48:35 UTC to 2023-09-27 22:57:27 UTC - update new trait solver docs (rust-lang/rustc-dev-guide#1802) - update rustc_driver examples (rust-lang/rustc-dev-guide#1803) - test headers: fix `compile-flags` example (rust-lang/rustc-dev-guide#1800)
Update books ## rust-lang/reference 2 commits in 5262e1c3b43a2c489df8f6717683a44c7a2260fd..142b2ed77d33f37a9973772bd95e6144ed9dce43 2023-10-07 19:41:21 UTC to 2023-09-26 12:26:35 UTC - replace 'UB on raw ptr deref' with UB on place projection/access (rust-lang/reference#1387) - docs: Fix links to ECMA standards in `attributes.md` (rust-lang/reference#1408) ## rust-lang/rust-by-example 11 commits in c954202c1e1720cba5628f99543cc01188c7d6fc..8eb3a01ab74c567b7174784892fb807f2c632d6b 2023-09-26 12:38:17 UTC to 2023-09-26 12:29:10 UTC - fixed a typo in the lifetime.md (rust-lang/rust-by-example#1737) - Misleading textual statement in HOF (rust-lang/rust-by-example#1731) - Equalize title from respective file with title in SUMMARY.md (rust-lang/rust-by-example#1738) - Added explanation for compiling and executing match_args.rs. (rust-lang/rust-by-example#1739) - Wrapped long lines and put #[doc] in backquotes. (rust-lang/rust-by-example#1740) - Update read_lines example to flatten iterator (rust-lang/rust-by-example#1742) - Update while_let.md: address inconsistent use of fn main between 2 co… (rust-lang/rust-by-example#1744) - [TRIVIAL] Remove confusing `also` (rust-lang/rust-by-example#1746) - Fix and extend the explanation of outer vs inner attributes. (rust-lang/rust-by-example#1748) - Fix uncorresponded back quote (rust-lang/rust-by-example#1749) - Fix format in constants.md (rust-lang/rust-by-example#1741) ## rust-lang/rustc-dev-guide 3 commits in a13b7c28ed705891c681ce5417b3d1cdb12cecd1..b98af7d661e4744baab81fb8dc7a049e44a4a998 2023-10-05 19:48:35 UTC to 2023-09-27 22:57:27 UTC - update new trait solver docs (rust-lang/rustc-dev-guide#1802) - update rustc_driver examples (rust-lang/rustc-dev-guide#1803) - test headers: fix `compile-flags` example (rust-lang/rustc-dev-guide#1800)
Rollup merge of rust-lang#116574 - rustbot:docs-update, r=ehuss Update books ## rust-lang/reference 2 commits in 5262e1c3b43a2c489df8f6717683a44c7a2260fd..142b2ed77d33f37a9973772bd95e6144ed9dce43 2023-10-07 19:41:21 UTC to 2023-09-26 12:26:35 UTC - replace 'UB on raw ptr deref' with UB on place projection/access (rust-lang/reference#1387) - docs: Fix links to ECMA standards in `attributes.md` (rust-lang/reference#1408) ## rust-lang/rust-by-example 11 commits in c954202c1e1720cba5628f99543cc01188c7d6fc..8eb3a01ab74c567b7174784892fb807f2c632d6b 2023-09-26 12:38:17 UTC to 2023-09-26 12:29:10 UTC - fixed a typo in the lifetime.md (rust-lang/rust-by-example#1737) - Misleading textual statement in HOF (rust-lang/rust-by-example#1731) - Equalize title from respective file with title in SUMMARY.md (rust-lang/rust-by-example#1738) - Added explanation for compiling and executing match_args.rs. (rust-lang/rust-by-example#1739) - Wrapped long lines and put #[doc] in backquotes. (rust-lang/rust-by-example#1740) - Update read_lines example to flatten iterator (rust-lang/rust-by-example#1742) - Update while_let.md: address inconsistent use of fn main between 2 co… (rust-lang/rust-by-example#1744) - [TRIVIAL] Remove confusing `also` (rust-lang/rust-by-example#1746) - Fix and extend the explanation of outer vs inner attributes. (rust-lang/rust-by-example#1748) - Fix uncorresponded back quote (rust-lang/rust-by-example#1749) - Fix format in constants.md (rust-lang/rust-by-example#1741) ## rust-lang/rustc-dev-guide 3 commits in a13b7c28ed705891c681ce5417b3d1cdb12cecd1..b98af7d661e4744baab81fb8dc7a049e44a4a998 2023-10-05 19:48:35 UTC to 2023-09-27 22:57:27 UTC - update new trait solver docs (rust-lang/rustc-dev-guide#1802) - update rustc_driver examples (rust-lang/rustc-dev-guide#1803) - test headers: fix `compile-flags` example (rust-lang/rustc-dev-guide#1800)
don't UB on dangling ptr deref, instead check inbounds on projections This implements rust-lang/reference#1387 in Miri. See that PR for what the change is about. Detecting dangling references in `let x = &...;` is now done by validity checking only, so some tests need to have validity checking enabled. There is no longer inherently a "nodangle" check in evaluating the expression `&*ptr` (aside from the aliasing model). r? `@oli-obk` Based on: - rust-lang/reference#1387 - rust-lang#115524
don't UB on dangling ptr deref, instead check inbounds on projections This implements rust-lang/reference#1387 in Miri. See that PR for what the change is about. Detecting dangling references in `let x = &...;` is now done by validity checking only, so some tests need to have validity checking enabled. There is no longer inherently a "nodangle" check in evaluating the expression `&*ptr` (aside from the aliasing model). r? `@oli-obk` Based on: - rust-lang/reference#1387 - rust-lang/rust#115524
Update the alignment checks to match rust-lang/reference#1387 Previously, we had a special case to not check `Rvalue::AddressOf` in this pass because we weren't quite sure if pointers needed to be aligned in the Place passed to it: rust-lang#112026 Since rust-lang/reference#1387 merged, this PR updates this pass to match. The behavior of the check is nearly unchanged, except we also avoid inserting a check for creating references. Most of the changes in this PR are cleanup and new tests.
Update the alignment checks to match rust-lang/reference#1387 Previously, we had a special case to not check `Rvalue::AddressOf` in this pass because we weren't quite sure if pointers needed to be aligned in the Place passed to it: rust-lang#112026 Since rust-lang/reference#1387 merged, this PR updates this pass to match. The behavior of the check is nearly unchanged, except we also avoid inserting a check for creating references. Most of the changes in this PR are cleanup and new tests.
update and clarify addr_of docs This updates the docs to match rust-lang/reference#1387. Cc `@rust-lang/opsem` `@chorman0773` not sure if you had anything else you wanted to say here, I'd be happy to get your feedback. :) Fixes rust-lang#114902, so Cc `@joshlf`
Update the alignment checks to match rust-lang/reference#1387 Previously, we had a special case to not check `Rvalue::AddressOf` in this pass because we weren't quite sure if pointers needed to be aligned in the Place passed to it: rust-lang/rust#112026 Since rust-lang/reference#1387 merged, this PR updates this pass to match. The behavior of the check is nearly unchanged, except we also avoid inserting a check for creating references. Most of the changes in this PR are cleanup and new tests.
update and clarify addr_of docs This updates the docs to match rust-lang/reference#1387. Cc `@rust-lang/opsem` `@chorman0773` not sure if you had anything else you wanted to say here, I'd be happy to get your feedback. :) Fixes rust-lang/rust#114902, so Cc `@joshlf`
Update the alignment checks to match rust-lang/reference#1387 Previously, we had a special case to not check `Rvalue::AddressOf` in this pass because we weren't quite sure if pointers needed to be aligned in the Place passed to it: rust-lang/rust#112026 Since rust-lang/reference#1387 merged, this PR updates this pass to match. The behavior of the check is nearly unchanged, except we also avoid inserting a check for creating references. Most of the changes in this PR are cleanup and new tests.
Update the alignment checks to match rust-lang/reference#1387 Previously, we had a special case to not check `Rvalue::AddressOf` in this pass because we weren't quite sure if pointers needed to be aligned in the Place passed to it: rust-lang/rust#112026 Since rust-lang/reference#1387 merged, this PR updates this pass to match. The behavior of the check is nearly unchanged, except we also avoid inserting a check for creating references. Most of the changes in this PR are cleanup and new tests.
…nethercote Taking a raw ref (`&raw (const|mut)`) of a deref of pointer (`*ptr`) is always safe T-opsem decided in rust-lang/reference#1387 that `*ptr` is only unsafe if the place is accessed. This means that taking a raw ref of a deref expr is always safe, since it doesn't constitute a read. This also relaxes the `DEREF_NULLPTR` lint to stop warning in the case of raw ref of a deref'd nullptr, and updates its docs to reflect that change in the UB specification. This does not change the behavior of `addr_of!((*ptr).field)`, since field projections still require the projection is in-bounds. I'm on the fence whether this requires an FCP, since it's something that is guaranteed by the reference you could ostensibly call this a bugfix since we were counting truly safe operations as unsafe. Perhaps someone on opsem has a strong opinion? cc `@rust-lang/opsem`
Rollup merge of rust-lang#129248 - compiler-errors:raw-ref-deref, r=nnethercote Taking a raw ref (`&raw (const|mut)`) of a deref of pointer (`*ptr`) is always safe T-opsem decided in rust-lang/reference#1387 that `*ptr` is only unsafe if the place is accessed. This means that taking a raw ref of a deref expr is always safe, since it doesn't constitute a read. This also relaxes the `DEREF_NULLPTR` lint to stop warning in the case of raw ref of a deref'd nullptr, and updates its docs to reflect that change in the UB specification. This does not change the behavior of `addr_of!((*ptr).field)`, since field projections still require the projection is in-bounds. I'm on the fence whether this requires an FCP, since it's something that is guaranteed by the reference you could ostensibly call this a bugfix since we were counting truly safe operations as unsafe. Perhaps someone on opsem has a strong opinion? cc `@rust-lang/opsem`
As discussed by @rust-lang/opsem in rust-lang/opsem-team#9: instead of saying that
*ptr
is insta-UB for "bad" pointers, only have UB when the place is actually accessed, and when place projections go out-of-bounds.This makes the following code (which currently has UB) legal:
However, the following code is still UB: