-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Tracking Issue for future-incompatibility warning unaligned_references
#82523
Comments
…ochenkov make unaligned_references future-incompat lint warn-by-default and also remove the safe_packed_borrows lint that it replaces. `std::ptr::addr_of!` has hit beta now and will hit stable in a month, so I propose we start fixing rust-lang#27060 for real: creating a reference to a field of a packed struct needs to eventually become a hard error; this PR makes it a warn-by-default future-incompat lint. (The lint already existed, this just raises its default level.) At the same time I removed the corresponding code from unsafety checking; really there's no reason an `unsafe` block should make any difference here. For references to packed fields outside `unsafe` blocks, this means `unaligned_refereces` replaces the previous `safe_packed_borrows` warning with a link to rust-lang#82523 (and no more talk about unsafe blocks making any difference). So behavior barely changes, the warning is just worded differently. For references to packed fields inside `unsafe` blocks, this PR shows a new future-incompat warning. Closes rust-lang#46043 because that lint no longer exists.
error: reference to packed field is unaligned --> virtio-devices/src/vhost_user/fs.rs:85:21 | 85 | fs.flags[i].bits() as i32, | ^^^^^^^^^^^ | = note: `-D unaligned-references` implied by `-D warnings` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <rust-lang/rust#82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) Signed-off-by: Rob Bradford <[email protected]>
error: reference to packed field is unaligned --> virtio-devices/src/vhost_user/fs.rs:85:21 | 85 | fs.flags[i].bits() as i32, | ^^^^^^^^^^^ | = note: `-D unaligned-references` implied by `-D warnings` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <rust-lang/rust#82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) Signed-off-by: Rob Bradford <[email protected]>
error: reference to packed field is unaligned --> virtio-devices/src/vhost_user/fs.rs:85:21 | 85 | fs.flags[i].bits() as i32, | ^^^^^^^^^^^ | = note: `-D unaligned-references` implied by `-D warnings` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <rust-lang/rust#82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) Signed-off-by: Rob Bradford <[email protected]>
Just like how it is done in the top-level Cargo.toml. This fixes a warning [0] when building the fuzzer binaries. [0] rust-lang/rust#82523 Signed-off-by: Wei Liu <[email protected]>
Just like how it is done in the top-level Cargo.toml. This fixes a warning [0] when building the fuzzer binaries. [0] rust-lang/rust#82523 Signed-off-by: Wei Liu <[email protected]>
fix warning, when compiling with 1.53.0 ``` warning: reference to packed field is unaligned --> src/vhost_user/message.rs:252:53 | 252 | unsafe { std::mem::transmute_copy::<u32, R>(&self.request) } | ^^^^^^^^^^^^^ | = note: `#[warn(unaligned_references)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <rust-lang/rust#82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) ``` Signed-off-by: wanglei <[email protected]>
Should this be deny-by-default for the 2021 edition, or is it too early for this list (and too late for the edition)? |
IIRC the consensus was that since this problem affects all editions, it would not make sense to make it deny-by-default in only in some editions. |
This will be an error some day. warning: reference to packed field is unaligned --> src/certs/sev/cert/mod.rs:176:47 | 176 | 1 => PublicKey::try_from(unsafe { &value.v1.body.data.key }), | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(unaligned_references)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <rust-lang/rust#82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) Also bump the minimum stable compiler. The addr_of! macro was introduced in 1.51.0. Signed-off-by: Connor Kuehl <[email protected]>
Sorry if this is not the right place for this question, but I'm curious about how to do method calls with #[repr(packed)]
pub struct Obj {
pub field: String,
}
pub unsafe fn test(concat: *const Obj) {
println!("{}", (*concat).field.len());
// ^^^^^^^^^^^^^^^ "reference to packed field is unaligned"
} Here a reference is created implicitly for the method call, causing the warning. Since the method is defined in a library I can't make it a When I have the control over called methods, do I make the methods take a When compiling to platforms with no alignment restrictions (such as Wasm) is there a way to relax this check? Finally, looking at https://doc.rust-lang.org/reference/behavior-considered-undefined.html (linked in the issue description), it doesn't mention unaligned references. Should it be updated? It also doesn't link to this issue. |
It is not possible (and has never been possible) to call such methods on packed fields. You have to first move the data to some well-aligned place, and then call the method.
It does, the following is listed as UB due to producing an invalid value: "A reference or Box that is dangling, unaligned, or points to an invalid value." |
I'm confused by this. My example above does exactly this, and it used to work without warnings a few versions ago. It works today, but generates a warning. Did I misunderstand what you mean? Do you mean it's never supposed to work, rather than it never worked? |
This was previously accepted by the compiler, then it was being phased out, and finally it became a hard error. For more information, see Rust issue #82523 rust-lang/rust#82523
…lot,scottmcm make unaligned_reference a hard error The `unaligned_references` lint has been warn-by-default since Rust 1.53 (rust-lang/rust#82525) and deny-by-default with mention in cargo future-incompat reports since Rust 1.62 (rust-lang/rust#95372). Current nightly will become Rust 1.66, so (unless major surprises show up with crater) I think it is time we make this a hard error, and close this old soundness gap in the language. EDIT: Turns out this will only land for Rust 1.67, so there is another 6 weeks of time here for crates to adjust. Fixes rust-lang/rust#82523.
warning: lint `unaligned_references` has been removed: converted into hard error, see issue #82523 <rust-lang/rust#82523> for more information --> test_suite/tests/test_macros.rs:1931:8 | 1931 | #[deny(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(renamed_and_removed_lints)]` on by default
It's been 7.5 years since #27060 was reported, but the problem is finally fixed for good. :) |
This fixes the warning: warning: lint `unaligned_references` has been removed: converted into hard error, see issue #82523 <rust-lang/rust#82523> for more information
Obtaining reference of unaligned fields is being phased out. Therefore, `&struct.field` is replaced with `std::ptr::addr_of!(struct.field)` to avoid those warning issues. For more details, please refer to rust-lang/rust#82523. Fixes: openanolis#273 Signed-off-by: Xuewei Niu <[email protected]>
Obtaining reference of unaligned fields is being phased out. Therefore, `&struct.field` is replaced with `std::ptr::addr_of!(struct.field)` to avoid those warning issues. For more details, please refer to rust-lang/rust#82523. Fixes: #273 Signed-off-by: Xuewei Niu <[email protected]>
I ran into #110777 today, but now I'm wondering why you can't form a reference to a field |
Because |
Oh, I forgot that |
You can: pub(crate) struct UInt16LE {
bytes: [u8; 2],
}
#[repr(C, packed)] // struct has the same layout without the `packed`!
pub(crate) struct Header {
version: u8,
kind: UInt16LE,
}
const _: () = {
assert!(std::mem::align_of::<Header>() == 1);
};
fn main() {
let h = Header { version: 0, kind: UInt16LE { bytes: [0, 0] }};
let r = &h.kind; // taking the reference
} Your issue is that |
That makes sense. For some reason I was hoping there was some kind of autoref trick involved rather than the derive-macro simply making a choice, but it makes sense that it does not do this. Sorry for the noise, then! (And thanks everyone for the help in both places.) |
The derive macro can't know whether the field types are 1-aligned or packed, so it does the common thing. If you need something else, you'll have to write out the impl yourself. |
Obtaining reference of unaligned fields is being phased out. Therefore, `&struct.field` is replaced with `std::ptr::addr_of!(struct.field)` to avoid those warning issues. For more details, please refer to rust-lang/rust#82523. Fixes: openanolis#273 Signed-off-by: Xuewei Niu <[email protected]>
lint `unaligned_references` has been removed: converted into hard error, see issue #82523 <rust-lang/rust#82523> for more information
This is a tracking issue for the future-incompatibility warning
unaligned_references
.This warning will fire for code like the following:
The reason this pattern is being phased out is that Rust requires references to always be aligned; creating an unaligned reference falls under the "creating an invalid value" clause in the Rust definition of Undefined Behavior. Fields of packed structs are not necessarily properly aligned. Hence creating a reference to a field of a packed struct can cause UB, even if it is never used, and even inside an
unsafe
block. This is a soundness bug, which is fixed by deprecating and eventually disallowing this pattern.Previously, a future-incompatibility warning was emitted when creating references to packed fields outside an unsafe block; however, that warning was incorrectly silenced inside unsafe blocks.
To fix this code, it needs to stop creating a reference to a packed field. The alternative is to either just copy the packed field by adding curly braces (the compiler knows how to do that despite lack of alignment), or to create a raw pointer:
For further background, see #46043, #27060.
The text was updated successfully, but these errors were encountered: