All of lore.kernel.org
 help / color / mirror / Atom feed
From: Satoru Takeuchi <satoru.takeuchi@gmail.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-kernel@vger.kernel.org, stable@vger.kernel.org,
	Alexandre SIMON <Alexandre.Simon@univ-lorraine.fr>
Subject: Re: [ 1/1] printk: fix buffer overflow when calling log_prefix function from call_console_drivers
Date: Wed, 20 Feb 2013 22:02:13 +0900	[thread overview]
Message-ID: <87ip5njfze.wl%satoru.takeuchi@gmail.com> (raw)
In-Reply-To: <20130218181454.976143076@linuxfoundation.org>

Hi Alexandre,

At Mon, 18 Feb 2013 10:24:56 -0800,
Greg Kroah-Hartman wrote:
> 
> 3.4-stable review patch.  If anyone has any objections, please let me know.
> 
> ------------------
> 
> From: Alexandre SIMON <Alexandre.Simon@univ-lorraine.fr>
> 
> This patch corrects a buffer overflow in kernels from 3.0 to 3.4 when calling
> log_prefix() function from call_console_drivers().
> 
> This bug existed in previous releases but has been revealed with commit
> 162a7e7500f9664636e649ba59defe541b7c2c60 (2.6.39 => 3.0) that made changes
> about how to allocate memory for early printk buffer (use of memblock_alloc).
> It disappears with commit 7ff9554bb578ba02166071d2d487b7fc7d860d62 (3.4 => 3.5)
> that does a refactoring of printk buffer management.
> 
> In log_prefix(), the access to "p[0]", "p[1]", "p[2]" or
> "simple_strtoul(&p[1], &endp, 10)" may cause a buffer overflow as this
> function is called from call_console_drivers by passing "&LOG_BUF(cur_index)"
> where the index must be masked to do not exceed the buffer's boundary.

I reviewed this patch and it seems to be good for me. Since I'm not good at
printk code, I want to confirm whether what I think is correct or not.
Is the following my understanding correct?

> -			cur_index += log_prefix(&LOG_BUF(cur_index), &msg_level, NULL);

Here is one example of the problematic case.

  +---- start of log_buf
  |
  |                           +--- end of log_buf
  |                           |
  v                           v
  <-------- log_buf ----------><------- * outside of log_buf. Don't access here !!! * --- ~~~
                              ^
                              |
                              cur_index

In this case, only LOG_BUF(cur_index) is safe to access and

 - "LOG_BUF(cur_index) + 1" as p[1],
 - "LOG_BUF(cur_index) + 2" as p[2], and
 - "LOG_BUF(cur_index) + 1 or more" as simple_strtoul(&p[1], &endp, 10)

in log_prefix() are not to do so. Hence touching them would cause the system hang as you
said as follows.

> 
> The trick is to prepare in call_console_drivers() a buffer with the necessary
> data (PRI field of syslog message) to be safely evaluated in log_prefix().
> 
> This patch can be applied to stable kernel branches 3.0.y, 3.2.y and 3.4.y.
> 
> Without this patch, one can freeze a server running this loop from shell :
>   $ export DUMMY=`cat /dev/urandom | tr -dc '12345AZERTYUIOPQSDFGHJKLMWXCVBNazertyuiopqsdfghjklmwxcvbn' | head -c255`
>   $ while true do ; echo $DUMMY > /dev/kmsg ; done
> 
> The "server freeze" depends on where memblock_alloc does allocate printk buffer :
> if the buffer overflow is inside another kernel allocation the problem may not
> be revealed, else the server may hangs up.
...
> --- a/kernel/printk.c
> +++ b/kernel/printk.c
> @@ -638,8 +638,19 @@ static void call_console_drivers(unsigne
>  	start_print = start;
>  	while (cur_index != end) {
>  		if (msg_level < 0 && ((end - cur_index) > 2)) {
> +			/*
> +			 * prepare buf_prefix, as a contiguous array,
> +			 * to be processed by log_prefix function
> +			 */
> +			char buf_prefix[SYSLOG_PRI_MAX_LENGTH+1];
> +			unsigned i;
> +			for (i = 0; i < ((end - cur_index)) && (i < SYSLOG_PRI_MAX_LENGTH); i++) {

The condition, "i < ((end - cur_index)) && (i < SYSLOG_PRI_MAX_LENGTH)", is to prevent
access over

 - the region to write out, and
 - the max length of log_prefix.

In addition, "min(end - cur_index, SYSLOG_PRI_MAX_LENGTH)" has the same meaning here.

> +				buf_prefix[i] = LOG_BUF(cur_index + i);

You ensure that all characters (not only first character) in the candidate of log_prefix
are inside of log_buf here by copying each character of them one by one.

Thanks,
Satoru

  reply	other threads:[~2013-02-20 13:02 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-02-18 18:24 [ 0/1] 3.4.33-stable review Greg Kroah-Hartman
2013-02-18 18:24 ` [ 1/1] printk: fix buffer overflow when calling log_prefix function from call_console_drivers Greg Kroah-Hartman
2013-02-20 13:02   ` Satoru Takeuchi [this message]
2013-02-20 13:43     ` Alexandre SIMON
2013-02-20 15:56       ` Satoru Takeuchi
2013-02-19  2:50 ` [ 0/1] 3.4.33-stable review Shuah Khan
2013-02-20  2:51   ` Greg Kroah-Hartman
2013-02-20  3:31     ` Shuah Khan
2013-02-20 13:09       ` Satoru Takeuchi
  -- strict thread matches above, loose matches on Subject: below --
2013-02-18 18:25 [ 0/1] 3.0.66-stable review Greg Kroah-Hartman
2013-02-18 18:25 ` [ 1/1] printk: fix buffer overflow when calling log_prefix function from call_console_drivers Greg Kroah-Hartman

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=87ip5njfze.wl%satoru.takeuchi@gmail.com \
    --to=satoru.takeuchi@gmail.com \
    --cc=Alexandre.Simon@univ-lorraine.fr \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /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.