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 undefined-behavior in nightly Rust #32

Merged
merged 4 commits into from
Apr 20, 2018
Merged

Conversation

gnzlbg
Copy link
Collaborator

@gnzlbg gnzlbg commented Apr 15, 2018

MacOSX uses #pragma pack 4 to pack all of its structs on x86_64 but mach did not.

This resulted in the Rust structs of mach having a different layout than the C structs which is undefined behavior.

This PR fixes this using repr(packed) for nightly Rust builds. It adds a new opt-in feature to the crate called unstable that enables the repr_packed feature and it conditionally applies repr(packed(N)) to all structs with incorrect layout.


Note: the stable Rust build bots currently fail because Rust 1.11.0 is too old: it does not have attribute literals. I've made a similar PR to libc where the exact same thing happened. I'll wait till that is merged and will bump our stable Rust version to continue to match that of libc: rust-lang/libc#972

@gnzlbg gnzlbg requested review from fitzgen and dcuddeback April 15, 2018 13:06
@gnzlbg
Copy link
Collaborator Author

gnzlbg commented Apr 15, 2018

@fitzgen @dcuddeback I am a bit wary of using unstable features in mach, but I've tried to compartmentalize here so that we don't break people using stable Rust.

This allows us to test that repr(packed) does indeed solve mach problems, and to allow those on nightly to use this. Once repr(packed) is stabilized we might want to still keep it behind a feature gate to avoid forcing people to update, and once we unconditionally enable it we can just leave the unstable feature as is but doing nothing to avoid breaking other people's script that might be passing that explicitly.

@gnzlbg
Copy link
Collaborator Author

gnzlbg commented Apr 16, 2018

So @fitzgen @dcuddeback after figuring out the minimum Rust version required for this change (Rust 1.13.0) that does not seem that bad - we currently support Rust 1.11.0 though.

I think this can be merged as is to master, and I would prefer to do a release after that, but I'd rather bump the version to mach 0.2 since there have been a couple of breaking changes on master.

AFAICT all the changes on master have fixed one form or another of undefined behavior (structs that were not repr(C) but should have been, incorrect types on extern C function signatures, etc.), so they could qualify for a new 0.1.x release, but I'd rather not risk breaking anybody and go straight to 0.2.

Thoughts?

@@ -45,7 +45,7 @@ fi

# Runs ctest to verify mach's ABI against the system libraries:
if [[ -z "$NOCTEST" ]]; then
if [[ $TRAVIS_RUST_VERSION == "beta" ]] || [[ $TRAVIS_RUST_VERSION == "nightly" ]]; then
if [[ $TRAVIS_RUST_VERSION == "nightly" ]]; then
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The ctest now only pass on nightly because they require repr(packed) to pass. Before they used to pass on beta as well because we just ignored the undefined behavior on packed structs. I think it is more important for CI to catch these issues unconditionally than to just check beta.

@@ -5,7 +5,7 @@ authors = ["gnzlbg <[email protected]>"]
build = "build.rs"

[dependencies]
mach = { path = ".." }
mach = { path = "..", features = ["unstable"] }
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ctest does not white-list structs with wrong layouts anymore, so without repr(packed) it would fail. This should catch on CI that newer types introduced in the future have at least the proper layout on nightly.

@@ -2,6 +2,7 @@
#![allow(non_upper_case_globals)]

#![cfg_attr(not(feature = "use_std"), no_std)]
#![cfg_attr(feature = "unstable", feature(repr_packed))]
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

packed is opt-in, users compiling with nightly need to explicitly opt-into it, this allows the library to keep working as is on stable Rust.

@fitzgen
Copy link
Owner

fitzgen commented Apr 16, 2018

I think it is fine to go straight to a 0.2 series.

@fitzgen
Copy link
Owner

fitzgen commented Apr 16, 2018

I thought that stable repr(packed) was riding the release trains now -- I guess that isn't the case?

@gnzlbg
Copy link
Collaborator Author

gnzlbg commented Apr 16, 2018

Ok! repr(packed) is stable since 1.0, but repr(packed(N)) is not :/

@gnzlbg gnzlbg merged commit 8ea95a0 into fitzgen:master Apr 20, 2018
@gnzlbg
Copy link
Collaborator Author

gnzlbg commented Apr 20, 2018

So rust-lang/libc#972 was merged in libc, bumping the minimum supported libc Rust version to 1.13.0 as well. This PR does the same, syncing mach with libc.

I've added a new commit bumping the crate version to 0.2, and just published it.

@fitzgen
Copy link
Owner

fitzgen commented Apr 20, 2018

Sounds good!

@fitzgen
Copy link
Owner

fitzgen commented Apr 20, 2018

Probably want to update the table in the README with the new rust version too.

@gnzlbg
Copy link
Collaborator Author

gnzlbg commented Apr 23, 2018

@fitzgen done #33

delta4chat pushed a commit to delta4chat/mach that referenced this pull request Feb 25, 2024
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.

2 participants