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