dcavalca / rpms / grub2

Forked from rpms/grub2 3 years ago
Clone

Blame SOURCES/0281-yylex-Make-lexer-fatal-errors-actually-be-fatal.patch

5975ab
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
a4d572
From: Peter Jones <pjones@redhat.com>
a4d572
Date: Wed, 15 Apr 2020 15:45:02 -0400
5975ab
Subject: [PATCH] yylex: Make lexer fatal errors actually be fatal
a4d572
a4d572
When presented with a command that can't be tokenized to anything
a4d572
smaller than YYLMAX characters, the parser calls YY_FATAL_ERROR(errmsg),
a4d572
expecting that will stop further processing, as such:
a4d572
a4d572
  #define YY_DO_BEFORE_ACTION \
a4d572
        yyg->yytext_ptr = yy_bp; \
a4d572
        yyleng = (int) (yy_cp - yy_bp); \
a4d572
        yyg->yy_hold_char = *yy_cp; \
a4d572
        *yy_cp = '\0'; \
a4d572
        if ( yyleng >= YYLMAX ) \
a4d572
                YY_FATAL_ERROR( "token too large, exceeds YYLMAX" ); \
a4d572
        yy_flex_strncpy( yytext, yyg->yytext_ptr, yyleng + 1 , yyscanner); \
a4d572
        yyg->yy_c_buf_p = yy_cp;
a4d572
a4d572
The code flex generates expects that YY_FATAL_ERROR() will either return
a4d572
for it or do some form of longjmp(), or handle the error in some way at
a4d572
least, and so the strncpy() call isn't in an "else" clause, and thus if
a4d572
YY_FATAL_ERROR() is *not* actually fatal, it does the call with the
a4d572
questionable limit, and predictable results ensue.
a4d572
a4d572
Unfortunately, our implementation of YY_FATAL_ERROR() is:
a4d572
a4d572
   #define YY_FATAL_ERROR(msg)                     \
a4d572
     do {                                          \
a4d572
       grub_printf (_("fatal error: %s\n"), _(msg));     \
a4d572
     } while (0)
a4d572
a4d572
The same pattern exists in yyless(), and similar problems exist in users
a4d572
of YY_INPUT(), several places in the main parsing loop,
a4d572
yy_get_next_buffer(), yy_load_buffer_state(), yyensure_buffer_stack,
a4d572
yy_scan_buffer(), etc.
a4d572
a4d572
All of these callers expect YY_FATAL_ERROR() to actually be fatal, and
a4d572
the things they do if it returns after calling it are wildly unsafe.
a4d572
a4d572
Fixes: CVE-2020-10713
a4d572
a4d572
Signed-off-by: Peter Jones <pjones@redhat.com>
a4d572
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
a4d572
Upstream-commit-id: 926df817dc8
a4d572
---
a4d572
 grub-core/script/yylex.l | 4 ++--
a4d572
 1 file changed, 2 insertions(+), 2 deletions(-)
a4d572
a4d572
diff --git a/grub-core/script/yylex.l b/grub-core/script/yylex.l
a4d572
index 7b44c37b76f..b7203c82309 100644
a4d572
--- a/grub-core/script/yylex.l
a4d572
+++ b/grub-core/script/yylex.l
a4d572
@@ -37,11 +37,11 @@
a4d572
 
a4d572
 /* 
a4d572
  * As we don't have access to yyscanner, we cannot do much except to
a4d572
- * print the fatal error.
a4d572
+ * print the fatal error and exit.
a4d572
  */
a4d572
 #define YY_FATAL_ERROR(msg)                     \
a4d572
   do {                                          \
a4d572
-    grub_printf (_("fatal error: %s\n"), _(msg));     \
a4d572
+    grub_fatal (_("fatal error: %s\n"), _(msg));\
a4d572
   } while (0)
a4d572
 
a4d572
 #define COPY(str, hint)                         \