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

Fix UB from misalignment and provenance widening in std::sys::windows #101171

Merged
merged 4 commits into from
Aug 31, 2022

Conversation

thomcc
Copy link
Member

@thomcc thomcc commented Aug 29, 2022

This fixes two types of UB:

  1. Reading past the end of a reference in types like &c::REPARSE_DATA_BUFFER (see Storing an object as &Header, but reading the data past the end of the header unsafe-code-guidelines#256). This is fixed by using addr_of!. I think there are probably a couple more cases where we do this for other structures, and will look into it in a bit.

  2. Failing to ensure that a [u8; N] on the stack is sufficiently aligned to convert to a REPARSE_DATA_BUFFER. This was done by introducing a new AlignedAs struct that allows aligning one type to the alignment of another type. I expect there are other places where we have this issue too, or I wouldn't introduce this type, but will get to them after this lands.

    Worth noting, it is implemented in a way that can cause problems depending on how we fix repr(C) is unsound on MSVC targets #81996, but this would be caught by the test I added (and presumably if we decide to fix that in a way that would break this code, we'd also introduce a #[repr(simple)] or #[repr(linear)] as a replacement for this usage of #[repr(C)]).

    Edit: None of that is still in the code, I just went with a Align8 since that's all we'll need for almost everything we want to call.

These are more or less "potential UB" since it's likely at the moment everything works fine, although the alignment not causing issues might just be down to luck (and x86 being forgiving).

NB: I've only ensured this check builds, but will run tests soon. All tests pass, including stage2 compiler tests.

r? @ChrisDenton

@rustbot rustbot added the T-libs Relevant to the library team, which will review and decide on the PR/issue. label Aug 29, 2022
@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 29, 2022
@thomcc thomcc added the O-windows Operating system: Windows label Aug 29, 2022
Copy link
Member

@ChrisDenton ChrisDenton left a comment

Choose a reason for hiding this comment

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

Ok, I think this is basically fine. Only one thing that I think needs to be addressed, the other comments are just me being resigned to Rust not having better support for this atm. 🤷

library/std/src/sys/windows/c.rs Show resolved Hide resolved
library/std/src/sys/windows/mod.rs Outdated Show resolved Hide resolved
library/std/src/sys/windows/fs.rs Outdated Show resolved Hide resolved
@ChrisDenton
Copy link
Member

ChrisDenton commented Aug 30, 2022

Oh, just noticed:

let mut data = [0u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];

EDIT: Wait no that's a different buffer... for some reason.

@thomcc
Copy link
Member Author

thomcc commented Aug 30, 2022

EDIT: Wait no that's a different buffer... for some reason.

It's still wrong the way it's written, I think?

That said there are a couple places in this file that are like this that I didn't touch (for example, it's not 100% clear to me what the best fix for the DirBuff stuff would be, but I was just going to tackle it later).

@ChrisDenton
Copy link
Member

It's still wrong the way it's written, I think?

Yeah, but I'm ok with this PR being more focused. That said, I'm also more than happy for you to fix that too!

@thomcc
Copy link
Member Author

thomcc commented Aug 30, 2022

I fixed it. It actually was wrong in another way, since it was turning a pointer derived from data.as_ptr() into a mutable pointer, which is wrong because it's mutating a pointer derived from &self, which can't give out mutable pointers.

(Tragically as_mut_ptr() would also be wrong -- that goes through &mut self which would invalidate the other pointers derived from it, so I just added a new local for data.value.as_mut_ptr())

@ChrisDenton
Copy link
Member

lgtm

@bors r+

@bors
Copy link
Contributor

bors commented Aug 30, 2022

📌 Commit d9c760d has been approved by ChrisDenton

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 Aug 30, 2022
@thomcc
Copy link
Member Author

thomcc commented Aug 30, 2022

@bors r-

After a quick discussion with @ChrisDenton I'm actually going to simplify this a bit.

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Aug 30, 2022
@rustbot rustbot added the T-infra Relevant to the infrastructure team, which will review and decide on the PR/issue. label Aug 30, 2022
@thomcc
Copy link
Member Author

thomcc commented Aug 30, 2022

I'll remove the donotland CI changes after it passes (don't have a convenient windows box right now)

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@thomcc
Copy link
Member Author

thomcc commented Aug 30, 2022

@thomcc thomcc removed the T-infra Relevant to the infrastructure team, which will review and decide on the PR/issue. label Aug 30, 2022
@ChrisDenton
Copy link
Member

@bors r+

@bors
Copy link
Contributor

bors commented Aug 30, 2022

📌 Commit c41f21b has been approved by ChrisDenton

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-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Aug 30, 2022
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Aug 31, 2022
Fix UB from misalignment and provenance widening in `std::sys::windows`

This fixes two types of UB:

1. Reading past the end of a reference in types like `&c::REPARSE_DATA_BUFFER` (see rust-lang/unsafe-code-guidelines#256). This is fixed by using `addr_of!`. I think there are probably a couple more cases where we do this for other structures, and will look into it in a bit.

2. Failing to ensure that a `[u8; N]` on the stack is sufficiently aligned to convert to a `REPARSE_DATA_BUFFER`. ~~This was done by introducing a new `AlignedAs` struct that allows aligning one type to the alignment of another type. I expect there are other places where we have this issue too, or I wouldn't introduce this type, but will get to them after this lands.~~

    ~~Worth noting, it *is* implemented in a way that can cause problems depending on how we fix rust-lang#81996, but this would be caught by the test I added (and presumably if we decide to fix that in a way that would break this code, we'd also introduce a `#[repr(simple)]` or `#[repr(linear)]` as a replacement for this usage of `#[repr(C)]`).~~

    Edit: None of that is still in the code, I just went with a `Align8` since that's all we'll need for almost everything we want to call.

These are more or less "potential UB" since it's likely at the moment everything works fine, although the alignment not causing issues might just be down to luck (and x86 being forgiving).

~~NB: I've only ensured this check builds, but will run tests soon.~~ All tests pass, including stage2 compiler tests.

r? `@ChrisDenton`
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 31, 2022
…iaskrgr

Rollup of 8 pull requests

Successful merges:

 - rust-lang#100970 (Allow deriving multipart suggestions)
 - rust-lang#100984 (Reinstate preloading of some dll imports)
 - rust-lang#101011 (Use getentropy when possible on all Apple platforms)
 - rust-lang#101025 (Add tier-3 support for powerpc64 and riscv64 openbsd)
 - rust-lang#101049 (Remove span fatal from ast lowering)
 - rust-lang#101100 (Make call suggestions more general and more accurate)
 - rust-lang#101171 (Fix UB from misalignment and provenance widening in `std::sys::windows`)
 - rust-lang#101185 (Tweak `WellFormedLoc`s a bit)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 0ed046f into rust-lang:master Aug 31, 2022
@rustbot rustbot added this to the 1.65.0 milestone Aug 31, 2022
@thomcc thomcc deleted the fix-winfs-ub branch August 31, 2022 15:26
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Aug 31, 2022
Avoid needless buffer zeroing in `std::sys::windows::fs`

Followup to rust-lang#101171 and rust-lang#101193. This finishes up avoiding buffer zeroing pointed out in rust-lang#100729 (comment) (thanks!)

r? `@ChrisDenton`
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this pull request Sep 7, 2022
Avoid UB in the Windows filesystem code in... bootstrap?

This basically a subset of the changes from rust-lang#101171. I didn't think to look in src/bootstrap for more windows filesystem API usage, which was apparently a mistake on my part. It's kinda goofy that stuff like this is in here, but what are you gonna do, computers are awful.

I also added `winbase` to the `winapi` dep -- I tested this in a tmp crate but needed to add this to your Cargo.toml -- you `use winapi::stuff::winbase` in this function, but are relying on something else turning on that feature.
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this pull request Sep 7, 2022
Avoid UB in the Windows filesystem code in... bootstrap?

This basically a subset of the changes from rust-lang#101171. I didn't think to look in src/bootstrap for more windows filesystem API usage, which was apparently a mistake on my part. It's kinda goofy that stuff like this is in here, but what are you gonna do, computers are awful.

I also added `winbase` to the `winapi` dep -- I tested this in a tmp crate but needed to add this to your Cargo.toml -- you `use winapi::stuff::winbase` in this function, but are relying on something else turning on that feature.
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this pull request Sep 8, 2022
Avoid UB in the Windows filesystem code in... bootstrap?

This basically a subset of the changes from rust-lang#101171. I didn't think to look in src/bootstrap for more windows filesystem API usage, which was apparently a mistake on my part. It's kinda goofy that stuff like this is in here, but what are you gonna do, computers are awful.

I also added `winbase` to the `winapi` dep -- I tested this in a tmp crate but needed to add this to your Cargo.toml -- you `use winapi::stuff::winbase` in this function, but are relying on something else turning on that feature.
workingjubilee pushed a commit to tcdi/postgrestd that referenced this pull request Sep 15, 2022
Avoid needless buffer zeroing in `std::sys::windows::fs`

Followup to rust-lang/rust#101171 and rust-lang/rust#101193. This finishes up avoiding buffer zeroing pointed out in rust-lang/rust#100729 (comment) (thanks!)

r? `@ChrisDenton`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
O-windows Operating system: Windows S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

repr(C) is unsound on MSVC targets
6 participants