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