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