dcavalca / rpms / grub2

Forked from rpms/grub2 3 years ago
Clone

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

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