<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux/drivers/char/random.c, branch v5.18</title>
<subtitle>Mirror of https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
</subtitle>
<id>https://git.shady.money/linux/atom?h=v5.18</id>
<link rel='self' href='https://git.shady.money/linux/atom?h=v5.18'/>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/'/>
<updated>2022-04-25T15:26:40Z</updated>
<entry>
<title>random: document crng_fast_key_erasure() destination possibility</title>
<updated>2022-04-25T15:26:40Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2022-04-18T18:57:31Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=8717627d6ac53251ee012c3c7aca392f29f38a42'/>
<id>urn:sha1:8717627d6ac53251ee012c3c7aca392f29f38a42</id>
<content type='text'>
This reverts 35a33ff3807d ("random: use memmove instead of memcpy for
remaining 32 bytes"), which was made on a totally bogus basis. The thing
it was worried about overlapping came from the stack, not from one of
its arguments, as Eric pointed out.

But the fact that this confusion even happened draws attention to the
fact that it's a bit non-obvious that the random_data parameter can
alias chacha_state, and in fact should do so when the caller can't rely
on the stack being cleared in a timely manner. So this commit documents
that.

Reported-by: Eric Biggers &lt;ebiggers@kernel.org&gt;
Reviewed-by: Eric Biggers &lt;ebiggers@google.com&gt;
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>random: use memmove instead of memcpy for remaining 32 bytes</title>
<updated>2022-04-16T10:53:31Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2022-04-13T23:50:38Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=35a33ff3807d3adb9daaf937f5bca002ffa9f84e'/>
<id>urn:sha1:35a33ff3807d3adb9daaf937f5bca002ffa9f84e</id>
<content type='text'>
In order to immediately overwrite the old key on the stack, before
servicing a userspace request for bytes, we use the remaining 32 bytes
of block 0 as the key. This means moving indices 8,9,a,b,c,d,e,f -&gt;
4,5,6,7,8,9,a,b. Since 4 &lt; 8, for the kernel implementations of
memcpy(), this doesn't actually appear to be a problem in practice. But
relying on that characteristic seems a bit brittle. So let's change that
to a proper memmove(), which is the by-the-books way of handling
overlapping memory copies.

Reviewed-by: Dominik Brodowski &lt;linux@dominikbrodowski.net&gt;
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>random: make random_get_entropy() return an unsigned long</title>
<updated>2022-04-13T11:58:57Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2022-04-08T16:14:57Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=b0c3e796f24b588b862b61ce235d3c9417dc8983'/>
<id>urn:sha1:b0c3e796f24b588b862b61ce235d3c9417dc8983</id>
<content type='text'>
Some implementations were returning type `unsigned long`, while others
that fell back to get_cycles() were implicitly returning a `cycles_t` or
an untyped constant int literal. That makes for weird and confusing
code, and basically all code in the kernel already handled it like it
was an `unsigned long`. I recently tried to handle it as the largest
type it could be, a `cycles_t`, but doing so doesn't really help with
much.

Instead let's just make random_get_entropy() return an unsigned long all
the time. This also matches the commonly used `arch_get_random_long()`
function, so now RDRAND and RDTSC return the same sized integer, which
means one can fallback to the other more gracefully.

Cc: Dominik Brodowski &lt;linux@dominikbrodowski.net&gt;
Cc: Theodore Ts'o &lt;tytso@mit.edu&gt;
Acked-by: Thomas Gleixner &lt;tglx@linutronix.de&gt;
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>random: allow partial reads if later user copies fail</title>
<updated>2022-04-13T11:58:57Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2022-04-07T19:23:08Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=5209aed5137880fa229746cb521f715e55596460'/>
<id>urn:sha1:5209aed5137880fa229746cb521f715e55596460</id>
<content type='text'>
Rather than failing entirely if a copy_to_user() fails at some point,
instead we should return a partial read for the amount that succeeded
prior, unless none succeeded at all, in which case we return -EFAULT as
before.

This makes it consistent with other reader interfaces. For example, the
following snippet for /dev/zero outputs "4" followed by "1":

  int fd;
  void *x = mmap(NULL, 4096, PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
  assert(x != MAP_FAILED);
  fd = open("/dev/zero", O_RDONLY);
  assert(fd &gt;= 0);
  printf("%zd\n", read(fd, x, 4));
  printf("%zd\n", read(fd, x + 4095, 4));
  close(fd);

This brings that same standard behavior to the various RNG reader
interfaces.

While we're at it, we can streamline the loop logic a little bit.

Suggested-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Cc: Jann Horn &lt;jannh@google.com&gt;
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>random: check for signals every PAGE_SIZE chunk of /dev/[u]random</title>
<updated>2022-04-06T23:36:37Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2022-04-06T00:36:16Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=e3c1c4fd9e6d14059ed93ebfe15e1c57793b1a05'/>
<id>urn:sha1:e3c1c4fd9e6d14059ed93ebfe15e1c57793b1a05</id>
<content type='text'>
In 1448769c9cdb ("random: check for signal_pending() outside of
need_resched() check"), Jann pointed out that we previously were only
checking the TIF_NOTIFY_SIGNAL and TIF_SIGPENDING flags if the process
had TIF_NEED_RESCHED set, which meant in practice, super long reads to
/dev/[u]random would delay signal handling by a long time. I tried this
using the below program, and indeed I wasn't able to interrupt a
/dev/urandom read until after several megabytes had been read. The bug
he fixed has always been there, and so code that reads from /dev/urandom
without checking the return value of read() has mostly worked for a long
time, for most sizes, not just for &lt;= 256.

Maybe it makes sense to keep that code working. The reason it was so
small prior, ignoring the fact that it didn't work anyway, was likely
because /dev/random used to block, and that could happen for pretty
large lengths of time while entropy was gathered. But now, it's just a
chacha20 call, which is extremely fast and is just operating on pure
data, without having to wait for some external event. In that sense,
/dev/[u]random is a lot more like /dev/zero.

Taking a page out of /dev/zero's read_zero() function, it always returns
at least one chunk, and then checks for signals after each chunk. Chunk
sizes there are of length PAGE_SIZE. Let's just copy the same thing for
/dev/[u]random, and check for signals and cond_resched() for every
PAGE_SIZE amount of data. This makes the behavior more consistent with
expectations, and should mitigate the impact of Jann's fix for the
age-old signal check bug.

---- test program ----

  #include &lt;unistd.h&gt;
  #include &lt;signal.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;sys/random.h&gt;

  static unsigned char x[~0U];

  static void handle(int) { }

  int main(int argc, char *argv[])
  {
    pid_t pid = getpid(), child;
    signal(SIGUSR1, handle);
    if (!(child = fork())) {
      for (;;)
        kill(pid, SIGUSR1);
    }
    pause();
    printf("interrupted after reading %zd bytes\n", getrandom(x, sizeof(x), 0));
    kill(child, SIGTERM);
    return 0;
  }

Cc: Jann Horn &lt;jannh@google.com&gt;
Cc: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>random: check for signal_pending() outside of need_resched() check</title>
<updated>2022-04-06T13:09:33Z</updated>
<author>
<name>Jann Horn</name>
<email>jannh@google.com</email>
</author>
<published>2022-04-05T16:39:31Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=1448769c9cdb69ad65287f4f7ab58bc5f2f5d7ba'/>
<id>urn:sha1:1448769c9cdb69ad65287f4f7ab58bc5f2f5d7ba</id>
<content type='text'>
signal_pending() checks TIF_NOTIFY_SIGNAL and TIF_SIGPENDING, which
signal that the task should bail out of the syscall when possible. This
is a separate concept from need_resched(), which checks
TIF_NEED_RESCHED, signaling that the task should preempt.

In particular, with the current code, the signal_pending() bailout
probably won't work reliably.

Change this to look like other functions that read lots of data, such as
read_zero().

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Jann Horn &lt;jannh@google.com&gt;
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>random: do not allow user to keep crng key around on stack</title>
<updated>2022-04-06T13:05:10Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2022-04-05T14:40:51Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=aba120cc101788544aa3e2c30c8da88513892350'/>
<id>urn:sha1:aba120cc101788544aa3e2c30c8da88513892350</id>
<content type='text'>
The fast key erasure RNG design relies on the key that's used to be used
and then discarded. We do this, making judicious use of
memzero_explicit().  However, reads to /dev/urandom and calls to
getrandom() involve a copy_to_user(), and userspace can use FUSE or
userfaultfd, or make a massive call, dynamically remap memory addresses
as it goes, and set the process priority to idle, in order to keep a
kernel stack alive indefinitely. By probing
/proc/sys/kernel/random/entropy_avail to learn when the crng key is
refreshed, a malicious userspace could mount this attack every 5 minutes
thereafter, breaking the crng's forward secrecy.

In order to fix this, we just overwrite the stack's key with the first
32 bytes of the "free" fast key erasure output. If we're returning &lt;= 32
bytes to the user, then we can still return those bytes directly, so
that short reads don't become slower. And for long reads, the difference
is hopefully lost in the amortization, so it doesn't change much, with
that amortization helping variously for medium reads.

We don't need to do this for get_random_bytes() and the various
kernel-space callers, and later, if we ever switch to always batching,
this won't be necessary either, so there's no need to change the API of
these functions.

Cc: Theodore Ts'o &lt;tytso@mit.edu&gt;
Reviewed-by: Jann Horn &lt;jannh@google.com&gt;
Fixes: c92e040d575a ("random: add backtracking protection to the CRNG")
Fixes: 186873c549df ("random: use simpler fast key erasure flow on per-cpu keys")
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>random: opportunistically initialize on /dev/urandom reads</title>
<updated>2022-04-05T14:13:13Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2022-04-05T13:57:05Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=48bff1053c172e6c7f340e506027d118147c8b7f'/>
<id>urn:sha1:48bff1053c172e6c7f340e506027d118147c8b7f</id>
<content type='text'>
In 6f98a4bfee72 ("random: block in /dev/urandom"), we tried to make a
successful try_to_generate_entropy() call *required* if the RNG was not
already initialized. Unfortunately, weird architectures and old
userspaces combined in TCG test harnesses, making that change still not
realistic, so it was reverted in 0313bc278dac ("Revert "random: block in
/dev/urandom"").

However, rather than making a successful try_to_generate_entropy() call
*required*, we can instead make it *best-effort*.

If try_to_generate_entropy() fails, it fails, and nothing changes from
the current behavior. If it succeeds, then /dev/urandom becomes safe to
use for free. This way, we don't risk the regression potential that led
to us reverting the required-try_to_generate_entropy() call before.

Practically speaking, this means that at least on x86, /dev/urandom
becomes safe. Probably other architectures with working cycle counters
will also become safe. And architectures with slow or broken cycle
counters at least won't be affected at all by this change.

So it may not be the glorious "all things are unified!" change we were
hoping for initially, but practically speaking, it makes a positive
impact.

Cc: Theodore Ts'o &lt;tytso@mit.edu&gt;
Cc: Dominik Brodowski &lt;linux@dominikbrodowski.net&gt;
Cc: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>random: do not split fast init input in add_hwgenerator_randomness()</title>
<updated>2022-04-04T17:34:49Z</updated>
<author>
<name>Jan Varho</name>
<email>jan.varho@gmail.com</email>
</author>
<published>2022-04-04T16:42:30Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=527a9867af29ff89f278d037db704e0ed50fb666'/>
<id>urn:sha1:527a9867af29ff89f278d037db704e0ed50fb666</id>
<content type='text'>
add_hwgenerator_randomness() tries to only use the required amount of input
for fast init, but credits all the entropy, rather than a fraction of
it. Since it's hard to determine how much entropy is left over out of a
non-unformly random sample, either give it all to fast init or credit
it, but don't attempt to do both. In the process, we can clean up the
injection code to no longer need to return a value.

Signed-off-by: Jan Varho &lt;jan.varho@gmail.com&gt;
[Jason: expanded commit message]
Fixes: 73c7733f122e ("random: do not throw away excess input to crng_fast_load")
Cc: stable@vger.kernel.org # 5.17+, requires af704c856e88
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>random: mix build-time latent entropy into pool at init</title>
<updated>2022-03-31T20:43:27Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2022-03-31T15:01:01Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=1754abb3e7583c570666fa1e1ee5b317e88c89a0'/>
<id>urn:sha1:1754abb3e7583c570666fa1e1ee5b317e88c89a0</id>
<content type='text'>
Prior, the "input_pool_data" array needed no real initialization, and so
it was easy to mark it with __latent_entropy to populate it during
compile-time. In switching to using a hash function, this required us to
specifically initialize it to some specific state, which means we
dropped the __latent_entropy attribute. An unfortunate side effect was
this meant the pool was no longer seeded using compile-time random data.
In order to bring this back, we declare an array in rand_initialize()
with __latent_entropy and call mix_pool_bytes() on that at init, which
accomplishes the same thing as before. We make this __initconst, so that
it doesn't take up space at runtime after init.

Fixes: 6e8ec2552c7d ("random: use computational hash for entropy extraction")
Reviewed-by: Dominik Brodowski &lt;linux@dominikbrodowski.net&gt;
Reviewed-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
</feed>
