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

Make compatible as submodule to libstd #119

Closed
wants to merge 14 commits into from

Conversation

faern
Copy link
Collaborator

@faern faern commented Feb 14, 2019

Preparing to include this repository as a git submodule under libstd over at rust-lang/rust#56410

This is work in progress. Would like feedback, plus get confirmation from the CI that it works everywhere.

@faern faern marked this pull request as ready for review February 14, 2019 20:24
Copy link
Owner

@Amanieu Amanieu left a comment

Choose a reason for hiding this comment

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

Overall this looks OK, but I would like to see the actual libstd integration code for a proper review.

core/build.rs Outdated Show resolved Hide resolved
lock_api/src/lib.rs Outdated Show resolved Hide resolved
@faern faern force-pushed the as-libstd-submodule branch 5 times, most recently from 75d184b to 8f4860d Compare February 21, 2019 22:16
@faern faern mentioned this pull request Mar 4, 2019
@faern faern force-pushed the as-libstd-submodule branch 6 times, most recently from ab001c5 to 21a842c Compare March 6, 2019 20:06
@faern faern mentioned this pull request Mar 20, 2019
@faern faern force-pushed the as-libstd-submodule branch 2 times, most recently from 236e043 to 3a9b689 Compare April 1, 2019 12:52
@jethrogb
Copy link

jethrogb commented Apr 1, 2019

In SGX, invalid return values can happen and you must check for them. Specifically in the case of synchronization primitives, you must not unwind on an error, see rust-lang/rust#59614. Therefore, you should apply something like the following:

diff --git a/core/src/thread_parker/sgx.rs b/core/src/thread_parker/sgx.rs
index ed511ce..e323801 100644
--- a/core/src/thread_parker/sgx.rs
+++ b/core/src/thread_parker/sgx.rs
@@ -19,6 +19,9 @@ use super::libstd::{
 };
 use core::sync::atomic::{AtomicBool, Ordering};
 
+#[cfg(not(feature = "i-am-libstd"))]
+use std::panic as rtabort;
+
 // Helper type for putting a thread to sleep until some other thread wakes it up
 pub struct ThreadParker {
     parked: AtomicBool,
@@ -55,7 +58,10 @@ impl ThreadParker {
     pub fn park(&self) {
         while self.parked.load(Ordering::Acquire) {
             let result = usercalls::wait(EV_UNPARK, WAIT_INDEFINITE);
-            debug_assert_eq!(result.expect("wait returned error") & EV_UNPARK, EV_UNPARK);
+            match result.map(|eventset| eventset & EV_UNPARK) {
+                Ok(EV_UNPARK) => {}
+                _ => rtabort!("usercall wait returned an invalid value"),
+            }
         }
     }
 
@@ -65,7 +71,7 @@ impl ThreadParker {
     #[inline]
     pub fn park_until(&self, _timeout: Instant) -> bool {
         // FIXME: https://github.com/fortanix/rust-sgx/issues/31
-        panic!("timeout not supported in SGX");
+        rtabort!("timeout not supported in SGX");
     }
 
     // Locks the parker to prevent the target thread from exiting. This is
@@ -90,13 +96,11 @@ impl UnparkHandle {
     #[inline]
     pub fn unpark(self) {
         let result = usercalls::send(EV_UNPARK, Some(self.0));
-        if cfg!(debug_assertions) {
-            if let Err(error) = result {
-                // `InvalidInput` may be returned if the thread we send to has
-                // already been unparked and exited.
-                if error.kind() != io::ErrorKind::InvalidInput {
-                    panic!("send returned an unexpected error: {:?}", error);
-                }
+        if let Err(error) = result {
+            // `InvalidInput` may be returned if the thread we send to has
+            // already been unparked and exited.
+            if error.kind() != io::ErrorKind::InvalidInput {
+                rtabort!("send returned an unexpected error: {:?}", error);
             }
         }
     }

@faern
Copy link
Collaborator Author

faern commented Apr 1, 2019

@jethrogb parking_lot does not handle very well to crash in the parking code. Which is why all assertions in all ThreadParker implementations are just debug_asserts. So, we already don't unwind on errors, we just ignore them. What is the reason SGX can't tolerate this? Can you explain what bad things can happen with the current implementation?

@jethrogb
Copy link

jethrogb commented Apr 1, 2019

SGX is an security isolation mechanism for running code on untrusted systems. Therefore, the program must detect when the system is trying to manipulate it into an invalid state. If any manipulation is detected, the program must abort and most definitely not try to continue normally. You can read more about these types of attacks in the Iago attacks paper.

The error checks in the thread_parker implementation are different from the checks elsewhere in the code in that they detect a misbehaving system as opposed to a bug in the parking_lot code.

@faern
Copy link
Collaborator Author

faern commented Apr 2, 2019

@jethrogb Could you evaluate my attempt to implement what you suggested over in the testing branch: https://github.com/faern/parking_lot/blob/as-libstd-submodule-test/core/src/thread_parker/sgx.rs#L23-L30 ?

I applied something very similar to your patch. But I used std::process::abort when not running as part of libstd instead of panicking. std::process::abort and the rtabort! macro end up calling the very same abort implementation, but rtabort! prints the message first.

Not sure it's a good idea to try to unwind or print anything when running outside libstd. Both unwinding and printing to stderr involves locking locks in the background. I suspect doing so if the parking impl is in an inconsistent state might either deadlock or double-panic.

@jethrogb
Copy link

jethrogb commented Apr 2, 2019

LGTM. But note that panic never locks stderr for printing. I agree that unwinding doesn't work well right now but IMO that should just be fixed in the implementation.

core/src/parking_lot.rs Outdated Show resolved Hide resolved
@Amanieu Amanieu mentioned this pull request Apr 7, 2019
@faern faern force-pushed the as-libstd-submodule branch 2 times, most recently from 39f3917 to c1569fd Compare April 7, 2019 19:32
bors bot added a commit that referenced this pull request Apr 13, 2019
133: Add version detection for stabilized atomics and checked_add r=Amanieu a=faern

Automatically detecting Rust >= 1.34 and make good use of the now stable `AtomicU{8,32}` types as well as `Instant::checked_add`.

This has been broken out from #119 since that PR is a bit large and this commit is not really related to the crate being used in libstd. We don't really know when the libstd stuff will be merged anyway, and this could be immediately useful to anyone using `parking_lot` on the latest stable Rust.

I'm just generally against "let's just put this in the already open PR, it'll be fine". I find it usually creates more problems than it solves.

Co-authored-by: Linus Färnstrand <faern@faern.net>
@faern faern force-pushed the as-libstd-submodule branch 2 times, most recently from 9ac9a6e to c88b2c2 Compare April 18, 2019 09:13
@dekellum
Copy link
Contributor

Is there any newer version of this work, or any chance this one could be revived? Or perhaps I just need some helpful advise. I imagine this PR includes making the parking_lot types (like Mutex and Condvar) API compatible with libstd 1.x. Tokio might like to have a non-default feature that uses these types instead of the libstd ones. If it was API compatible, that would be a lot easier!

@Amanieu
Copy link
Owner

Amanieu commented Jan 17, 2020

There are no plans to make parking_lot fully API-compatible with libstd. This PR does not do this.

The plan for libstd integration is for the libstd types to become wrappers around RawMutex, etc. But this all happens in libstd, not parking_lot.

@dekellum
Copy link
Contributor

dekellum commented Jan 17, 2020

Are there libstd PR's for that I could look at? Thanks for your work in any case! I definitely have found it faster than libstd, for example in the blocking-permit crate I'm working on.

@Amanieu
Copy link
Owner

Amanieu commented Jan 17, 2020

You can have a look at rust-lang/rust#56410 but I don't think it will help you much.

@Amanieu
Copy link
Owner

Amanieu commented Nov 22, 2023

Closing since this is not going to happen.

@Amanieu Amanieu closed this Nov 22, 2023
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.

4 participants