japaric/steed

Implement Rust getrandom syscall wrapper

briansmith opened this issue · 15 comments

ring calls libc's syscall(2) from C code to invoke the getrandom syscall. In order to port ring to steed, we need a wrapper around the syscall that we can call from Rust (ideally) or C (less-than-ideally).

You can use the syscall! macro from the sc crate for this:

let code = syscall!(GETRANDOM, something, something);

Sadly, that macro is untyped. I would like to have another crate that exposes typed syscalls but I don't think steed should expose a syscall API.

You can use the syscall! macro from the sc crate for this:

That uses #![feature(asm)] and thus only works on Nightly. I'm hoping to (eventually) use steed with Stable Rust.

I don't think steed should expose a syscall API.

To be clear, I'm not asking for a generic syscall API, just one for getrandom().

I'm hoping to (eventually) use steed with Stable Rust.

That's going to be tough because you need unstable features, and thus nightly, to compile steed and both your crate and steed must be compiled using the same compiler or you'll get compile time errors about metadata mismatch.

That's going to be tough because you need unstable features, and thus nightly, to compile steed

Isn't this something that can be solved with Xargo, by telling it to enable unstable features for steed only when steed is substituted for libstd, probably the same way that Cargo will presumably use for compiling libstd once it is possible to build libstd through Cargo?

Isn't this something that can be solved with Xargo

It can. Still, it's tricky because, to unlock unstable features, you have to extract the key from the rustc binary. Also, that unlocking mechanism is not stable and has already changed once in the last months.

tbu- commented

You can get getrandom from the rand crate on crates.io, use OsRng.

You can get getrandom from the rand crate on crates.io, use OsRng.

ring won't do that. If we wanted to use OsRng we wouldn't do it ourselves. In particular, ring has a mode that guarantees that getrandom() will be used and no other method will be attempted, which cann't be implemented on top of OsRng.

tbu- commented

Forgive me the question, why is that needed? The only case where getrandom is not invoked is where it doesn't exist.

Forgive me the question, why is that needed? The only case where getrandom is not invoked is where it doesn't exist.

My interest in seed is primarily in helping build seccomp-pbf-sandboxed applications. When getrandom() is not available, I want to return a Result::Err instead of reading from /dev/urandom, because reading from /dev/urandom will crash when the needed file I/O operations are blocked by seccomp-pbf. Also, I want to require block-on-uninitialized-random-pool semantics, which only getrandom properly provides.

tbu- commented

Ah, thanks for the explanation.

tbu- commented

@briansmith Maybe that's still something you could ask for in the rand crate: They just need to provide a second constructor for OsRng, one that errors out if getrandom isn't available.

@tbu- Just to be clear, my crate is intended as a complete replacement for the rand crate. If you don't want to implement the getrandom() function in steed, that's understandable. I can implement it in assembly language in ring.

tbu- commented

Sorry, I was just trying to understand the issue. :/

When I originally asked for this, there wasn't an easy way to detect steed vs. non-steed. My understanding is that now I can use #[cfg(target_abi == "steed")] to detect steed is being used, right? If so, then I will just implement the needed stuff in ring on top of the sc crate, just like I'm asking you to do. Then it makes sense to close this with no action. Please reopen if my understanding is wrong.

now I can use #[cfg(target_abi == "steed")] to detect steed

#[cfg(target_env = "steed")] actually. But, yes. You can add steed compatibility to your crate using cfg switches.

on top of the sc crate

I eventually want to make that crate work on stable (japaric/syscall.rs#11) but I don't have much experience with integrating assembly files with Cargo.

I expect that eventually we'll create a linux crate (or perhaps a libr crate) that provides a rustic interface to Linux system calls without going through libc with the goal of making more crates (those that use the libc crate today) work with steed. getrandom would certainly be there.