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

systemd reads from urandom before initialization #4167

Closed
falconindy opened this Issue Sep 16, 2016 · 34 comments

Comments

@falconindy
Copy link
Contributor

falconindy commented Sep 16, 2016

Submission type

  • Bug report
  • Request for enhancement (RFE)

systemd version the issue has been seen with

v231

Used distribution

Arch Linux

In case of bug report: Unexpected behaviour you saw

On bootup, the kernel reports:

Sep 10 13:44:57 localhost kernel: random: systemd: uninitialized urandom read (16 bytes read, 3 bits of entropy available)
Sep 10 13:44:57 localhost kernel: random: systemd: uninitialized urandom read (16 bytes read, 3 bits of entropy available)
Sep 10 13:44:57 localhost kernel: random: systemd: uninitialized urandom read (16 bytes read, 3 bits of entropy available)
Sep 10 13:44:57 localhost kernel: random: systemd: uninitialized urandom read (16 bytes read, 3 bits of entropy available)
Sep 10 13:44:57 localhost kernel: random: systemd: uninitialized urandom read (16 bytes read, 3 bits of entropy available)
Sep 10 13:44:57 localhost kernel: random: systemd: uninitialized urandom read (16 bytes read, 3 bits of entropy available)
Sep 10 13:44:57 localhost kernel: random: systemd: uninitialized urandom read (16 bytes read, 3 bits of entropy available)

In some cases, this appears for more than just systemd but also systemd-udevd, systemd-tmpfiles, and maybe others.

ref: https://bugs.archlinux.org/task/50798

@michich

This comment has been minimized.

Copy link
Contributor

michich commented Sep 16, 2016

It must be the randomness we use for hashmaps.
What can we do about it? Should we just use rand() for a few seconds and then rehash when enough randomness is available? I don't know.

@keszybz

This comment has been minimized.

Copy link
Member

keszybz commented Sep 16, 2016

I don't think there's anything wrong in what we're doing. In dev_urandom we're calling getrandom(p, n, GRND_NONBLOCK) and if that fails reading some bytes from /dev/urandom. /dev/urandom is supposed to generate some bytes on a best-effort basis, afaiu. Rather than complicate our codebase with iffy fixes I think we can wait for latent entropy plugin to be merged into the kernel.

@poettering

This comment has been minimized.

Copy link
Member

poettering commented Sep 18, 2016

The entropy used for the hash tables may be low quality. In fact we could even start with a fixed entropy value of 0 for all hash table, and it wouldn't hurt. This is because we pick a new random value for each hashtable when we resize it. The only reason we use a random value at all is to make sure that an attacker cannot trick us into allocating huge hash tables with large numbers of collisions. Since we pick a new seed value on each resize doing so will necessarily take benefit of better entropy as the hash table grows.

Closing this hence. I don't think systemd is doing anything wrong here, and we really shouldn't change anything.

@poettering poettering closed this Sep 18, 2016

@noloader

This comment has been minimized.

Copy link

noloader commented Mar 11, 2017

@randomice42

This comment has been minimized.

Copy link

randomice42 commented Apr 5, 2017

Hi,
can this be reopened?
The problem is that shortly after it was opened, the kernel limited the warnings to 10.[1]

This makes it an issue for all systemd users, because you cannot see if there are other services starting from an uninitialized /dev/urandom anymore. Apart from the own system's insecurity, this in turn also makes it difficult to troubleshoot and file bug reports against those services, which don't use get getrandom(2) call. And we all know this is still a tough enough problem to tackle.[2]
The init system should assist not make it harder, particularly if it uses /dev/urandom unnecessarily as written above.

Question: Is it not possible to require the systemd-random-seed.service finished it's job first?

[1] https://patchwork.kernel.org/patch/9173499/
[2] https://factorable.net/weakkeys12.extended.pdf

@poettering

This comment has been minimized.

Copy link
Member

poettering commented Apr 5, 2017

@randomice42 there's nothing "insecure" in systemd's use of the random pool for our hash table implementation. It's fine if the random numbers we need are initially crappy: as soon as somebody manages to exploit this, and thus manages to trigger hash collisions we'll pick a new one. And if that one is crappy, that's fine too, as long as we'll pick another one as we get too many collisions and so on, until the random numbers aren't crappy anymore.

We really don't want to delay boot just to make kernel log messages go away (or even reapper, as you suggests). It's a good thing if systemd boots fast, not a bad thing.

Question: Is it not possible to require the systemd-random-seed.service finished it's job first?

That's a service activated pretty late (specifically after /var has been made writable, and hence has shown up, was fscked, and so on), but we already need random numbers in PID 1 during earliest boot.

@noloader

This comment has been minimized.

Copy link

noloader commented Apr 7, 2017

@poettering,

This issue seems to be unique to systemd given how early it starts and the requirements for random numbers. If systemd did not start early, then it seems this would not be an issue.

One of unintended the side effects of attempting to obtain random number when they are not needed is it depletes the pool at a critical time. Boot time is a critical time, and the kernel is gathering entropy to get the generators in good working order.

If its true that systemd does not need good random numbers, then systemd should not reach into the pool at such an early time. Instead, use another method like (1) deferring the request for random numbers; or (2) maintaining a seed file and reading it instead of using one of the kernel generators.

Related, this is from an off-line conversation concerning this issue:

I have analyzed what systemd really does with the data from /dev/urandom. See
[1] for the explanation. All of the purposes are non-cryptographic in nature
and do not need high-entropic data. That said, I am not following Lennard
Poettering's last sentence on the github bug you mentioned, because early boot
entropy is precious and systemd actually harms entropy (see http://
www.chronox.de/lrng/doc/lrng.html section 2.1.3 for an idea of the issue that
is present because /dev/urandom is forced to provide random data without being
initialized).

...
[1] https://lkml.org/lkml/2016/10/23/83

@poettering

This comment has been minimized.

Copy link
Member

poettering commented Apr 7, 2017

One of unintended the side effects of attempting to obtain random number when they are not needed is it depletes the pool at a critical time. Boot time is a critical time, and the kernel is gathering entropy to get the generators in good working order.

Well, Linux doesn't really have an API for "get me a random number as good as you can without blocking, and don't negatively affect the pool"... If there was we'd be happy to use it. Hence we use the next best thing: /dev/urandom, which will get us what we need, even though it might negatively affect the pool.

@poettering

This comment has been minimized.

Copy link
Member

poettering commented Apr 7, 2017

(1) deferring the request for random numbers; or (2) maintaining a seed file and reading it instead of using one of the kernel generators.

Seed files cannot work, we cannot assume to have writable file systems that early (or even read access to what might be writable later).

@randomice42

This comment has been minimized.

Copy link

randomice42 commented Apr 10, 2017

Thanks. For the answer on the seed file: too bad that's no quick wayout.

We really don't want to delay boot just to make kernel log messages go away (or even reapper, as you suggests). It's a good thing if systemd boots fast, not a bad thing.

No doubt, I still remember the "oh, nice" on boot speed when Arch switched to systemd and so many improvements were implemented since.

However, system entropy is a paramount critical knob for initializing some services safely. I did not comment to delay any boot, but because I feel stumbed how to troubleshoot such service startups, looking for the safe&sane option to start them.

Simple case: a system provides a single entropy starving service.

Now, how to to be sure it has sufficient entropy: At current I only see the option to hack it clumsily. For example, require a custom one which listens for "random: crng init done" kernel messages before the actual service is started.

On the notebook I write this on, the latter means a 10+ seconds delay for said service startup. Beg your pardon, but to me and all users of the case system that is the relevant boot time - and it does not matter.

Open questions to me:

  • What would be the crng init delay, if systemd- units boot "kernel entropy neutral"?
  • Does anyone have a neat work-around to enable said services safely?

I appreciate you taking time.

@keszybz

This comment has been minimized.

Copy link
Member

keszybz commented Apr 10, 2017

I guess we could start with the 0 as the hash table seed. It shouldn't really matter, since there isn't any "attacker" during early boot. And as we resize, we could use a proper seed. This might make the warning go away, not sure exactly how early we resize tables.

A side note: based on the log in the the first comment, we seem to read at least 16×7=112 bytes, which seems a lot. I can imagine this could significantly deplete the pool on an embedded or headless device.

@randomice42

This comment has been minimized.

Copy link

randomice42 commented Apr 11, 2017

To @keszybz side note: the log in the first post is likely truncated. On the standard notebook here it is 16x10, and since the kernel limits warnings to 10 it might be more. See for yourself easily with "dmesg |grep -e random:"

@poettering

This comment has been minimized.

Copy link
Member

poettering commented Apr 17, 2017

I guess we could start with the 0 as the hash table seed. It shouldn't really matter, since there isn't any "attacker" during early boot. And as we resize, we could use a proper seed. This might make the warning go away, not sure exactly how early we resize tables.

I'm not convinced that would be really the best option.

What we could do is share the seed process-wide: store it in a global static variable each time we pick a new one, and start new hash tables with that instead of a fresh one each time. This would not make the initial request go away, but it would reduce the overall amount of syscalls we'd issue, as we'd only ask for new randomness once in the beginning and when we resize any hash table.

This wouldn't make the log message go away (and I think making misguided log messages in other software go away isn't our business), but it would reduce it's frequency a lot.

@kroeckx

This comment has been minimized.

Copy link

kroeckx commented Jun 24, 2017

From what I understand, the problem is that your hash table can't deal with duplicates entries and that on collision you try new random numbers until there is no collision anymore. So does that mean that during a normal boot you actually have to rehash everything 10 times or more?

Could you consider using a hash algorithm that can deal with duplicate entries instead?

@kroeckx

This comment has been minimized.

Copy link

kroeckx commented Jun 24, 2017

An other option is that you use an RNG that does not make use of getrandom() or /dev/urandom, but something you just seed with the current time and then extract numbers from. I think rand()/srand() do that.

@poettering

This comment has been minimized.

Copy link
Member

poettering commented Jun 25, 2017

From what I understand, the problem is that your hash table can't deal with duplicates entries and that on collision you try new random numbers until there is no collision anymore. So does that mean that during a normal boot you actually have to rehash everything 10 times or more?

No, this is not the problem. The hash table can deal with collisions just fine. Like for every hash table if you manage to create too many collisions the access complexity deteriorates though from the intended O(1) towards O(n). We use a keyed hash function for hashing though and the key for that is created randomly, in order to thwart attacks that want to take benefit of that: unless you know the key its very hard to create many collisions. On top of that we swap out the key of the keyed hash function whenever we need to rehash due to the hash table growing too large. That has the effect that even if you manage to figureout the key somehow and can create a ton of collisions at soon as you added enough entries the key is changed again and you need to start from the beginning.

Now for this kind of stuff we are fine with low quality entropy in the beginning as long as it gets better with time, so that the key gets harder to guess the longer you try to exploit hash collisions. And /dev/urandom provides hence the exact right semantics to us.

@poettering

This comment has been minimized.

Copy link
Member

poettering commented Jun 25, 2017

An other option is that you use an RNG that does not make use of getrandom() or /dev/urandom, but something you just seed with the current time and then extract numbers from. I think rand()/srand() do that.

Yeah, we can use a lot of stuff. But we can also /dev/urandom, which provides us with the exact right kind of entropy we want.

@kroeckx

This comment has been minimized.

Copy link

kroeckx commented Jun 25, 2017

@poettering

This comment has been minimized.

Copy link
Member

poettering commented Jun 25, 2017

I have no idea what what the hash table is used for or how systemd can be attacked, and what you're trying to protect against.

We use this hash table implementation heavily and pretty much everywhere in the systemd code base. Units are stored in hash tables, and each dependency type in each unit is a hash table. Hence we use it for pretty much everything pretty much everywhere in our codebase.

Any hash table implementation that is not keyed by a random key is vulnerable to attacks like these:
https://arstechnica.com/business/2011/12/huge-portions-of-web-vulnerable-to-hashing-denial-of-service-attack/

It's pretty common knowledge these days that if you do hash tables you need to key them.

And yeah, remote clients can create entries in our hash tables, already due to per-connection socket activation.

@poettering

This comment has been minimized.

Copy link
Member

poettering commented Jun 25, 2017

From what I understand, you want to detect an attack and then change the key, and you want that key to be unlikely to guess in that case.

We don't really detect any attack, we don't bother with that. We just change the key when we resize and rehash, because it's cheap and makes this threat go away easily.

My problem with your solution to use /dev/urandom is that it's used as an excuse not to fix /dev/urandom.

Hmm? "fix /dev/urandom"? What's there to fix? If your program wants guarantees about entropy then it shouldn't use /dev/urandom, that's pretty well known knowledge, and there are alternative APIs around for that case.

If you want to redefine /dev/urandom to be something else than it has always been you break API, and that's not really how things are done on the kernel.

I mean, if you can offer me an alternative API that does what I want nicely (i.e. give me some random data in a "best effort" kind of way), then I am happy to migrate to it, I really don't care if the API is called /dev/urandom or something else, but as long as that doesn't exist, migrating away from the current mode which does exactly what we want makes very little sense, in particular if you do all this to break the kernel's userspace-facing API massively...

But anyway, I am pretty sure our usecase is valid, and the API we use is the only one available that does exactly what we need. Please work with the kernel people to add a suitable alternative API before telling us to not use it anymore. Thank you for your understanding.

@kroeckx

This comment has been minimized.

Copy link

kroeckx commented Jun 25, 2017

@poettering

This comment has been minimized.

Copy link
Member

poettering commented Jun 25, 2017

So you're saying that you want a cryptographic secure random number, but if there isn't one you're happy that it's not. Which is why you fall back from getrandom() to using /dev/urandom. You could instead fall back to something like rand() if getrandom() is supported but returns EAGAIN.

Well, it's not a binary thing really. It's: "Give me the best you have. If it is cryptographic quality, that's excellent. If it is not quite there yet, give me what you have I am happy with that too for now, as long as it eventually gets better."

But I suggest you also try to initialize /dev/urandom before you try to read from it, which would be as soon as /var is writeable.

/var becomes accessible very late during the boot process, long after PID 1 initialized and created and populated all its hash tables. Yes, systemd initializes /dev/urandom from entropy gathered on a previous boot, but we use the keys for our hash tables really early on.

@keszybz

This comment has been minimized.

Copy link
Member

keszybz commented Jun 25, 2017

I see one reason why we might want current implementation: even though we are using /dev/urandom, we are still pulling quite a few bits of randomness out of the pool this way. For systemd itself this is not a problem, because it doesn't really need good randomness, especially when initially allocating hash tables, but it could have a deleterious effect on other processes which actually do need strong random numbers. For example an embedded device which needs to generate some ssh keys during boot could be significantly delayed by our initial request for a 100-200 bytes. So after thinking this over, I think that although using the kernel APIs as documented, from the POV of the whole system it might be better to frugal.

@keszybz keszybz reopened this Jun 25, 2017

keszybz added a commit to keszybz/systemd that referenced this issue Jun 25, 2017

basic/random-util: do not fall back to /dev/urandom if getrandom() re…
…turns short

During early boot, we'd call getrandom(), and immediately fall back to
reading from /dev/urandom unless we got the full requested number of bytes.
Those two sources are the same, so the most likely result is /dev/urandom
producing some pseudorandom numbers for us, complaining widely on the way.

Let's change our behaviour to be more conservative:
- if the numbers are only used to initialize a hash table, a short read
  is OK, we don't really care if we get the first part of the seed and then
  some zeros. So just return "success" in that case.
- if getrandom() returns -EAGAIN, fall back to rand() instead of querying
  /dev/urandom again.
  The idea with those two changes is to avoid hammering the random number
  pool if it is empty or nearly empty.
- only in the cases where we really need to make the best effort possible
  (sd_id128_randomize and firstboot password hashing), fall back to
  /dev/urandom.

sd_id128_randomize is a special case — for our internal uses we'd be fine to
fall back to rand(), but when provided as a function in sd_id128.so, we don't
know whether srand() was called properly, and how rand() is used otherwise, so
we cannot fall back to rand(). In that case using /dev/urandom is the only
reasonable fallback.

When falling back to /dev/urandom, don't lose the short read we already got,
and just read the remaining bytes.

When calling getrandom(), drop the checks whether the argument fits in an int —
getrandom() should do that for us already, and we call it with small arguments
only anyway.

If getrandom() syscall is not available, we fall back to /dev/urandom same
as before.

Fixes systemd#4167.
@noloader

This comment has been minimized.

Copy link

noloader commented Jun 27, 2017

Thanks for this commit, @keszybz.

Would systemd consider another request that could dramatically improve the security posture on many Linux systems? Its an opportunistic security measure that leverages systemd's unique role in the order of things. I can make it a separate request if it sounds like something worth entertaining.

The request is, for processors that provide a CPU instruction to produce random numbers, allow systemd collect initial entropy and add it to /dev/{u}random.

I think this strategy has quite a few upsides with little downside. There are two big upsides. First, drivers which follow systemd and don't wait for /dev/{u}random to become operational will actually have entropy to use.

Second, drivers won't deplete the entropy pool at a critical time because the generators are already well seeded. That's a huge win over the current situation, and it greatly reduces risk in threat models which account for it.

A third, smaller upside is, you don't need a driver to do it because its a native CPU instruction. systemd can use GCC inline assembly and not even bother with *.s files.

A fourth, smaller upside is, adopting the strategy will be compatible with anything the kernel does if the kernel chooses to try and improve things. systemd will not need to change code based on kernel changes. To date, the kernel's strategy has been "don't ask, don't tell", so its not clear they will be moving anytime in the future.

There are two downsides, but they don't increase the risk. First, some people are suspect of instructions like rdrand and rdseed. However, using a hypothetically backdoor that appear to be a random stream to most attackers is still better that using nothing at all.

Second, not all platforms have a dedicated CPU instruction, so systemd cannot apply the strategy on all platforms. However, in this case, the risk remains the same as before, so there is no increase in risk.

There are some slightly more complicated corner cases that are not accounted for, but they don't require drivers either. For example, a MIPS Creator ci20 has a JZ4780 with a RNG, and its value read through an I/O address. Also see ERNG and RNG cgu registers on the ci20 mailing list (the kernel added a driver with similar function for the JZ4780).

As I understand it, swapper or process 0 sets up CPU capabilities. systemd should have the information it needs to determine when it can execute the strategy in most cases.

The kernel may be able to adopt a similar strategy, but they best I can tell, they are less agile and it may take more effort to get it into mainline. Given Torvalds' feeling that closing gaps like these are sometimes labeled "insane", it could reduce to a political (not technical) problem, and there may be little interest in addressing the gaps. Buts its easy enough for systemd to fix without much fuss.

Its worth mentioning that I am not asking to re-architect the kernel driver model around this. The kernel can keep doing what it has always done. In fact, the kernel's current practice should help ally fears about potential backdoors tainting a pool. Mixing-in additional entropy will remove hypothetical advantages an attacker may posses from the use of instructions like rdrand and rdseed.

I believe the request falls under the purview of systemd, and the project has authority to make the changes since its partially responsible for execution environments. From Rethinking PID 1:

... A good babysitter should not only oversee and control when a daemon starts, ends or crashes, but also set up a good, minimal, and secure working environment for it.

Finally, its also worth mentioning the kernel is enhancing logging in this area. In the future there will likely be more dmesg entries about drivers using /dev/{u}random before the random devices are operational. If I am parsing things correctly, at least one message will be printed for each driver that uses /dev/{u}random before its ready. Also see random: silence compiler warnings and fix race on the kernel crypto mailing list.

Sorry about wandering off-topic in this issue. It seemed like a good time to bring it up given folks like @poettering, @michich and @keszybz were re-evaluating the issue.

@poettering

This comment has been minimized.

Copy link
Member

poettering commented Jun 27, 2017

The request is, for processors that provide a CPU instruction to produce random numbers, allow systemd collect initial entropy and add it to /dev/{u}random.

Last time I looked the kernel does that anyway, and there's no point in involving usespace with that.

@noloader

This comment has been minimized.

Copy link

noloader commented Jun 27, 2017

Last time I looked the kernel does that anyway, and there's no point in involving usespace with that.

There seems to be a disconnect somewhere.. Here's what I am seeing. The machines below are modern and fully patched. They are x86_64 with 4th and 5th gen Core i5's and Core i7's.

Ubuntu 17:

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu Zesty Zapus
Release:        17.04
Codename:       zesty

$ dmesg 2>&1 | grep random
[    2.089120] random: systemd-udevd: uninitialized urandom read (16 bytes read)
[    2.089243] random: systemd-udevd: uninitialized urandom read (16 bytes read)
[    2.089259] random: systemd-udevd: uninitialized urandom read (16 bytes read)
[    2.090556] random: udevadm: uninitialized urandom read (16 bytes read)
[    2.090621] random: udevadm: uninitialized urandom read (16 bytes read)
[    2.092149] random: udevadm: uninitialized urandom read (16 bytes read)
[    2.092242] random: udevadm: uninitialized urandom read (16 bytes read)
[    2.092829] random: udevadm: uninitialized urandom read (16 bytes read)
[    2.092923] random: udevadm: uninitialized urandom read (16 bytes read)
[    2.093011] random: udevadm: uninitialized urandom read (16 bytes read)
[    3.106702] random: fast init done
[    5.413113] random: crng init done
[   10.115108] systemd[1]: apt-daily.timer: Adding 6h 12min 31.501857s random time.
[   10.463175] systemd[1]: apt-daily.timer: Adding 9h 1min 46.081847s random time.
...

And Fedora 25:

$ lsb_release -a
LSB Version:    :core-4.1-amd64:core-4.1-noarch
Distributor ID: Fedora
Description:    Fedora release 25 (Twenty Five)
Release:        25
Codename:       TwentyFive

$ dmesg 2>&1 | grep random
[    1.290538] random: systemd: uninitialized urandom read (16 bytes read)
[    1.291153] random: systemd: uninitialized urandom read (16 bytes read)
[    1.291182] random: systemd: uninitialized urandom read (16 bytes read)
[    1.365406] random: systemd: uninitialized urandom read (16 bytes read)
[    1.365444] random: systemd: uninitialized urandom read (16 bytes read)
[    1.365502] random: systemd: uninitialized urandom read (16 bytes read)
[    1.365584] random: systemd: uninitialized urandom read (16 bytes read)
[    1.366847] random: systemd: uninitialized urandom read (16 bytes read)
[    1.367186] random: systemd: uninitialized urandom read (16 bytes read)
[    1.367597] random: systemd: uninitialized urandom read (16 bytes read)
[    3.306724] random: fast init done
[    8.673833] random: crng init done
...
@poettering

This comment has been minimized.

Copy link
Member

poettering commented Jun 27, 2017

There seems to be a disconnect somewhere.. Here's what I am seeing. The machines below are modern and fully patched. They are x86_64 with 4th and 5th gen Core i5's and Core i7's.

I think the data is included but not credited to the entropy, since the source can't be trusted too much... Anyway, this issue here is about something else. And either way, whether to include the CPU's generator in /dev/urandom and whether to credit the entropy for it, is really a discussion for the kernel folks, userspace should not be involved. LWN had a couple of stories about this btw, try searching there.

keszybz added a commit to keszybz/systemd that referenced this issue Jun 28, 2017

basic/random-util: do not fall back to /dev/urandom if getrandom() re…
…turns short

During early boot, we'd call getrandom(), and immediately fall back to
reading from /dev/urandom unless we got the full requested number of bytes.
Those two sources are the same, so the most likely result is /dev/urandom
producing some pseudorandom numbers for us, complaining widely on the way.

Let's change our behaviour to be more conservative:
- if the numbers are only used to initialize a hash table, a short read
  is OK, we don't really care if we get the first part of the seed and then
  some zeros. So just return "success" in that case.
- if getrandom() returns -EAGAIN, fall back to rand() instead of querying
  /dev/urandom again.
  The idea with those two changes is to avoid generating a warning about
  reading from an /dev/urandom when the kernel doesn't have enough entropy.
- only in the cases where we really need to make the best effort possible
  (sd_id128_randomize and firstboot password hashing), fall back to
  /dev/urandom.

sd_id128_randomize is a special case — for our internal uses we'd be fine to
fall back to rand(), but when provided as a function in sd_id128.so, we don't
know whether srand() was called properly, and how rand() is used otherwise, so
we cannot fall back to rand(). In that case using /dev/urandom is the only
reasonable fallback.

When falling back to /dev/urandom, don't lose the short read we already got,
and just read the remaining bytes.

When calling getrandom(), drop the checks whether the argument fits in an int —
getrandom() should do that for us already, and we call it with small arguments
only anyway.

Note that this does not really change the (relatively high) number of random
bytes we request from the kernel. On my laptop, during boot, PID 1 and all
other processes using this code through libsystemd request:
  74780 bytes with high_quality_required == false
    464 bytes with high_quality_required == true
and it does not eliminate reads from /dev/urandom completely. If the kernel was
short on entropy and getrandom() would fail, we would fall back to /dev/urandom
for those 464 bytes.

If getrandom() syscall is not available, we fall back to /dev/urandom same
as before.

Fixes systemd#4167 (possibly partially, let's see).

@keszybz keszybz closed this in f0d0905 Jun 30, 2017

@dhardy dhardy referenced this issue Mar 26, 2018

Merged

Osrng doc #333

@corsac-s

This comment has been minimized.

Copy link

corsac-s commented May 9, 2018

It seems that the fix for https://bugs.chromium.org/p/project-zero/issues/detail?id=1559 made this one much worse. A Debian bug has been opened with one message pointing to sd_id128_randomize() calling acquire_random_bytes(high_quality_required=true) which ends up busy-looping on /dev/urandom (which is now blocking).

@kroeckx

This comment has been minimized.

Copy link

kroeckx commented May 9, 2018

My current understand is that reading from /dev/uradom never blocks, but that there is a call to getrandom() without GRND_NONBLOCK which is probably the case when high_quality_required=true.

@corsac-s

This comment has been minimized.

Copy link

corsac-s commented May 10, 2018

@kroeckx it seems that the specific problem for Debian is not in systemd/udev but rather in plymouth/fontconfig/libuuid (generating uuids requires randomness). That specific UUID generation can be prevented, and util-linux 2.32 makes the getrandom call non-blocking.

@KumarShrawan

This comment has been minimized.

Copy link

KumarShrawan commented Oct 1, 2018

I am using systemd234 and kernel version 4.4.84 and I see that one of the early boot application which internally calls createuuid() takes lot of time to come-up . It blocks until Random pool gets initialized .
Do we know some quick hack.fix for this issue ?

@corsac-s

This comment has been minimized.

Copy link

corsac-s commented Oct 1, 2018

I am using systemd234 and kernel version 4.4.84 and I see that one of the early boot application which internally calls createuuid() takes lot of time to come-up . It blocks until Random pool gets initialized .
Do we know some quick hack.fix for this issue ?

See my reply just above? util-linux 2.32 makes the getrandom call in libuuid non-blocking

@crrodriguez

This comment has been minimized.

Copy link
Contributor

crrodriguez commented Nov 20, 2018

With kernel 4.19 or later, pass random.trust_cpu=1 as a boot parameter and all this kind of issues will go away, getrandom will never block on Intel or AMD cpus that support RDRAND/RDSEED.

@jskusk

This comment has been minimized.

Copy link

jskusk commented Dec 4, 2018

@corsac-s: FYI I tried util-linux 2.32.1-0.1 from testing but it still hangs approx 30 sec doing boot on my Beaglebone Black with Debian 9.5 (beaglebone 4.14.67-ti-r73 #1 SMP PREEMPT Thu Aug 30 00:08:52 UTC 2018 armv7l GNU/Linux)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment