1*4882a593SmuzhiyunFrom a7ab0cc98fa89a3d5098c29cbe44bcd24b0a6454 Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: Peter Jones <pjones@redhat.com>
3*4882a593SmuzhiyunDate: Wed, 15 Apr 2020 15:45:02 -0400
4*4882a593SmuzhiyunSubject: [PATCH] yylex: Make lexer fatal errors actually be fatal
5*4882a593SmuzhiyunMIME-Version: 1.0
6*4882a593SmuzhiyunContent-Type: text/plain; charset=UTF-8
7*4882a593SmuzhiyunContent-Transfer-Encoding: 8bit
8*4882a593Smuzhiyun
9*4882a593SmuzhiyunWhen presented with a command that can't be tokenized to anything
10*4882a593Smuzhiyunsmaller than YYLMAX characters, the parser calls YY_FATAL_ERROR(errmsg),
11*4882a593Smuzhiyunexpecting that will stop further processing, as such:
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun  #define YY_DO_BEFORE_ACTION \
14*4882a593Smuzhiyun        yyg->yytext_ptr = yy_bp; \
15*4882a593Smuzhiyun        yyleng = (int) (yy_cp - yy_bp); \
16*4882a593Smuzhiyun        yyg->yy_hold_char = *yy_cp; \
17*4882a593Smuzhiyun        *yy_cp = '\0'; \
18*4882a593Smuzhiyun        if ( yyleng >= YYLMAX ) \
19*4882a593Smuzhiyun                YY_FATAL_ERROR( "token too large, exceeds YYLMAX" ); \
20*4882a593Smuzhiyun        yy_flex_strncpy( yytext, yyg->yytext_ptr, yyleng + 1 , yyscanner); \
21*4882a593Smuzhiyun        yyg->yy_c_buf_p = yy_cp;
22*4882a593Smuzhiyun
23*4882a593SmuzhiyunThe code flex generates expects that YY_FATAL_ERROR() will either return
24*4882a593Smuzhiyunfor it or do some form of longjmp(), or handle the error in some way at
25*4882a593Smuzhiyunleast, and so the strncpy() call isn't in an "else" clause, and thus if
26*4882a593SmuzhiyunYY_FATAL_ERROR() is *not* actually fatal, it does the call with the
27*4882a593Smuzhiyunquestionable limit, and predictable results ensue.
28*4882a593Smuzhiyun
29*4882a593SmuzhiyunUnfortunately, our implementation of YY_FATAL_ERROR() is:
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun   #define YY_FATAL_ERROR(msg)                     \
32*4882a593Smuzhiyun     do {                                          \
33*4882a593Smuzhiyun       grub_printf (_("fatal error: %s\n"), _(msg));     \
34*4882a593Smuzhiyun     } while (0)
35*4882a593Smuzhiyun
36*4882a593SmuzhiyunThe same pattern exists in yyless(), and similar problems exist in users
37*4882a593Smuzhiyunof YY_INPUT(), several places in the main parsing loop,
38*4882a593Smuzhiyunyy_get_next_buffer(), yy_load_buffer_state(), yyensure_buffer_stack,
39*4882a593Smuzhiyunyy_scan_buffer(), etc.
40*4882a593Smuzhiyun
41*4882a593SmuzhiyunAll of these callers expect YY_FATAL_ERROR() to actually be fatal, and
42*4882a593Smuzhiyunthe things they do if it returns after calling it are wildly unsafe.
43*4882a593Smuzhiyun
44*4882a593SmuzhiyunFixes: CVE-2020-10713
45*4882a593Smuzhiyun
46*4882a593SmuzhiyunSigned-off-by: Peter Jones <pjones@redhat.com>
47*4882a593SmuzhiyunReviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
48*4882a593SmuzhiyunSigned-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
49*4882a593Smuzhiyun---
50*4882a593Smuzhiyun grub-core/script/yylex.l | 4 ++--
51*4882a593Smuzhiyun 1 file changed, 2 insertions(+), 2 deletions(-)
52*4882a593Smuzhiyun
53*4882a593Smuzhiyundiff --git a/grub-core/script/yylex.l b/grub-core/script/yylex.l
54*4882a593Smuzhiyunindex 7b44c37b7..b7203c823 100644
55*4882a593Smuzhiyun--- a/grub-core/script/yylex.l
56*4882a593Smuzhiyun+++ b/grub-core/script/yylex.l
57*4882a593Smuzhiyun@@ -37,11 +37,11 @@
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun /*
60*4882a593Smuzhiyun  * As we don't have access to yyscanner, we cannot do much except to
61*4882a593Smuzhiyun- * print the fatal error.
62*4882a593Smuzhiyun+ * print the fatal error and exit.
63*4882a593Smuzhiyun  */
64*4882a593Smuzhiyun #define YY_FATAL_ERROR(msg)                     \
65*4882a593Smuzhiyun   do {                                          \
66*4882a593Smuzhiyun-    grub_printf (_("fatal error: %s\n"), _(msg));     \
67*4882a593Smuzhiyun+    grub_fatal (_("fatal error: %s\n"), _(msg));\
68*4882a593Smuzhiyun   } while (0)
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun #define COPY(str, hint)                         \
71*4882a593Smuzhiyun--
72*4882a593Smuzhiyun2.26.2
73*4882a593Smuzhiyun
74