You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Potential improvements to use of /dev/random on Linux/Android #451
1. The man page says that Linux returns ENOMEM and never EAGAIN. Since this code is Linux-specific, should we remove the EAGAIN case in the poll loop? Should we replace it with an ENOMEM case?
2. The man page directs the user to note that poll may return "spurious readiness notifications" where poll indicates the file is readable when it actually isn't. Especially in the case of pre-getrandom-syscall-capable Linux versions, are such spurious readiness notifications possible? If so, this would be counter to the goal of polling but not reading /dev/random.
4. The above PRs mention a few syscalls that poll() may be mapped to. ppoll_time64 is available from Linux 5.1+. Thus, people may need to update their seccomp filters to work on Linux 5.1. In any case, if we're going to document seccomp compatibliity anywhere then we should mention this in that documentation. [Edit: Addressed in PR Linux/Android: Document /dev/random polling considerations. #452].
5. https://doc.libsodium.org/usage#sodium_init-stalling-on-linux notes that even on pretty new Linux kernels, in certain environments that seems actually increasingly important, blocking on /dev/random becoming readable will stall an application. We might want to provide similar guidance.
It seems like they also have methods in there for read, open, and close. I'm wondering if sanitizers being enabled just requires using a libc that has been modified to make those particular calls
I don't think we should spend too much effort on the fallback path trying to handle every possible edge case. This path is quite rare in practice and becomes even rarer with every passing day. The current code works fine and we do not have any complains from users.
The man page says that Linux returns ENOMEM and never EAGAIN. Since this code is Linux-specific, should we remove the EAGAIN case in the poll loop? Should we replace it with an ENOMEM case?
Removal of the EAGAIN check sounds reasonable. I am not sure we can reasonably handle ENOMEM, so we probably should just return it.
The man page directs the user to note that poll may return "spurious readiness notifications" where poll indicates the file is readable when it actually isn't.
IIUC it mostly happens with network devices. The select(2) man page (to which poll docs refer) states the following:
This could for example happen when data has arrived but upon examination has the wrong checksum and is discarded.
There is also a caveat about "other circumstances", but I couldn't find anything that applies to "virtual" files like /dev/random. We could replace the polling code with one byte read, but I think we can just ignore "spurious readiness" in our case. Especially considering that other libraries apparently do the same.
https://doc.libsodium.org/usage#sodium_init-stalling-on-linux notes that even on pretty new Linux kernels, in certain environments that seems actually increasingly important, blocking on /dev/random becoming readable will stall an application. We might want to provide similar guidance.
I think this is already sufficiently addressed in the "early boot" section.
When sanitizers are enabled, it seems like we should be calling __sanitizer_syscall_pre_impl_poll and __sanitizer_syscall_post_impl_poll?
I think we should just move responsibility for this to libc.
Activity
briansmith commentedon Jun 3, 2024
/dev/randominstead of polling it. #449 and PR Linux/Android: Improve sandbox compatibility when checking/dev/random. #450 both attempt to preventgetrandomfrom failing in the case where a sandbox blockspoll().pollreturnsENOSYSunikraft/lib-musl#58 describes such a case. Interestingly, they note thatlibstdinternally usespollin some situations. The libstd code is especially interesting because it bails out to a fallback path onEINVAL,EAGAIN, orENOMEMinstead of retrying. https://github.com/rust-lang/rust/blob/master/library/std/src/sys/pal/unix/mod.rs#L101-L113 shows this, updated to address theUnikraftissue.briansmith commentedon Jun 3, 2024
poll()may be mapped to.ppoll_time64is available from Linux 5.1+. Thus, people may need to update their seccomp filters to work on Linux 5.1. In any case, if we're going to document seccomp compatibliity anywhere then we should mention this in that documentation. [Edit: Addressed in PR Linux/Android: Document /dev/random polling considerations. #452].briansmith commentedon Jun 3, 2024
/dev/randombecoming readable will stall an application. We might want to provide similar guidance.briansmith commentedon Jun 4, 2024
__sanitizer_syscall_pre_impl_polland__sanitizer_syscall_post_impl_poll?josephlr commentedon Jun 4, 2024
It seems like they also have methods in there for
read,open, andclose. I'm wondering if sanitizers being enabled just requires using alibcthat has been modified to make those particular callsnewpavlov commentedon Oct 16, 2024
I don't think we should spend too much effort on the fallback path trying to handle every possible edge case. This path is quite rare in practice and becomes even rarer with every passing day. The current code works fine and we do not have any complains from users.
Removal of the EAGAIN check sounds reasonable. I am not sure we can reasonably handle ENOMEM, so we probably should just return it.
IIUC it mostly happens with network devices. The
select(2)man page (to whichpolldocs refer) states the following:There is also a caveat about "other circumstances", but I couldn't find anything that applies to "virtual" files like
/dev/random. We could replace the polling code with one byte read, but I think we can just ignore "spurious readiness" in our case. Especially considering that other libraries apparently do the same.I think this is already sufficiently addressed in the "early boot" section.
I think we should just move responsibility for this to
libc.