dcavalca / rpms / grub2

Forked from rpms/grub2 3 years ago
Clone
5975ab
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
a4d572
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
a4d572
Date: Tue, 7 Jul 2020 15:12:25 -0400
5975ab
Subject: [PATCH] term: Fix overflow on user inputs
a4d572
a4d572
This requires a very weird input from the serial interface but can cause
a4d572
an overflow in input_buf (keys) overwriting the next variable (npending)
a4d572
with the user choice:
a4d572
a4d572
(pahole output)
a4d572
a4d572
struct grub_terminfo_input_state {
a4d572
        int                        input_buf[6];         /*     0    24 */
a4d572
        int                        npending;             /*    24     4 */ <- CORRUPT
a4d572
        ...snip...
a4d572
a4d572
The magic string requires causing this is "ESC,O,],0,1,2,q" and we overflow
a4d572
npending with "q" (aka increase npending to 161). The simplest fix is to
a4d572
just to disallow overwrites input_buf, which exactly what this patch does.
a4d572
a4d572
Fixes: CID 292449
a4d572
a4d572
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
a4d572
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
a4d572
Upstream-commit-id: 98dfa546777
a4d572
---
a4d572
 grub-core/term/terminfo.c | 9 ++++++---
a4d572
 1 file changed, 6 insertions(+), 3 deletions(-)
a4d572
a4d572
diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c
a4d572
index 537a5c0cb0b..44d0b3b19fb 100644
a4d572
--- a/grub-core/term/terminfo.c
a4d572
+++ b/grub-core/term/terminfo.c
a4d572
@@ -398,7 +398,7 @@ grub_terminfo_getwh (struct grub_term_output *term)
a4d572
 }
a4d572
 
a4d572
 static void
a4d572
-grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len,
a4d572
+grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, int max_len,
a4d572
 		       int (*readkey) (struct grub_term_input *term))
a4d572
 {
a4d572
   int c;
a4d572
@@ -414,6 +414,9 @@ grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len,
a4d572
     if (c == -1)						\
a4d572
       return;							\
a4d572
 								\
a4d572
+    if (*len >= max_len)                                       \
a4d572
+      return;                                                   \
a4d572
+                                                                \
a4d572
     keys[*len] = c;						\
a4d572
     (*len)++;							\
a4d572
   }
a4d572
@@ -602,8 +605,8 @@ grub_terminfo_getkey (struct grub_term_input *termi)
a4d572
       return ret;
a4d572
     }
a4d572
 
a4d572
-  grub_terminfo_readkey (termi, data->input_buf,
a4d572
-			 &data->npending, data->readkey);
a4d572
+  grub_terminfo_readkey (termi, data->input_buf, &data->npending,
a4d572
+			 GRUB_TERMINFO_READKEY_MAX_LEN, data->readkey);
a4d572
 
a4d572
 #if defined(__powerpc__) && defined(GRUB_MACHINE_IEEE1275)
a4d572
   if (data->npending == 1 && data->input_buf[0] == GRUB_TERM_ESC