CVE-2020-24240 (published 2020-08-25T14:15Z)

GNU Bison before 3.7.1 has a use-after-free in _obstack_free in lib/obstack.c (called from gram_lex) when a '\\0' byte is encountered. NOTE: there is a risk only if Bison is used with untrusted input, and the observed bug happens to cause unsafe behavior with a specific compiler/architecture. The bug report was intended to show that a crash may occur in Bison itself, not that a crash may occur in code that is generated by Bison.

Severity: HIGH
CVSS v2 base score: 7.1 (AV:N/AC:M/Au:N/C:N/I:N/A:C)
CVSS v3 base score: 5.5, MEDIUM (CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-416
cwe_name: Use After Free
description: The product reuses or references memory after it has been freed. At some point afterward, the memory may be allocated again and saved in another pointer, while the original pointer references a location somewhere within the new allocation. Any operations using the original pointer are no longer valid because the memory "belongs" to the code that operates on the new pointer.
extended_description: 
             
             
             
			 
             
             
         
         

Fix information:
repo_url: https://github.com/akimd/bison
commit_details: repo_url: https://github.com/akimd/bison
author: Akim Demaille
author_date: 2020-07-28 18:51:30+02:00
msg: scanner: don't crash on strings containing a NUL byte

We crash if the input contains a string containing a NUL byte.
Reported by Suhwan Song.
https://lists.gnu.org/r/bug-bison/2020-07/msg00051.html

* src/flex-scanner.h (STRING_FREE): Avoid accidental use of
last_string.
* src/scan-gram.l: Don't call STRING_FREE without calling
STRING_FINISH first.
* tests/input.at (Invalid inputs): Check that case.
repository: repo_url: https://github.com/akimd/bison
repo_name: akimd/bison
description: GNU Bison
repo_language: C
owner: akimd
file_changes: filename: THANKS
change_type: ModificationType.MODIFY
diff: @@ -185,6 +185,7 @@ Simon Sobisch             simonsobisch@web.de
 Stefano Lattarini         stefano.lattarini@gmail.com
 Stephen Cameron           stephenmcameron@gmail.com
 Steve Murphy              murf@parsetree.com
+Suhwan Song               prada960808@gmail.com
 Sum Wu                    sum@geekhouse.org
 Théophile Ranquet         theophile.ranquet@gmail.com
 Thiru Ramakrishnan        thiru.ramakrishnan@gmail.com

programming_language: Batchfile
filename: flex-scanner.h
change_type: ModificationType.MODIFY
diff: @@ -112,7 +112,15 @@ static struct obstack obstack_for_string;
 # define STRING_1GROW(Char)                     \
   obstack_1grow (&obstack_for_string, Char)
 
-# define STRING_FREE()                                  \
+# ifdef NDEBUG
+#  define STRING_FREE()                                 \
   obstack_free (&obstack_for_string, last_string)
+# else
+#  define STRING_FREE()                                  \
+  do {                                                   \
+    obstack_free (&obstack_for_string, last_string);     \
+    last_string = NULL;                                  \
+  } while (0)
+#endif
 
 #endif

programming_language: C
filename: scan-gram.l
change_type: ModificationType.MODIFY
diff: @@ -403,6 +403,7 @@ eqopt    ({sp}=)?
 {
   \0         {
     complain (loc, complaint, _("invalid null character"));
+    STRING_FINISH ();
     STRING_FREE ();
     return GRAM_error;
   }
@@ -599,7 +600,6 @@ eqopt    ({sp}=)?
     STRING_FINISH ();
     BEGIN INITIAL;
     loc->start = token_start;
-    val->CHAR = last_string[0];
 
     if (last_string[0] == '\0')
       {
@@ -615,6 +615,7 @@ eqopt    ({sp}=)?
       }
     else
       {
+        val->CHAR = last_string[0];
         STRING_FREE ();
         return CHAR;
       }

programming_language: C
filename: input.at
change_type: ModificationType.MODIFY
diff: @@ -1,4 +1,4 @@
-# Checking the Bison scanner.                    -*- Autotest -*-
+# Checking the Bison reader.                    -*- Autotest -*-
 
 # Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc.
 
@@ -78,10 +78,13 @@ AT_CLEANUP
 ## Invalid inputs.  ##
 ## ---------------- ##
 
+# The truly bad guys no human would write, but easily uncovered by
+# fuzzers.
 AT_SETUP([Invalid inputs])
 
 AT_DATA([input.y],
 [[\000\001\002\377?
+"\000"
 %%
 ?
 default: 'a' }
@@ -92,16 +95,41 @@ default: 'a' }
 ]])
 AT_PERL_REQUIRE([[-pi -e 's/\\(\d{3})/chr(oct($1))/ge' input.y]])
 
-AT_BISON_CHECK([input.y], [1], [],
+AT_BISON_CHECK([-fcaret input.y], [1], [], [stderr])
+
+# Autotest's diffing, when there are NUL bytes, just reports "binary
+# files differ".  So don't leave NUL bytes.
+AT_PERL_CHECK([[-p -e 's{([\0\377])}{sprintf "\\x%02x", ord($1)}ge' stderr]], [],
 [[input.y:1.1-2: error: invalid characters: '\0\001\002\377?'
-input.y:3.1: error: invalid character: '?'
-input.y:4.14: error: invalid character: '}'
-input.y:5.1: error: invalid character: '%'
-input.y:5.2: error: invalid character: '&'
-input.y:6.1-17: error: invalid directive: '%a-does-not-exist'
-input.y:7.1: error: invalid character: '%'
-input.y:7.2: error: invalid character: '-'
-input.y:8.1-9.0: error: missing '%}' at end of file
+    1 | \x00\xff?
+      | ^~
+input.y:2.2: error: invalid null character
+    2 | "\x00"
+      |  ^
+input.y:4.1: error: invalid character: '?'
+    4 | ?
+      | ^
+input.y:5.14: error: invalid character: '}'
+    5 | default: 'a' }
+      |              ^
+input.y:6.1: error: invalid character: '%'
+    6 | %&
+      | ^
+input.y:6.2: error: invalid character: '&'
+    6 | %&
+      |  ^
+input.y:7.1-17: error: invalid directive: '%a-does-not-exist'
+    7 | %a-does-not-exist
+      | ^~~~~~~~~~~~~~~~~
+input.y:8.1: error: invalid character: '%'
+    8 | %-
+      | ^
+input.y:8.2: error: invalid character: '-'
+    8 | %-
+      |  ^
+input.y:9.1-10.0: error: missing '%}' at end of file
+    9 | %{
+      | ^~
 ]])
 
 AT_CLEANUP

programming_language: Perl