-
-
Notifications
You must be signed in to change notification settings - Fork 393
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
winapi crashes on x86 because of conflicting stack alignment assumptions #1043
Comments
This should be fixed (well, worked around) by rust-lang/rust#112684. |
I'm seeing this with x86_64-pc-windows-gnu cross-compiled on linux thread 'main' panicked at 'misaligned pointer dereference: address must be a multiple of 0x8 but is 0xc06614', /home/lun/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sysinfo-0.29.4/src/windows/system.rs |
Maybe we need #align(4) on this struct. Or maybe downstream code https://github.com/GuillaumeGomez/sysinfo/blob/3991a4de8a8c39aafdedd82b9cfd465cc385060e/src/windows/system.rs#L257 should be using read_unaligned |
@LunNova which struct are you seeing the issue with? |
Are you running the program in Wine? |
here's the code: https://docs.rs/sysinfo/0.29.4/x86_64-pc-windows-msvc/src/sysinfo/windows/system.rs.html#258 afaict this is the sysinfo crate's fault since it gets a pointer from |
afaict if you run this code on an old 32-bit arm windows computer it will crash (old enough that it doesn't support misaligned loads), rustc is just exploiting the UB to make it panic more places. |
That is mitigated by the fact the default allocator has a minimum alignment of 16 on x64. So unless a custom allocator is used (that doesn't behave like malloc) then it'll still work in practice. |
it also manually offsets by an unknown number of bytes (provided by the win32 function), so, because it's crashing, obviously the number of bytes is not a multiple of the alignment -- UB. |
created a bug: GuillaumeGomez/sysinfo#1009 |
It should be for any real Windows system. Windows itself will not misalign structures in these buffers (they add padding). Emulators or security software that shims APIs may not properly align structures but that's a bug in them. |
Winehq aligns to a multiple of 8: |
on x86_64-pc-windows-gnu, ntapi v0.4.1: |
wine + debug build of x86_64-pc-windows-gnu + let mut sys = sysinfo::System::new();
sys.refresh_processes(); is enough to replicate it. Patching sysinfo with this works around it: diff --git a/src/windows/system.rs b/src/windows/system.rs
index 849d783..b2b4b17 100644
--- a/src/windows/system.rs
+++ b/src/windows/system.rs
@@ -254,7 +254,8 @@ impl SystemExt for System {
.as_ptr()
.offset(process_information_offset)
as *const SYSTEM_PROCESS_INFORMATION;
- let pi = &*p;
+ let pi = std::ptr::read_unaligned(p);
+ let pi = π
process_ids.push(Wrap(p));
@@ -278,7 +279,7 @@ impl SystemExt for System {
// able to run it over `process_information` directly!
let processes = into_iter(process_ids)
.filter_map(|pi| {
- let pi = *pi.0;
+ let pi = std::ptr::read_unaligned(pi.0);
let pid = Pid(pi.UniqueProcessId as _);
if let Some(proc_) = (*process_list.0.get()).get_mut(&pid) {
if proc_ Wine reports its version as 8.0-staging and was built from
|
Such a custom allocator would be totally legitimate though, so there clearly is a bug here (which I see has been reported at GuillaumeGomez/sysinfo#1009, so I think this is resolved). |
Of course. My point was only that it's unlikely to be the cause of the error in the OP. |
Debug builds with new rustc versions add an 8 byte alignment check for every 8 byte read/write. MS however says that 8 byte types need to be 4 byte aligned, so those checks will kill your process if the alignment is not 8 (i.e. in approx. 50% of cases).
An example of crashes in downstream projects is GuillaumeGomez/sysinfo#1001.
The text was updated successfully, but these errors were encountered: