Change:
let err = errno() as libc::c_int; if err == libc::EINTR { continue; <del> } else if err == libc::ENOSYS { </del> <ins> } else if err == libc::ENOSYS || err == libc::EPERM { // Fall back to reading /dev/urandom if `getrandom` is not // supported on the current kernel. // // Also fall back in case it is disabled by something like // seccomp or inside of virtual machines. </ins> GETRANDOM_UNAVAILABLE.store(true, Ordering::Relaxed); return false; } else if err == libc::EAGAIN {

Discussion:
Hi, Rust code panics on linux 3.10: Panic message: Rustc from rustup, version The code is running on Qnap NAS Rust core library which was .
I see there is a check in the code (), but it doesn't seem to work correctly. Backtrace: treats syscall as available if the error is not . I think Qnap kernel violates this rule (there are already some similar bug reports: ).
Is this sufficient to fix it?
I'm trying to reproduce this error with the minimal code. Will get back soon
The problem is that QNAP kernel returns error on syscall. So we need to handle three error codes:
That’s very nonsensical error code usage by QNAP. I can understand (even though it is not exactly a valid code for it to return), but is just outright wrong to ignore or interpret as lack of the syscall as it could easily indicate a bug somewhere in the code.
I totally agree. But Qnap devices exist with all these buggy kernels. The code related to random syscall is in the rust core library, which makes the rust code just impossible to use there. I don't know what is the rust policy regarding the buggy implementations in external systems, but it seems like there should be some way to deal with such situations.
It's also possible to handle this by providing the way to disable syscall completely. E.g.
According to , receiving anything besides EINTR or EAGAIN should fallback to .
According to that page, it seems that PHP people aren’t really sure what should have been done either, other than that QNAP should fix their own stuff. Whatever they implemented is just them giving up on a sensible solution. My ultimate suggestion would be to apply a QNAP specific patch for whatever distribution is used by QNAP during compilation/packaging of their rustc package and use that rustc to compile all the rust code.
It's very common in embedded software to have this type of bugs, which exist for many years without having a chance to fix it someday (including the fact, that some devices' firmware cannot be upgraded at all). If rust targets embedded development, there should always be a clear way on how to deal with it. Rebuilding rustc works, but it's very distracting and unsustainable from the development side.

As of this QNAP bug, I fully agree, that means completely different, and using it in auto-detection is a wrong and harmful way. I would suggest to refactor this code a bit and implement "random backends" with a clear strategy on how to deal with them. The default should be the same - auto-detect. But in addition to that, the developer would have a chance to select which particular random implementation to use (or even provide own?). I can image many cases where it may be useful, besides this horrible QNAP bug.
The statement is true, but is not an embedded target at all! It is a target that targets (heh) a very well specified and understood hosted system (even if that hosted system is implemented in many embedded-like use-cases). Furthermore, “real” embedded targets don’t get to use libstd, which makes dealing with… hosted system idiosyncrasies a problem of no relevance. For the user code this is absolutely a non-problem. exposes no way to generate random data – for that you would use a . Furthermore, the infrastructure to switch out the random number generator used by the hash maps (the only user of randomness in ) is . Given that neither of those seem like a satisfactory solution, there already exists a mechanism to tailor for particularities of certain hosted system. Namely, the , and configuration variables that correspond to the final three parts of a target specification. Since is not really a "well specified and understood Linux" that the is targeting, then perhaps adding a would be an acceptable solution? Bear in mind, that a new target does not necessarily imply that there would be binary artefacts (sysroot and/or librustc itself) for the target, in which case you’d still have to at least build your own sysroot for the target.
Regardless of how we call it (embedded or embedded-like), there are still hundreds of millions of devices, including routers, NASes, IoT hubs, smart speakers, kiosks, IP cameras, etc. running Linux. And vendors typically provide their SDKs, with the modified kernel and *libc, which may work unpredictably sometimes. It sounds like the idea with custom target makes sense. Will try to use for that
On a side note: can be generated by any system call, because the end user can use the seccomp kernel module.

We had the same problem in already.
Python treats the same as : ,
When you'll decide on how to deal with this issue, please also send a patch to .
Nominating this. I propose we follow Python here, the rationale that seccomp can block getrandom seems reasonable to me.
This was discussed recently at a libs triage meeting, and the conclusion was that following python's precedent of handling EPERM as well as ENOSYS makes sense for our usage of