[binutils-gdb] buffer overflow in gas/app.c

Alan Modra amodra@sourceware.org
Wed Dec 25 22:57:03 GMT 2024


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=578c704c8eb0f376315056bde431c4403facd5e5

commit 578c704c8eb0f376315056bde431c4403facd5e5
Author: Alan Modra <amodra@gmail.com>
Date:   Wed Dec 25 19:17:24 2024 +1030

    buffer overflow in gas/app.c
    
    This testcase:
     .irp x x x "
     .end #
     .endr
    manages to access lex[EOF].
    
    xxx: Warning: end of file in string; '"' inserted
    xxx:1: Warning: missing closing `"'
    gas/app.c:844:16: runtime error: index -1 out of bounds for type 'char [256]
    Following that there is a buffer overflow.
    
    Stop this happening, and in other similar places, by checking for EOF.

Diff:
---
 gas/app.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/gas/app.c b/gas/app.c
index 8dc69ff4ce0..20b41209f94 100644
--- a/gas/app.c
+++ b/gas/app.c
@@ -820,7 +820,9 @@ do_scrub_chars (size_t (*get) (char *, size_t), char *tostart, size_t tolen,
 
       /* We need to watch out for .end directives: We should in particular not
 	 issue diagnostics for anything after an active one.  */
-      if (end_state == NULL)
+      if (ch == EOF)
+	end_state = NULL;
+      else if (end_state == NULL)
 	{
 	  if ((state == 0 || state == 1)
 	      && (ch == '.'
@@ -858,7 +860,9 @@ do_scrub_chars (size_t (*get) (char *, size_t), char *tostart, size_t tolen,
 #if defined TC_ARM && defined OBJ_ELF
       /* We need to watch out for .symver directives.  See the comment later
 	 in this function.  */
-      if (symver_state == NULL)
+      if (ch == EOF)
+	symver_state = NULL;
+      else if (symver_state == NULL)
 	{
 	  if ((state == 0 || state == 1)
 	      && strchr (tc_comment_chars, '@') != NULL
@@ -891,7 +895,9 @@ do_scrub_chars (size_t (*get) (char *, size_t), char *tostart, size_t tolen,
 	 MRI mode or not.  Unfortunately, since m68k MRI mode affects
 	 the scrubber, that means that we need a special purpose
 	 recognizer here.  */
-      if (mri_state == NULL)
+      if (ch == EOF)
+	mri_state = NULL;
+      else if (mri_state == NULL)
 	{
 	  if ((state == 0 || state == 1)
 	      && ch == mri_pseudo[0])
@@ -927,7 +933,7 @@ do_scrub_chars (size_t (*get) (char *, size_t), char *tostart, size_t tolen,
 	    }
 	  else
 	    {
-	      /* We've read the entire pseudo-op.  mips_last_ch is
+	      /* We've read the entire pseudo-op.  mri_last_ch is
 		 either '0' or '1' indicating whether to enter or
 		 leave MRI mode.  */
 	      do_scrub_begin (mri_last_ch == '1');


More information about the Binutils-cvs mailing list