All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Morton <akpm@linux-foundation.org>
To: Aaron Straus <aaron@merfinllc.com>
Cc: mpm@selenic.com, linux-kernel@vger.kernel.org,
	"Theodore Ts'o" <tytso@mit.edu>,
	stable@kernel.org
Subject: Re: drivers/char/random.c line 728 BUG
Date: Fri, 29 Aug 2008 12:48:07 -0700	[thread overview]
Message-ID: <20080829124807.54293904.akpm@linux-foundation.org> (raw)
In-Reply-To: <20080828225924.GD6432@merfinllc.com>

On Thu, 28 Aug 2008 15:59:24 -0700
Aaron Straus <aaron@merfinllc.com> wrote:

> Hi,
> 
> On Aug 26 03:59 PM, Aaron Straus wrote:
> > kernel BUG at drivers/char/random.c:728!
> 
> OK so that's (outside spinlock):
> 
>    BUG_ON(r->entropy_count > r->poolinfo->POOLBITS); 
> 
> in credit_entropy_bits we do (inside spinlock):
> 
> 	r->entropy_count += nbits;
> 	if (r->entropy_count < 0) {
> 		DEBUG_ENT("negative entropy/overflow\n");
> 		r->entropy_count = 0;
> 	} else if (r->entropy_count > r->poolinfo->POOLBITS)
> 		r->entropy_count = r->poolinfo->POOLBITS;
> 
> I wonder if we got unlucky and did the:
> 
>   r->entropy_count += nbits
> 
>  - overflowed the entropy_count THEN
>  - another thread hits the BUG before this thread reaches
> 
>    r->entropy_count = r->poolinfo->POOLBITS;
> 
> --
> 
> I notice before this commit:
> 
> commit adc782dae6c4c0f6fb679a48a544cfbcd79ae3dc
> Author: Matt Mackall <mpm@selenic.com>
> Date:   Tue Apr 29 01:03:07 2008 -0700
> 
>     random: simplify and rename credit_entropy_store
> 
> The credit_entropy_store function looks like this:
> 
> 	spin_lock_irqsave(&r->lock, flags);
> 
> 	if (r->entropy_count + nbits < 0) {
> 		DEBUG_ENT("negative entropy/overflow (%d+%d)\n",
> 			  r->entropy_count, nbits);
> 		r->entropy_count = 0;
> 	} else if (r->entropy_count + nbits > r->poolinfo->POOLBITS) {
> 		r->entropy_count = r->poolinfo->POOLBITS;
> 	} else {
> 		r->entropy_count += nbits;
> 		if (nbits)
> 			DEBUG_ENT("added %d entropy credits to %s\n",
> 				  nbits, r->name);
> 	}
> 
> 
> Notice the old version is careful not to overflow r->entropy_count at
> any point (even within the spinlock).  So perhaps that's why we didn't
> hit this BUG() in the past?
> 

yep, I would agree with all that.

How's this look?


From: Andrew Morton <akpm@linux-foundation.org>

Fix a bug reported by and diagnosed by Aaron Straus.

This is a regression intruduced into 2.6.26 by

    commit adc782dae6c4c0f6fb679a48a544cfbcd79ae3dc
    Author: Matt Mackall <mpm@selenic.com>
    Date:   Tue Apr 29 01:03:07 2008 -0700

        random: simplify and rename credit_entropy_store

credit_entropy_bits() does:

	spin_lock_irqsave(&r->lock, flags);
	...
	if (r->entropy_count > r->poolinfo->POOLBITS)
		r->entropy_count = r->poolinfo->POOLBITS;

so there is a time window in which this BUG_ON():

static size_t account(struct entropy_store *r, size_t nbytes, int min,
		      int reserved)
{
	unsigned long flags;

	BUG_ON(r->entropy_count > r->poolinfo->POOLBITS);

	/* Hold lock while accounting */
	spin_lock_irqsave(&r->lock, flags);

can trigger.

We could fix this by moving the assertion inside the lock, but it seems
safer and saner to revert to the old behaviour wherein
entropy_store.entropy_count at no time exceeds
entropy_store.poolinfo->POOLBITS.

Reported-by: Aaron Straus <aaron@merfinllc.com>
Cc: Matt Mackall <mpm@selenic.com>
Cc: Theodore Ts'o <tytso@mit.edu>
Cc: <stable@kernel.org>		[2.6.26.x]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 drivers/char/random.c |   17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff -puN drivers/char/random.c~drivers-char-randomc-fix-a-race-which-can-lead-to-a-bogus-bug drivers/char/random.c
--- a/drivers/char/random.c~drivers-char-randomc-fix-a-race-which-can-lead-to-a-bogus-bug
+++ a/drivers/char/random.c
@@ -520,6 +520,7 @@ static void mix_pool_bytes(struct entrop
 static void credit_entropy_bits(struct entropy_store *r, int nbits)
 {
 	unsigned long flags;
+	int entropy_count;
 
 	if (!nbits)
 		return;
@@ -527,20 +528,20 @@ static void credit_entropy_bits(struct e
 	spin_lock_irqsave(&r->lock, flags);
 
 	DEBUG_ENT("added %d entropy credits to %s\n", nbits, r->name);
-	r->entropy_count += nbits;
-	if (r->entropy_count < 0) {
+	entropy_count = r->entropy_count;
+	entropy_count += nbits;
+	if (entropy_count < 0) {
 		DEBUG_ENT("negative entropy/overflow\n");
-		r->entropy_count = 0;
-	} else if (r->entropy_count > r->poolinfo->POOLBITS)
-		r->entropy_count = r->poolinfo->POOLBITS;
+		entropy_count = 0;
+	} else if (entropy_count > r->poolinfo->POOLBITS)
+		entropy_count = r->poolinfo->POOLBITS;
 
 	/* should we wake readers? */
-	if (r == &input_pool &&
-	    r->entropy_count >= random_read_wakeup_thresh) {
+	if (r == &input_pool && entropy_count >= random_read_wakeup_thresh) {
 		wake_up_interruptible(&random_read_wait);
 		kill_fasync(&fasync, SIGIO, POLL_IN);
 	}
-
+	r->entropy_count = entropy_count;
 	spin_unlock_irqrestore(&r->lock, flags);
 }
 
_


  reply	other threads:[~2008-08-29 19:48 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-26 22:59 drivers/char/random.c line 728 BUG Aaron Straus
2008-08-28 22:59 ` Aaron Straus
2008-08-29 19:48   ` Andrew Morton [this message]
2008-08-29 19:54     ` Andrew Morton
2008-08-29 22:31     ` Aaron Straus
2008-08-29 22:42       ` Andrew Morton
2008-09-03 18:18     ` Matt Mackall
2008-09-03 18:28       ` Aaron Straus
2008-09-03 22:12         ` Matt Mackall
2008-09-03 22:32           ` Andrew Morton
2008-09-03 22:51             ` Matt Mackall
2008-09-03 23:12               ` Andrew Morton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080829124807.54293904.akpm@linux-foundation.org \
    --to=akpm@linux-foundation.org \
    --cc=aaron@merfinllc.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mpm@selenic.com \
    --cc=stable@kernel.org \
    --cc=tytso@mit.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.