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

VirtIO RNG and unexpected behavior of arc4random_buf() standard function of C #68

Open
shengwen-tw opened this issue Jan 12, 2025 · 2 comments · May be fixed by #70
Open

VirtIO RNG and unexpected behavior of arc4random_buf() standard function of C #68

shengwen-tw opened this issue Jan 12, 2025 · 2 comments · May be fixed by #70
Assignees

Comments

@shengwen-tw
Copy link
Collaborator

shengwen-tw commented Jan 12, 2025

This issue was identified during the development of #34 , where kmscube was found to have an extremely high chance of hanging during startup.

Upon investigation, I discovered that the reason kmscube hangs is due to the use of arc4random_buf(), a standard C library function. Since Buildroot packages are mostly built from source, I was able to trace the issue directly to its source.

Firstly, kmscube has the following package dependencies:
kmscube -> Mesa3D -> libgbm (Generic Buffer Management) -> libexpat (an XML parser)

During its startup, kmscube calls a libgbm function that reads application and driver settings from 00-mesa-defaults.conf. This process involves libexpat to parse XML syntax.

It turns out that during initialization, the parser calculates a salt hash, which requires using arc4random_buf() to generate a random number. However, due to an unknown issue, arc4random_buf() often hangs, preventing kmscube from starting.

Currently, we can work around the issue by modifying the following file:

buildroot/output/build/expat-2.6.2/lib/xmlparse.c

static unsigned long
generate_hash_secret_salt(XML_Parser parser) {
+ return 2147483647;

  unsigned long entropy;
  (void)parser;

  /* "Failproof" high quality providers: */
#if defined(HAVE_ARC4RANDOM_BUF)
  arc4random_buf(&entropy, sizeof(entropy));
  return ENTROPY_DEBUG("arc4random_buf", entropy);
#elif defined(HAVE_ARC4RANDOM)
  ...
}
@shengwen-tw
Copy link
Collaborator Author

shengwen-tw commented Jan 25, 2025

Quoted from https://en.wikipedia.org/wiki//dev/random:

/dev/random typically blocked if there was less entropy available than requested; more recently (see below for the differences between operating systems) it usually blocks at startup until sufficient entropy has been gathered, then unblocks permanently. The /dev/urandom device typically was never a blocking device, even if the pseudorandom number generator seed was not fully initialized with entropy since boot. Not all operating systems implement the same methods for /dev/random and /dev/urandom.

Entropy injection (VirtIO RNG)

With Linux kernel 3.16 and newer,[12] the kernel itself mixes data from hardware random number generators into /dev/random on a sliding scale based on the definable entropy estimation quality of the HWRNG. This means that no userspace daemon, such as rngd from rng-tools, is needed to do that job. With Linux kernel 3.17+, the VirtIO RNG was modified to have a default quality defined above 0,[13] and as such, is currently the only HWRNG mixed into /dev/random by default.

Check also:
https://elixir.bootlin.com/glibc/glibc-2.36/source/stdlib/arc4random.c

@shengwen-tw shengwen-tw self-assigned this Jan 25, 2025
@shengwen-tw shengwen-tw changed the title Unexpected behavior of arc4random_buf() standard function of C VirtIO RNG and unexpected behavior of arc4random_buf() standard function of C Jan 25, 2025
shengwen-tw added a commit to shengwen-tw/semu that referenced this issue Jan 26, 2025
This commit introduces the VirtIO entropy device, also known as virtio-rng in
QEMU or the Linux kernel.

Randomness is a precious resource in the system. Without sufficient entropy,
functions like arc4random_buf() in the standard C library may not work properly
since they rely on the blocking device /dev/random.

Closed sysprog21#68.
@shengwen-tw shengwen-tw linked a pull request Jan 26, 2025 that will close this issue
@shengwen-tw
Copy link
Collaborator Author

#70 resolves the issue here.

shengwen-tw added a commit to shengwen-tw/semu that referenced this issue Jan 29, 2025
This commit introduces the VirtIO entropy device, also known as virtio-rng in
QEMU or the Linux kernel.

Randomness is a precious resource in the system. Without sufficient entropy,
functions like arc4random_buf() in the standard C library may not work properly
since they rely on the blocking device /dev/random.

Quaoted from: https://en.wikipedia.org/wiki//dev/random

/dev/random typically blocked if there was less entropy available than
requested; more recently (see below for the differences between operating
systems) it usually blocks at startup until sufficient entropy has been
gathered, then unblocks permanently.

With Linux kernel 3.16 and newer, the kernel itself mixes data from hardware
random number generators into /dev/random on a sliding scale based on the
definable entropy estimation quality of the HWRNG. This means that no userspace
daemon, such as rngd from rng-tools, is needed to do that job. With Linux
kernel 3.17+, the VirtIO RNG was modified to have a default quality defined
above 0, and as such, is currently the only HWRNG mixed into /dev/random by
default.

Close sysprog21#68.
shengwen-tw added a commit to shengwen-tw/semu that referenced this issue Jan 29, 2025
This commit introduces the VirtIO entropy device, also known as virtio-rng in
QEMU or the Linux kernel.

Randomness is a precious resource in the system. Without sufficient entropy,
functions like arc4random_buf() in the standard C library may not work properly
since they rely on the blocking device /dev/random.

Quaoted from https://en.wikipedia.org/wiki//dev/random

/dev/random typically blocked if there was less entropy available than
requested; more recently (see below for the differences between operating
systems) it usually blocks at startup until sufficient entropy has been
gathered, then unblocks permanently.

With Linux kernel 3.16 and newer, the kernel itself mixes data from hardware
random number generators into /dev/random on a sliding scale based on the
definable entropy estimation quality of the HWRNG. This means that no userspace
daemon, such as rngd from rng-tools, is needed to do that job. With Linux
kernel 3.17+, the VirtIO RNG was modified to have a default quality defined
above 0, and as such, is currently the only HWRNG mixed into /dev/random by
default.

Close sysprog21#68.
shengwen-tw added a commit to shengwen-tw/semu that referenced this issue Jan 29, 2025
This commit introduces the VirtIO entropy device, also known as virtio-rng in
QEMU or the Linux kernel.

Randomness is a precious resource in the system. Without sufficient entropy,
functions like arc4random_buf() in the standard C library may not work properly
since they rely on the blocking device /dev/random.

Quaoted from https://en.wikipedia.org/wiki//dev/random

/dev/random typically blocked if there was less entropy available than
requested; more recently (see below for the differences between operating
systems) it usually blocks at startup until sufficient entropy has been
gathered, then unblocks permanently.

With Linux kernel 3.16 and newer, the kernel itself mixes data from hardware
random number generators into /dev/random on a sliding scale based on the
definable entropy estimation quality of the HWRNG. This means that no userspace
daemon, such as rngd from rng-tools, is needed to do that job. With Linux
kernel 3.17+, the VirtIO RNG was modified to have a default quality defined
above 0, and as such, is currently the only HWRNG mixed into /dev/random by
default.

Close sysprog21#68.
shengwen-tw added a commit to shengwen-tw/semu that referenced this issue Jan 29, 2025
This commit introduces the VirtIO entropy device (also know as virtio-rng in
QEMU and the Linux kernel) to resolve the blocking issue of arc4random_buf()
[1] caused by insufficient entropy for /dev/random.

According to the man page (`man 7 random`):

Interface Pool: /dev/random
Pool: Blocking pool
Blocking behavior: If entropy too low, blocks until there is enough entropy
Behavior when pool is not yet ready: Blocks until enough entropy gathered

Quaoted from https://en.wikipedia.org/wiki//dev/random

With Linux kernel 3.16 and newer, the kernel itself mixes data from hardware
random number generators into /dev/random on a sliding scale based on the
definable entropy estimation quality of the HWRNG. This means that no userspace
daemon, such as rngd from rng-tools, is needed to do that job. With Linux
kernel 3.17+, the VirtIO RNG was modified to have a default quality defined
above 0, and as such, is currently the only HWRNG mixed into /dev/random by
default.

[1] https://elixir.bootlin.com/glibc/glibc-2.36/source/stdlib/arc4random.c

Close sysprog21#68.
shengwen-tw added a commit to shengwen-tw/semu that referenced this issue Jan 29, 2025
This commit introduces the VirtIO entropy device (also know as virtio-rng in
QEMU and the Linux kernel) to resolve the blocking issue of arc4random_buf()
[1] caused by insufficient entropy for /dev/random.

According to the man page (`man 7 random`):

The kernel random-number generator relies on entropy gathered from device
drivers and other sources of environmental noise to seed a cryptographically
secure pseudorandom number generator (CSPRNG).

Interface Pool: /dev/random
Pool: Blocking pool
Blocking behavior: If entropy too low, blocks until there is enough entropy
Behavior when pool is not yet ready: Blocks until enough entropy gathered

Quaoted from https://en.wikipedia.org/wiki//dev/random

With Linux kernel 3.16 and newer, the kernel itself mixes data from hardware
random number generators into /dev/random on a sliding scale based on the
definable entropy estimation quality of the HWRNG. This means that no userspace
daemon, such as rngd from rng-tools, is needed to do that job. With Linux
kernel 3.17+, the VirtIO RNG was modified to have a default quality defined
above 0, and as such, is currently the only HWRNG mixed into /dev/random by
default.

[1] https://elixir.bootlin.com/glibc/glibc-2.36/source/stdlib/arc4random.c

Close sysprog21#68.
shengwen-tw added a commit to shengwen-tw/semu that referenced this issue Jan 29, 2025
This commit introduces the VirtIO entropy device (also know as virtio-rng in
QEMU and the Linux kernel) to resolve the blocking issue of arc4random_buf()
[1] caused by insufficient entropy of /dev/random.

According to the man page (`man 7 random`):

The kernel random-number generator relies on entropy gathered from device
drivers and other sources of environmental noise to seed a cryptographically
secure pseudorandom number generator (CSPRNG).

Interface Pool: /dev/random
Pool: Blocking pool
Blocking behavior: If entropy too low, blocks until there is enough entropy
Behavior when pool is not yet ready: Blocks until enough entropy gathered

Quaoted from https://en.wikipedia.org/wiki//dev/random

With Linux kernel 3.16 and newer, the kernel itself mixes data from hardware
random number generators into /dev/random on a sliding scale based on the
definable entropy estimation quality of the HWRNG. This means that no userspace
daemon, such as rngd from rng-tools, is needed to do that job. With Linux
kernel 3.17+, the VirtIO RNG was modified to have a default quality defined
above 0, and as such, is currently the only HWRNG mixed into /dev/random by
default.

[1] https://elixir.bootlin.com/glibc/glibc-2.36/source/stdlib/arc4random.c

Close sysprog21#68.
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 a pull request may close this issue.

1 participant