nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

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

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