]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 18 Feb 2013 17:55:37 +0000 (09:55 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 18 Feb 2013 17:55:37 +0000 (09:55 -0800)
added patches:
printk-fix-buffer-overflow-when-calling-log_prefix-function-from-call_console_drivers.patch

queue-3.4/printk-fix-buffer-overflow-when-calling-log_prefix-function-from-call_console_drivers.patch [new file with mode: 0644]
queue-3.4/series [new file with mode: 0644]

diff --git a/queue-3.4/printk-fix-buffer-overflow-when-calling-log_prefix-function-from-call_console_drivers.patch b/queue-3.4/printk-fix-buffer-overflow-when-calling-log_prefix-function-from-call_console_drivers.patch
new file mode 100644 (file)
index 0000000..2be3e80
--- /dev/null
@@ -0,0 +1,83 @@
+From Alexandre.Simon@univ-lorraine.fr  Mon Feb 18 09:52:16 2013
+From: Alexandre SIMON <Alexandre.Simon@univ-lorraine.fr>
+Date: Fri, 01 Feb 2013 15:31:54 +0100
+Subject: printk: fix buffer overflow when calling log_prefix function from call_console_drivers
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, stable@vger.kernel.org
+Cc: "Serge E. Hallyn" <serge@hallyn.com>, Jonathan Nieder <jrnieder@gmail.com>, James Morris <jmorris@namei.org>
+Message-ID: <510BD1DA.4010709@univ-lorraine.fr>
+
+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.
+
+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.
+
+Signed-off-by: Alexandre SIMON <Alexandre.Simon@univ-lorraine.fr>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/syslog.h |    6 ++++++
+ kernel/printk.c        |   13 ++++++++++++-
+ 2 files changed, 18 insertions(+), 1 deletion(-)
+
+--- a/include/linux/syslog.h
++++ b/include/linux/syslog.h
+@@ -47,6 +47,12 @@
+ #define SYSLOG_FROM_CALL 0
+ #define SYSLOG_FROM_FILE 1
++/*
++ * Syslog priority (PRI) maximum length in char : '<[0-9]{1,3}>'
++ * See RFC5424 for details
++*/
++#define SYSLOG_PRI_MAX_LENGTH 5
++
+ int do_syslog(int type, char __user *buf, int count, bool from_file);
+ #endif /* _LINUX_SYSLOG_H */
+--- 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++) {
++                              buf_prefix[i] = LOG_BUF(cur_index + i);
++                      }
++                      buf_prefix[i] = '\0'; /* force '\0' as last string character */
++
+                       /* strip log prefix */
+-                      cur_index += log_prefix(&LOG_BUF(cur_index), &msg_level, NULL);
++                      cur_index += log_prefix((const char *)&buf_prefix, &msg_level, NULL);
+                       start_print = cur_index;
+               }
+               while (cur_index != end) {
diff --git a/queue-3.4/series b/queue-3.4/series
new file mode 100644 (file)
index 0000000..097bb82
--- /dev/null
@@ -0,0 +1 @@
+printk-fix-buffer-overflow-when-calling-log_prefix-function-from-call_console_drivers.patch