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

Remove unsound offset_of macro #1485

Merged
merged 6 commits into from
May 13, 2021
Merged

Conversation

Thomasdezeeuw
Copy link
Collaborator

@Thomasdezeeuw Thomasdezeeuw commented Apr 12, 2021

And replace it with constants that define the offsets to the fields.
It's not a pretty solution, but it's one without UB.

Closes #1483.

And replace it with constants that define the offsets to the fields.
It's not a pretty solution, but it's one without UB.
Moving the Overlapped fields to the start to make it easier to determine
the offsets and hopefully incur less breakage once external fields
change size.

Note that the Overlapped fields internally uses miow::Overlapped, which
in turn is a OVERLAPPED struct as found in the winapi crate and has a
stable layout (as defined by the Windows API).
@Thomasdezeeuw
Copy link
Collaborator Author

This should fix #1483 @RalfJung.

@Thomasdezeeuw Thomasdezeeuw marked this pull request as ready for review April 12, 2021 18:29
/// fields.
const CONNECT_OFFSET: usize = 0;
const READ_OFFSET: usize = CONNECT_OFFSET + size_of::<Overlapped>(); // `connect` fields.
const WRITE_OFFSET: usize = READ_OFFSET + size_of::<Overlapped>(); // `read` fields.

Choose a reason for hiding this comment

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

This seems rather fragile...

If I understand correctly, we actually do have an instance of the relevant type available at the place where the offset needs to be computed. So why can't the code simply compute the offsets based on that instance? offset_of! is only hard when you don't have a value of the type you want to compute offsets in.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I agree it's fragile.

But we don't have an instance available in read_done when we need it. We have a pointer to one of the fields of the instance. How do you suggest we get the base pointer (to Inner) then?

Choose a reason for hiding this comment

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

Ah, I thought you'd have an instance anywhere, sorry... I don't really understand the code.^^

Btw, this looks like container_of!-style pointer arithmetic, which does not work well with the Rust aliasing model... rust-lang/unsafe-code-guidelines#243.

But ignoring aliasing issues, if you do not want to depend on addr_of!, you could either decide to not care about code being technically UB (you could still avoid the NULL ptr by using NonNull::dangling as the base) -- or I guess hard-code the offsets as you do...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don't really know of a way to solve this. I'm following rust-lang/unsafe-code-guidelines#243 now so if someone suggests a solution that is not UB we can always update this code.

Changes the Inner::ptr_from_* methods to use ptr::wrapping_sub rather
then casting to usize.
@Thomasdezeeuw
Copy link
Collaborator Author

CI failures: cross compile for Solaris fails; got a pr for it #1487, Minimal Windows versions fail with Cargo not being installed, but other Windows versions pass just fine.. I don't know what is going on there.

rust-lang/rust#82216 removed the
x86_64-sun-solaris target from rustup, changing it to use
x86_64-pc-solaris instead.

Related issues:
 * rust-lang/rust#85098
@Thomasdezeeuw
Copy link
Collaborator Author

Merging #1487 because that CI fails without this change, and this pr fails without #1487.

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.

offset_of is unsound
3 participants