xref: /OK3568_Linux_fs/buildroot/boot/grub2/0012-term-Fix-overflow-on-user-inputs.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1From 8d3b6f9da468f666e3a7976657f2ab5c52762a21 Mon Sep 17 00:00:00 2001
2From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
3Date: Tue, 7 Jul 2020 15:12:25 -0400
4Subject: [PATCH] term: Fix overflow on user inputs
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9This requires a very weird input from the serial interface but can cause
10an overflow in input_buf (keys) overwriting the next variable (npending)
11with the user choice:
12
13(pahole output)
14
15struct grub_terminfo_input_state {
16        int                        input_buf[6];         /*     0    24 */
17        int                        npending;             /*    24     4 */ <- CORRUPT
18        ...snip...
19
20The magic string requires causing this is "ESC,O,],0,1,2,q" and we overflow
21npending with "q" (aka increase npending to 161). The simplest fix is to
22just to disallow overwrites input_buf, which exactly what this patch does.
23
24Fixes: CID 292449
25
26Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
27Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
28Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
29---
30 grub-core/term/terminfo.c | 9 ++++++---
31 1 file changed, 6 insertions(+), 3 deletions(-)
32
33diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c
34index d317efa36..5fa94c0c3 100644
35--- a/grub-core/term/terminfo.c
36+++ b/grub-core/term/terminfo.c
37@@ -398,7 +398,7 @@ grub_terminfo_getwh (struct grub_term_output *term)
38 }
39
40 static void
41-grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len,
42+grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, int max_len,
43 		       int (*readkey) (struct grub_term_input *term))
44 {
45   int c;
46@@ -414,6 +414,9 @@ grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len,
47     if (c == -1)						\
48       return;							\
49 								\
50+    if (*len >= max_len)                                       \
51+      return;                                                   \
52+                                                                \
53     keys[*len] = c;						\
54     (*len)++;							\
55   }
56@@ -602,8 +605,8 @@ grub_terminfo_getkey (struct grub_term_input *termi)
57       return ret;
58     }
59
60-  grub_terminfo_readkey (termi, data->input_buf,
61-			 &data->npending, data->readkey);
62+  grub_terminfo_readkey (termi, data->input_buf, &data->npending,
63+			 GRUB_TERMINFO_READKEY_MAX_LEN, data->readkey);
64
65 #if defined(__powerpc__) && defined(GRUB_MACHINE_IEEE1275)
66   if (data->npending == 1 && data->input_buf[0] == GRUB_TERM_ESC
67--
682.26.2
69
70