All of lore.kernel.org
 help / color / mirror / Atom feed
From: <charley.ashbringer@gmail.com>
To: "'Andrew Morton'" <akpm@linux-foundation.org>
Cc: <willy@infradead.org>, <rdunlap@infradead.org>,
	<keescook@chromium.org>, <mcgrof@kernel.org>,
	<yzaikin@google.com>, <linux-kernel@vger.kernel.org>
Subject: RE: [PATCH v2] panic: prevent panic_timeout * 1000 from overflow
Date: Thu, 16 Jul 2020 00:48:14 -0400	[thread overview]
Message-ID: <000901d65b2c$515211f0$f3f635d0$@gmail.com> (raw)
In-Reply-To: <20200713185739.03d576cca0dc9f618ea76d67@linux-foundation.org>

> > Since panic_timeout is an integer passed-in through sysctl,
> > the loop boundary panic_timeout * 1000 could overflow and
> > result in a zero-delay panic when panic_timeout is greater
> > than INT_MAX/1000.
> >
> > Fix this by moving 1000 to the left, also in case i/1000
> > might never be greater than panic_timeout, change i to
> > long long so that it strictly has more bits.
> >
> > ...
> >
> > --- a/kernel/panic.c
> > +++ b/kernel/panic.c
> > @@ -178,7 +178,8 @@ void panic(const char *fmt, ...)
> >  {
> >  	static char buf[1024];
> >  	va_list args;
> > -	long i, i_next = 0, len;
> > +	long long i;
> > +	long i_next = 0, len;
> >  	int state = 0;
> >  	int old_cpu, this_cpu;
> >  	bool _crash_kexec_post_notifiers = crash_kexec_post_notifiers;
> > @@ -315,7 +316,7 @@ void panic(const char *fmt, ...)
> >  		 */
> >  		pr_emerg("Rebooting in %d seconds..\n", panic_timeout);
> >
> > -		for (i = 0; i < panic_timeout * 1000; i += PANIC_TIMER_STEP)
{
> > +		for (i = 0; i / 1000 < panic_timeout; i += PANIC_TIMER_STEP)
{
> 
> Problem is, 32-bit machines generally cannot perform 64-bit divides.
> So a call is emitted to the library function __divsi64() (I forget the
exact
> name) which Linux doesn't implement (because it's so slow, and we don't
> want to be calling it by accident).
> 

It's good to know, thanks for letting me know why 64-bit division 
is slow, and 64-multiplication is fast, surely doing so many
64-bit division will drag a lot, and should be prevented.

> So a fix would be to call do_div() or something from
> include/linux/div64.h but it's all a great mess.
> 
> However we can do native 64-bit multiplication on 32-bit!  So how about
> something like
> 
> --- a/kernel/panic.c~a
> +++ a/kernel/panic.c
> @@ -313,13 +313,16 @@ void panic(const char *fmt, ...)
>  		 * Delay timeout seconds before rebooting the machine.
>  		 * We can't use the "normal" timers since we just panicked.
>  		 */
> +		u64 timeout = panic_timeout * 1000;	/* avoid overflow */
> +		u64 timer;
>		pr_emerg("Rebooting in %d seconds..\n", panic_timeout);
> -		for (i = 0; i < panic_timeout * 1000; i += PANIC_TIMER_STEP)
{
> +		for (timer = 0; timer < timeout; timer += PANIC_TIMER_STEP)
{

If using u64 as the loop boundary, would it be a problem if
panic_timeout is negative? Since in the current code, if
panic_timeout is negative, the loop will not be executed;
as in the patched code, the loop boundary will be a huge 
unsigned value. I guess s64 should do?

If it's not a problem, I'll submit another patch enforcing
the change, including the changes suggested by Matthew here:

> > +		u64 timeout = panic_timeout * 1000;	/* avoid overflow */
> 1000ULL to not truncate before the assignment.

> > +		u64 timer;
> ... as you implied lateru64 timer, timer_next;


Thank you guys so much for your valuable feedback, I learned a lot!

Best,
Changming


      parent reply	other threads:[~2020-07-16  4:48 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <0d4601d65709a0e2d80e2a8880gmail.com>
2020-07-11  5:17 ` [PATCH v2] panic: prevent panic_timeout * 1000 from overflow Changming
2020-07-14  1:57   ` Andrew Morton
2020-07-14  2:50     ` Matthew Wilcox
2020-07-16 23:15       ` [PATCH v3] " Changming Liu
2020-07-16  4:48     ` charley.ashbringer [this message]

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='000901d65b2c$515211f0$f3f635d0$@gmail.com' \
    --to=charley.ashbringer@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mcgrof@kernel.org \
    --cc=rdunlap@infradead.org \
    --cc=willy@infradead.org \
    --cc=yzaikin@google.com \
    /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.