2016-10-17 17:06:27

by Andy Lutomirski

[permalink] [raw]
Subject: [PATCH resend 4.9] hw_random: Don't use a stack buffer in add_early_randomness()

hw_random carefully avoids using a stack buffer except in
add_early_randomness(). This causes a crash in virtio_rng if
CONFIG_VMAP_STACK=y.

Reported-by: Matt Mullins <[email protected]>
Tested-by: Matt Mullins <[email protected]>
Fixes: d3cc7996473a ("hwrng: fetch randomness only after device init")
Signed-off-by: Andy Lutomirski <[email protected]>
---

This fixes a crash in 4.9-rc1.

resending because I typoed the git send-email command. I stealthily added
Matt's Tested-by, too.

drivers/char/hw_random/core.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 9203f2d130c0..340f96e44642 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -84,14 +84,14 @@ static size_t rng_buffer_size(void)

static void add_early_randomness(struct hwrng *rng)
{
- unsigned char bytes[16];
int bytes_read;
+ size_t size = min_t(size_t, 16, rng_buffer_size());

mutex_lock(&reading_mutex);
- bytes_read = rng_get_data(rng, bytes, sizeof(bytes), 1);
+ bytes_read = rng_get_data(rng, rng_buffer, size, 1);
mutex_unlock(&reading_mutex);
if (bytes_read > 0)
- add_device_randomness(bytes, bytes_read);
+ add_device_randomness(rng_buffer, bytes_read);
}

static inline void cleanup_rng(struct kref *kref)
--
2.7.4


2016-10-16 21:37:18

by Matt Mullins

[permalink] [raw]
Subject: Re: [PATCH 4.9] hw_random: Don't use a stack buffer in add_early_randomness()

On Sun, Oct 16, 2016 at 10:17:15AM -0700, Andy Lutomirski wrote:
> hw_random carefully avoids using a stack buffer except in
> add_early_randomness(). This causes a crash in virtio_rng if
> CONFIG_VMAP_STACK=y.

I hadn't noticed the existing kmalloc in the __init, for the explicit purpose
of virt_to_page().

This boots on the VM from which I had grabbed the stack trace yesterday.

Tested-by: Matt Mullins <[email protected]>

Looks like an extra quote snuck in your To: line, so I'm not sure if this was
distributed as widely as you intended.

2016-10-17 17:17:38

by Stephan Müller

[permalink] [raw]
Subject: Re: [PATCH resend 4.9] hw_random: Don't use a stack buffer in add_early_randomness()

Am Montag, 17. Oktober 2016, 10:06:27 CEST schrieb Andy Lutomirski:

Hi Andy,

> diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
> index 9203f2d130c0..340f96e44642 100644
> --- a/drivers/char/hw_random/core.c
> +++ b/drivers/char/hw_random/core.c
> @@ -84,14 +84,14 @@ static size_t rng_buffer_size(void)
>
> static void add_early_randomness(struct hwrng *rng)
> {
> - unsigned char bytes[16];
> int bytes_read;
> + size_t size = min_t(size_t, 16, rng_buffer_size());
>
> mutex_lock(&reading_mutex);
> - bytes_read = rng_get_data(rng, bytes, sizeof(bytes), 1);
> + bytes_read = rng_get_data(rng, rng_buffer, size, 1);
> mutex_unlock(&reading_mutex);
> if (bytes_read > 0)
> - add_device_randomness(bytes, bytes_read);
> + add_device_randomness(rng_buffer, bytes_read);

Shouldn't there be a memset(0) of the rng_buffer at this point to avoid having
such data lingering in memory?


Ciao
Stephan

2016-10-17 17:30:53

by Andy Lutomirski

[permalink] [raw]
Subject: Re: [PATCH resend 4.9] hw_random: Don't use a stack buffer in add_early_randomness()

On Mon, Oct 17, 2016 at 10:17 AM, Stephan Mueller <[email protected]> wrote:
> Am Montag, 17. Oktober 2016, 10:06:27 CEST schrieb Andy Lutomirski:
>
> Hi Andy,
>
>> diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
>> index 9203f2d130c0..340f96e44642 100644
>> --- a/drivers/char/hw_random/core.c
>> +++ b/drivers/char/hw_random/core.c
>> @@ -84,14 +84,14 @@ static size_t rng_buffer_size(void)
>>
>> static void add_early_randomness(struct hwrng *rng)
>> {
>> - unsigned char bytes[16];
>> int bytes_read;
>> + size_t size = min_t(size_t, 16, rng_buffer_size());
>>
>> mutex_lock(&reading_mutex);
>> - bytes_read = rng_get_data(rng, bytes, sizeof(bytes), 1);
>> + bytes_read = rng_get_data(rng, rng_buffer, size, 1);
>> mutex_unlock(&reading_mutex);
>> if (bytes_read > 0)
>> - add_device_randomness(bytes, bytes_read);
>> + add_device_randomness(rng_buffer, bytes_read);
>
> Shouldn't there be a memset(0) of the rng_buffer at this point to avoid having
> such data lingering in memory?

Sure, but shouldn't that be a separate patch covering the whole hw_crypto core?

--Andy


--
Andy Lutomirski
AMA Capital Management, LLC

2016-10-17 18:36:22

by Stephan Müller

[permalink] [raw]
Subject: Re: [PATCH resend 4.9] hw_random: Don't use a stack buffer in add_early_randomness()

Am Montag, 17. Oktober 2016, 10:30:13 CEST schrieb Andy Lutomirski:

Hi Andy,
>
> Sure, but shouldn't that be a separate patch covering the whole hw_crypto
> core?

I think that you are right -- there are many more cases where a memset(0) is
warranted.

Do you want to make this change or should I send a patch?

Ciao
Stephan

2016-10-17 21:03:43

by Andy Lutomirski

[permalink] [raw]
Subject: Re: [PATCH resend 4.9] hw_random: Don't use a stack buffer in add_early_randomness()

On Mon, Oct 17, 2016 at 11:36 AM, Stephan Mueller <[email protected]> wrote:
> Am Montag, 17. Oktober 2016, 10:30:13 CEST schrieb Andy Lutomirski:
>
> Hi Andy,
>>
>> Sure, but shouldn't that be a separate patch covering the whole hw_crypto
>> core?
>
> I think that you are right -- there are many more cases where a memset(0) is
> warranted.
>
> Do you want to make this change or should I send a patch?

Can you do it? I have my work cut out for me making sure that all the
known regressions get stomped quickly...

2016-10-17 21:14:48

by Stephan Müller

[permalink] [raw]
Subject: Re: [PATCH resend 4.9] hw_random: Don't use a stack buffer in add_early_randomness()

Am Montag, 17. Oktober 2016, 14:03:17 CEST schrieb Andy Lutomirski:

Hi Andy,

> On Mon, Oct 17, 2016 at 11:36 AM, Stephan Mueller <[email protected]>
wrote:
> > Am Montag, 17. Oktober 2016, 10:30:13 CEST schrieb Andy Lutomirski:
> >
> > Hi Andy,
> >
> >> Sure, but shouldn't that be a separate patch covering the whole hw_crypto
> >> core?
> >
> > I think that you are right -- there are many more cases where a memset(0)
> > is warranted.
> >
> > Do you want to make this change or should I send a patch?
>
> Can you do it? I have my work cut out for me making sure that all the
> known regressions get stomped quickly...

Sure, will do.

Thanks.

Ciao
Stephan

2016-10-19 03:50:20

by Herbert Xu

[permalink] [raw]
Subject: Re: [PATCH resend 4.9] hw_random: Don't use a stack buffer in add_early_randomness()

On Mon, Oct 17, 2016 at 10:06:27AM -0700, Andy Lutomirski wrote:
> hw_random carefully avoids using a stack buffer except in
> add_early_randomness(). This causes a crash in virtio_rng if
> CONFIG_VMAP_STACK=y.
>
> Reported-by: Matt Mullins <[email protected]>
> Tested-by: Matt Mullins <[email protected]>
> Fixes: d3cc7996473a ("hwrng: fetch randomness only after device init")
> Signed-off-by: Andy Lutomirski <[email protected]>

Patch applied. Thanks.
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

2017-02-04 03:47:58

by Yisheng Xie

[permalink] [raw]
Subject: Re: [PATCH resend 4.9] hw_random: Don't use a stack buffer in add_early_randomness()

Hi Andy,

On 2016/10/18 1:06, Andy Lutomirski wrote:
> hw_random carefully avoids using a stack buffer except in
> add_early_randomness(). This causes a crash in virtio_rng if
> CONFIG_VMAP_STACK=y.
I try to understand this patch, but I do not know why it will cause
a crash in virtio_rng with CONFIG_VMAP_STACK=y?
Could you please give me more info. about it.

Really thanks for that!
Yisheng Xie.

>
> Reported-by: Matt Mullins <[email protected]>
> Tested-by: Matt Mullins <[email protected]>
> Fixes: d3cc7996473a ("hwrng: fetch randomness only after device init")
> Signed-off-by: Andy Lutomirski <[email protected]>
> ---
>
> This fixes a crash in 4.9-rc1.
>
> resending because I typoed the git send-email command. I stealthily added
> Matt's Tested-by, too.
>
> drivers/char/hw_random/core.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
> index 9203f2d130c0..340f96e44642 100644
> --- a/drivers/char/hw_random/core.c
> +++ b/drivers/char/hw_random/core.c
> @@ -84,14 +84,14 @@ static size_t rng_buffer_size(void)
>
> static void add_early_randomness(struct hwrng *rng)
> {
> - unsigned char bytes[16];
> int bytes_read;
> + size_t size = min_t(size_t, 16, rng_buffer_size());
>
> mutex_lock(&reading_mutex);
> - bytes_read = rng_get_data(rng, bytes, sizeof(bytes), 1);
> + bytes_read = rng_get_data(rng, rng_buffer, size, 1);
> mutex_unlock(&reading_mutex);
> if (bytes_read > 0)
> - add_device_randomness(bytes, bytes_read);
> + add_device_randomness(rng_buffer, bytes_read);
> }
>
> static inline void cleanup_rng(struct kref *kref)
>

2017-02-04 04:42:59

by Matt Mullins

[permalink] [raw]
Subject: Re: [PATCH resend 4.9] hw_random: Don't use a stack buffer in add_early_randomness()

On Sat, Feb 04, 2017 at 11:47:38AM +0800, Yisheng Xie wrote:
> On 2016/10/18 1:06, Andy Lutomirski wrote:
> > hw_random carefully avoids using a stack buffer except in
> > add_early_randomness(). This causes a crash in virtio_rng if
> > CONFIG_VMAP_STACK=y.
> I try to understand this patch, but I do not know why it will cause
> a crash in virtio_rng with CONFIG_VMAP_STACK=y?
> Could you please give me more info. about it.

My original report was
https://lkml.kernel.org/r/[email protected].

The virtio ring APIs use scatterlists to keep track of the buffers, and
scatterlist requires addresses to be in the kernel direct-mapped address range.
This is not the case for vmalloc()ed addresses, such as the original on-stack
"bytes" array when VMAP_STACK=y.

2017-02-04 10:32:46

by Yisheng Xie

[permalink] [raw]
Subject: Re: [PATCH resend 4.9] hw_random: Don't use a stack buffer in add_early_randomness()

hi, Matt,
Thanks for your reply.

On 2017/2/4 12:34, Matt Mullins wrote:
> On Sat, Feb 04, 2017 at 11:47:38AM +0800, Yisheng Xie wrote:
>> On 2016/10/18 1:06, Andy Lutomirski wrote:
>>> hw_random carefully avoids using a stack buffer except in
>>> add_early_randomness(). This causes a crash in virtio_rng if
>>> CONFIG_VMAP_STACK=y.
>> I try to understand this patch, but I do not know why it will cause
>> a crash in virtio_rng with CONFIG_VMAP_STACK=y?
>> Could you please give me more info. about it.
>
> My original report was
> https://lkml.kernel.org/r/[email protected].
>
> The virtio ring APIs use scatterlists to keep track of the buffers, and
> scatterlist requires addresses to be in the kernel direct-mapped address range.
> This is not the case for vmalloc()ed addresses, such as the original on-stack
> "bytes" array when VMAP_STACK=y.
>
I see, and will check the logic to get more detail about it.

Thanks.
Yisheng Xie