diff mbox

[resend,4.9] hw_random: Don't use a stack buffer in add_early_randomness()

Message ID 4169224b6858d1cf149f1a73f8a03603fa19076d.1476638125.git.luto@kernel.org (mailing list archive)
State Accepted
Delegated to: Herbert Xu
Headers show

Commit Message

Andy Lutomirski Oct. 17, 2016, 5:06 p.m. UTC
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 <mmullins@mmlx.us>
Tested-by: Matt Mullins <mmullins@mmlx.us>
Fixes: d3cc7996473a ("hwrng: fetch randomness only after device init")
Signed-off-by: Andy Lutomirski <luto@kernel.org>
---

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(-)

Comments

Stephan Mueller Oct. 17, 2016, 5:17 p.m. UTC | #1
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
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Andy Lutomirski Oct. 17, 2016, 5:30 p.m. UTC | #2
On Mon, Oct 17, 2016 at 10:17 AM, Stephan Mueller <smueller@chronox.de> 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
Stephan Mueller Oct. 17, 2016, 6:36 p.m. UTC | #3
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
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Andy Lutomirski Oct. 17, 2016, 9:03 p.m. UTC | #4
On Mon, Oct 17, 2016 at 11:36 AM, Stephan Mueller <smueller@chronox.de> 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...
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Stephan Mueller Oct. 17, 2016, 9:14 p.m. UTC | #5
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 <smueller@chronox.de> 
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
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Herbert Xu Oct. 19, 2016, 3:50 a.m. UTC | #6
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 <mmullins@mmlx.us>
> Tested-by: Matt Mullins <mmullins@mmlx.us>
> Fixes: d3cc7996473a ("hwrng: fetch randomness only after device init")
> Signed-off-by: Andy Lutomirski <luto@kernel.org>

Patch applied.  Thanks.
Xie Yisheng Feb. 4, 2017, 3:47 a.m. UTC | #7
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 <mmullins@mmlx.us>
> Tested-by: Matt Mullins <mmullins@mmlx.us>
> Fixes: d3cc7996473a ("hwrng: fetch randomness only after device init")
> Signed-off-by: Andy Lutomirski <luto@kernel.org>
> ---
> 
> 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)
>
Matt Mullins Feb. 4, 2017, 4:34 a.m. UTC | #8
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/20161016002151.GA18235@hydra.tuxags.com.

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.
Xie Yisheng Feb. 4, 2017, 10:32 a.m. UTC | #9
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/20161016002151.GA18235@hydra.tuxags.com.
> 
> 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
diff mbox

Patch

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)