Fix alignment issues in file info types#377
Merged
GabrielMajeri merged 3 commits intoMar 2, 2022
Merged
Conversation
Collaborator
|
Nice! Would be nice if we can also run Miri more regularly in the future. Based on the changes, I'm guessing this PR now completely fixes #80? |
Member
Author
Add `offset_up_to_alignment`, `round_up_to_alignment`, and `align_buf`.
The `FileSystemInfo` was accidentally different from the intended C representation of the type due to extra alignment padding inserted after the `FileSystemInfoHeader` struct. This wasn't noticeable when constructing with `FileSystemInfo::new`, so the existing unit test didn't catch it. However, when constructing with `FileSystemInfo::from_uefi`, the volume label info would go in the wrong place so the beginning of the name would be cut off. To fix this, merge all the `Header` types into their parent types. Replace the `NamedFileProtocolInfo` abstraction with an `InfoInternal` trait that allows each info type to specify the offset to the name field at the end of the struct. Also fixed the size checks for constructing file info types with a storage buffer so that they take alignment padding into account. For example, `FileInfo`'s alignment is 8, so the total size of the struct will be a multiple of 8 and the storage buffer needs to have room for that. The alignment and name field offset values are currently hardcoded for each struct. This isn't ideal, but it's not easy to avoid in a zero-cost way without running afoul of safety rules. It is straightforward to validate the hardcoded values once a type is constructed though, so the unit tests now do that (see `validate_layout`). Initializing of header fields is now done with `ptr::addr_of_mut` in a closure. Since the buffer is currently an initialized slice (i.e. not `MaybeUninit`), and the header fields are almost all numeric types where any bit pattern is valid this is really a bit overzealous, but is specifically neded for the `read_only` field since only two values are valid for `bool`. And it will make it simpler in the future if we switch the storage buffer to use `MaybeUninit` to avoid double initialization. One more alignment improvement: if the storage buffer is not aligned, an aligned sub-slice is used (if possible). The docstring for `FileInfoCreationError::InsufficientStorage` already implied this happened, now it actually does. With this fix it's possible to run the file-info tests under Miri for some added confidence in the correctness of all the unsafe code. rust-osdev#80
This test should catch the issue described in rust-osdev#80
7a57f63 to
bb0cc81
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This fixes a couple alignment bugs with the info types:
The
FileSystemInfowas accidentally different from the intended C representation of the type due to extra alignment padding as described in #80. Fixing that required fairly invasive changes to the file info types, but I think everything is now aligned correctly and has no UB.Additionally the storage size check didn't take trailing alignment padding into account, now it does.
One more alignment improvement: if the storage buffer is not aligned, an aligned sub-slice is used (if possible). With that fix in place it's possible run the tests under Miri for some added confidence in the correctness of all the unsafe code.
More details in the commit messages.