lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAG48ez3Jv6_SSgxMrzEmx1pY04TnsOXhGVvjt2-14-xe-BjTzA@mail.gmail.com>
Date:   Wed, 7 Oct 2020 06:20:40 +0200
From:   Jann Horn <jannh@...gle.com>
To:     Eric Biggers <ebiggers@...nel.org>
Cc:     "Theodore Ts'o" <tytso@....edu>, linux-crypto@...r.kernel.org,
        kernel list <linux-kernel@...r.kernel.org>,
        Andy Lutomirski <luto@...nel.org>
Subject: Re: [PATCH] random: fix the RNDRESEEDCRNG ioctl

On Wed, Sep 16, 2020 at 6:19 AM Eric Biggers <ebiggers@...nel.org> wrote:
> The RNDRESEEDCRNG ioctl reseeds the primary_crng from itself, which
> doesn't make sense.  Reseed it from the input_pool instead.

Good catch. (And its purpose is to ensure that entropy from
random_write() is plumbed all the way through such that getrandom()
and friends are guaranteed to actually use that entropy on the next
invocation; and random_write() just puts data into the input pool.)

But actually, looking at the surrounding code, I think there's another
small problem?

> Fixes: d848e5f8e1eb ("random: add new ioctl RNDRESEEDCRNG")
> Cc: stable@...r.kernel.org
> Signed-off-by: Eric Biggers <ebiggers@...gle.com>

Reviewed-by: Jann Horn <jannh@...gle.com>

> ---
>  drivers/char/random.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/char/random.c b/drivers/char/random.c
> index d20ba1b104ca3..a8b9e66f41435 100644
> --- a/drivers/char/random.c
> +++ b/drivers/char/random.c
> @@ -1973,7 +1973,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
>                         return -EPERM;
>                 if (crng_init < 2)
>                         return -ENODATA;
> -               crng_reseed(&primary_crng, NULL);
> +               crng_reseed(&primary_crng, &input_pool);

So now this will pull the data from the input_pool into the
primary_crng, so far so good...

>                 crng_global_init_time = jiffies - 1;

... and this will hopefully cause _extract_crng() to pull from the
primary_crng into crng_node_pool[numa_node_id()] afterwards. Unless
things are going too fast and therefore the jiffies haven't changed
since the last crng_reseed() on the crng_node_pool[numa_node_id()]...
a sequence number would probably be more robust than a timestamp.

And a plain write like this without holding any locks is also questionable.

The easiest way would probably be to make it an atomic_long_t, do
atomic_long_inc() instead of setting crng_global_init_time here, and
check atomic_long_read(...) against a copy stored in the crng_state on
_extract_crng()? And in crng_reseed(), grab the global sequence number
at the start, then do smp_rmb(), and then under the lock do the actual
reseeding and bump ->init_time? Or something like that?

>                 return 0;
>         default:

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ