495677c
From 840031ac0f74c51622490bb72e6671f7e35b95ff Mon Sep 17 00:00:00 2001
495677c
Message-Id: <840031ac0f74c51622490bb72e6671f7e35b95ff.1349642201.git.crobinso@redhat.com>
495677c
From: Ian Campbell <ian.campbell@citrix.com>
495677c
Date: Tue, 4 Sep 2012 10:26:09 -0500
495677c
Subject: [PATCH] console: bounds check whenever changing the cursor due to an
495677c
 escape code
495677c
MIME-Version: 1.0
495677c
Content-Type: text/plain; charset=UTF-8
495677c
Content-Transfer-Encoding: 8bit
495677c
495677c
This is XSA-17 / CVE-2012-3515
495677c
495677c
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
495677c
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
495677c
(cherry picked from commit 3eea5498ca501922520b3447ba94815bfc109743)
495677c
495677c
[AF: Resolves BNC#777084]
495677c
Signed-off-by: Andreas Färber <afaerber@suse.de>
495677c
Signed-off-by: Cole Robinson <crobinso@redhat.com>
495677c
---
495677c
 console.c | 57 ++++++++++++++++++++++++++++-----------------------------
495677c
 1 file changed, 28 insertions(+), 29 deletions(-)
495677c
495677c
diff --git a/console.c b/console.c
495677c
index 07c82b8..f9eb5a1 100644
495677c
--- a/console.c
495677c
+++ b/console.c
495677c
@@ -833,6 +833,26 @@ static void console_clear_xy(TextConsole *s, int x, int y)
495677c
     update_xy(s, x, y);
495677c
 }
495677c
 
495677c
+/* set cursor, checking bounds */
495677c
+static void set_cursor(TextConsole *s, int x, int y)
495677c
+{
495677c
+    if (x < 0) {
495677c
+        x = 0;
495677c
+    }
495677c
+    if (y < 0) {
495677c
+        y = 0;
495677c
+    }
495677c
+    if (y >= s->height) {
495677c
+        y = s->height - 1;
495677c
+    }
495677c
+    if (x >= s->width) {
495677c
+        x = s->width - 1;
495677c
+    }
495677c
+
495677c
+    s->x = x;
495677c
+    s->y = y;
495677c
+}
495677c
+
495677c
 static void console_putchar(TextConsole *s, int ch)
495677c
 {
495677c
     TextCell *c;
495677c
@@ -904,7 +924,8 @@ static void console_putchar(TextConsole *s, int ch)
495677c
                     s->esc_params[s->nb_esc_params] * 10 + ch - '0';
495677c
             }
495677c
         } else {
495677c
-            s->nb_esc_params++;
495677c
+            if (s->nb_esc_params < MAX_ESC_PARAMS)
495677c
+                s->nb_esc_params++;
495677c
             if (ch == ';')
495677c
                 break;
495677c
 #ifdef DEBUG_CONSOLE
495677c
@@ -918,59 +939,37 @@ static void console_putchar(TextConsole *s, int ch)
495677c
                 if (s->esc_params[0] == 0) {
495677c
                     s->esc_params[0] = 1;
495677c
                 }
495677c
-                s->y -= s->esc_params[0];
495677c
-                if (s->y < 0) {
495677c
-                    s->y = 0;
495677c
-                }
495677c
+                set_cursor(s, s->x, s->y - s->esc_params[0]);
495677c
                 break;
495677c
             case 'B':
495677c
                 /* move cursor down */
495677c
                 if (s->esc_params[0] == 0) {
495677c
                     s->esc_params[0] = 1;
495677c
                 }
495677c
-                s->y += s->esc_params[0];
495677c
-                if (s->y >= s->height) {
495677c
-                    s->y = s->height - 1;
495677c
-                }
495677c
+                set_cursor(s, s->x, s->y + s->esc_params[0]);
495677c
                 break;
495677c
             case 'C':
495677c
                 /* move cursor right */
495677c
                 if (s->esc_params[0] == 0) {
495677c
                     s->esc_params[0] = 1;
495677c
                 }
495677c
-                s->x += s->esc_params[0];
495677c
-                if (s->x >= s->width) {
495677c
-                    s->x = s->width - 1;
495677c
-                }
495677c
+                set_cursor(s, s->x + s->esc_params[0], s->y);
495677c
                 break;
495677c
             case 'D':
495677c
                 /* move cursor left */
495677c
                 if (s->esc_params[0] == 0) {
495677c
                     s->esc_params[0] = 1;
495677c
                 }
495677c
-                s->x -= s->esc_params[0];
495677c
-                if (s->x < 0) {
495677c
-                    s->x = 0;
495677c
-                }
495677c
+                set_cursor(s, s->x - s->esc_params[0], s->y);
495677c
                 break;
495677c
             case 'G':
495677c
                 /* move cursor to column */
495677c
-                s->x = s->esc_params[0] - 1;
495677c
-                if (s->x < 0) {
495677c
-                    s->x = 0;
495677c
-                }
495677c
+                set_cursor(s, s->esc_params[0] - 1, s->y);
495677c
                 break;
495677c
             case 'f':
495677c
             case 'H':
495677c
                 /* move cursor to row, column */
495677c
-                s->x = s->esc_params[1] - 1;
495677c
-                if (s->x < 0) {
495677c
-                    s->x = 0;
495677c
-                }
495677c
-                s->y = s->esc_params[0] - 1;
495677c
-                if (s->y < 0) {
495677c
-                    s->y = 0;
495677c
-                }
495677c
+                set_cursor(s, s->esc_params[1] - 1, s->esc_params[0] - 1);
495677c
                 break;
495677c
             case 'J':
495677c
                 switch (s->esc_params[0]) {
495677c
-- 
495677c
1.7.11.4
495677c