dcavalca / rpms / grub2

Forked from rpms/grub2 3 years ago
Clone

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

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