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

Use getentropy from std::random_device, avoiding FS usage of /dev/urandom #12240

Merged
merged 7 commits into from
Sep 17, 2020

Conversation

kripken
Copy link
Member

@kripken kripken commented Sep 16, 2020

This does not change the random number mechanism, it just avoids going through the FS
in order to get random values. getRandomDevice is refactored out of the FS code without
change into a global helper.

By avoiding the FS this is faster, in particular in pthreads builds all FS operations are
proxied, so this PR avoids that overhead.

As a benefit this makes us do the same as WASI, so it removes a difference.

Also make the test for this actually get a random number, and not just set up the device
(that used to open the FD, so the test wasn't useless before).

Fixes #10068.

…ndom. Fixes #10068. This does *not* change the random number mechanism, just it avoids going through the FS
@kripken kripken requested a review from sbc100 September 16, 2020 19:37
getentropy: function(buffer, size) {
if (!_getentropy.randomDevice) {
_getentropy.randomDevice = getRandomDevice();
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would it makes sense to do this memorization in getRandomDevice itself?

Also if you made _getentropy.randomDevice into $randomDevice then you could maybe save a few bytes?

Copy link
Member Author

Choose a reason for hiding this comment

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

I tried a few ways, but it's hard to reduce the code size below what it currently is.

Copy link
Collaborator

Choose a reason for hiding this comment

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

But we not memoize the getRandomDevice inner function? And why not use global for the memoization?

Copy link
Member Author

@kripken kripken Sep 17, 2020

Choose a reason for hiding this comment

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

I see getRandomDevice as getting a random device. It returns a new function each time.

In theory each of those functions could have its own internal DRNG or such (see discussion in #10068).

Callers can memoize when it makes sense. In the FS code we do, and in getentropy it does.

I do agree that if memoizing in getRandomDevice itself were smaller, it would be worth figuring out a proper name for that different API. I can't get it any smaller, though...

@@ -1 +1,2 @@
#include <unistd.h>
#include <random.h> // for getentropy()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this file sys/unistd.h ever actually included by anyone? (As opposed to unistd.h itself which lives elsewhere?)

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh, I meant to add it to compat/unistd.h, so yes, this was the wrong place.

Maybe it doesn't need to be added anywhere? The docs say it should be in unistd, but the usage in libc++ is for random.h. I'll remove this for now, we can add more later I guess.

Copy link
Collaborator

Choose a reason for hiding this comment

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

If it goes anywhere it should probably be in ./system/include/libc/unistd.h I guess?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks like libc++ includes #include <sys/random.h> directly so making it part of unistd.h too is not necessary in this case.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, looks like sys/random is enough.

@@ -0,0 +1,9 @@
#ifdef __cplusplus
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe add a comment about why we are adding this.. how it helps?

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't understand. The __cplusplus pattern? Lots of headers have this, like these siblings in the same dir:

system/include/compat/malloc.h
system/include/compat/netdb.h
system/include/compat/stdarg.h
system/include/compat/stdlib.h
system/include/compat/string.h
system/include/compat/time.h
system/include/compat/xlocale.h

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry no I meant a comment about why this header is added by emscripten when its not part of musl? What is the purpose of adding getransom? I guess that answer is something like "to get ransom bytes without depending on the filesytem stuff which is good for code size and complexity in the generated output" .. or something along those lines :)

Copy link
Member Author

@kripken kripken Sep 17, 2020

Choose a reason for hiding this comment

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

Ok, adding now.

The bigger question is maybe why isn't this in musl, given it seems to be a Linux unistd.h thing..? Looks like musl has added it meanwhile actually, ifduyue/musl@82f1768#diff-2fc78454dd4e341aace02870b1e0c8c9 - but using a syscall, which would adds some unnecessary redirection for us, and it's not where libc++ looks for it (in unistd as opposed to sys/random).

@@ -308,7 +308,7 @@
// random data even when using sandboxing mechanisms such as chroots,
// Capsicum, etc.
# define _LIBCPP_USING_ARC4_RANDOM
#elif defined(__Fuchsia__) || defined(__wasi__)
#elif defined(__Fuchsia__) || defined(__wasi__) || defined(__EMSCRIPTEN__)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Mention in system/lib/libcxx/readme.txt?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good idea, added. Also I added a mention in the changelog.

@kripken kripken merged commit 048f028 into master Sep 17, 2020
@kripken kripken deleted the urandom branch September 17, 2020 23:32
@kripken kripken mentioned this pull request Sep 26, 2020
kleisauke added a commit to kleisauke/rust that referenced this pull request Mar 29, 2023
`getentropy()` is available since Emscripten 2.0.5.

See:
emscripten-core/emscripten#12240
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.

Custom impl of std::random_device?
2 participants