Skip to content

multiboot2: massive refactoring, removed UB, Miri passes all tests #226

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

Merged
merged 17 commits into from
Aug 17, 2024

Conversation

phip1611
Copy link
Member

@phip1611 phip1611 commented Aug 17, 2024

About

This PR contains a massive refactoring of various internals. Now, all
unit tests pass Miri
, thus we removed lots of undefined behaviour and
increased the memory safety! 🎉 Only a small part of these internal refactorings
leak to the public interface. If you don't provide external custom tags, you
should be fine.

Impact of Release

Please note that all previous releases must be considered unsafe, as they
contain UB. However, it is never clear how UB results in immediate incorrect
behaviour and it might work. Nevertheless, users should migrate to the latest
release and they will be fine!

All previous releases on crates.io will be yanked, once this is released.

Code Changes

It was not really possible to split this into smaller commits or smaller PRs. At least not without massive time investment. The main changes are that there are now the internal types GenericTag and TagBytesRef, the refactoring of TagTrait, and that BoxedDst was replaced by new_boxed() which returns a normal Box.

Miri is now 100% happy - This is great success and a big improvement. #160 is entirely closed.

Technical Insights

Memory Properties of this crate:

  • Tags are 8-byte aligned.
  • Rust allocates (on the stack or the heap) not just the true size of a type, but increases the allocation size to the next multiple of the alignment
  • Some tags are modelled as DSTs (terminating [u8] field as this is the best Rusty representation for tags. This needs fat pointers which are complex for itself. A solution is to use the ptr_meta crate
  • Miri wants to track all lifetimes and memory accesses
  • In Rust, we can't cast a small type to a bigger type with Miri being happy

All these things are now solved. This is also done in a nice, non-hacky way.

@phip1611 phip1611 self-assigned this Aug 17, 2024
The goal of this commit is to prepare 100% memory safety (using Miri
passing tests as reference). For that, we need a significant
under-the-hood changes.

`GenericTag` is the generalization of all tags as DST that owns all
memory of the tag. This tag can be created from bytes, thus, we can
ensure a lifetime and a valid memory range. This tag then can be
casted to specific implementations of `TagTrait`. We now never have to
increase or decrease the size of the referenced memory during a Tag
cast, as the GenericTag already holds all bytes that the more specific
type needs.

Assertions and the memory checks along the way ensure that nothing can
co wrong.

Further, the creation of various test data structures was modified to
fulfill the new guarantees, that are given in real-world scenarios and
are also what the compiler expects.
This was already transitively the case as soon as they have a `header: TagHeader`
field, however, for perfection, this can now safely be added.
This will replace the existing BoxedDst typ, which has UB.
Note that Miri runs significantly longer with this change. More memory accesses
that need to be tracked.
Miri still outputs a warning tho: "warning: integer-to-pointer cast"

Nevertheless, no we are UB free!
@phip1611 phip1611 force-pushed the tag-casting branch 2 times, most recently from 7da331e to 545c045 Compare August 17, 2024 10:17
- all public fields -> methods
- Added missing InformationBuilder support for VBEInfoTag
This way, I don't have to increase the MSRV for the next release. I want
as many users as possible to adopt the latest version, so I want to make
it less breaking.
The same changes made in this crate, also needs to be done in multiboot2-header.
@phip1611 phip1611 marked this pull request as ready for review August 17, 2024 12:56
@phip1611 phip1611 merged commit e2c691e into main Aug 17, 2024
28 checks passed
@phip1611 phip1611 deleted the tag-casting branch August 17, 2024 12:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant