Patchwork [Fortran] PR55475 - fix invalid reads with show_locus

login
register
mail settings
Submitter Tobias Burnus
Date Nov. 26, 2012, 10:28 p.m.
Message ID <50B3ECFC.5040406@net-b.de>
Download mbox | patch
Permalink /patch/202039/
State New
Headers show

Comments

Tobias Burnus - Nov. 26, 2012, 10:28 p.m.
As found with -fsanitize=address by HJ, but it also shows up with 
valgrind. The fix for the PR is the change in scanner.c; I think the 
patch is rather obvious.

The change in error.c is due to:

   if (c1 == c2)
     c2 += 1;

which could lead to an out-of-bounds condition is "c1" is already at the 
last character - then one exceeds the bound for c2.

Build and tested on x86-64-linux with no new failures.*
OK for the trunk?

Tobias

* I get: FAIL for gfortran.dg/lto/pr45586, 
gfortran.dg/realloc_on_assign_5.f03 and gfortran.dg/reassoc_4.f and 
XPASS for gfortran.dg/do_1.f90.
Tobias Burnus - Dec. 3, 2012, 8:57 a.m.
I have now committed that patch as obvious, Rev. 194076.

http://gcc.gnu.org/ml/fortran/2012-11/msg00084.html

Tobias

Tobias Burnus wrote:
> As found with -fsanitize=address by HJ, but it also shows up with 
> valgrind. The fix for the PR is the change in scanner.c; I think the 
> patch is rather obvious.
>
> The change in error.c is due to:
>
>   if (c1 == c2)
>     c2 += 1;
>
> which could lead to an out-of-bounds condition is "c1" is already at 
> the last character - then one exceeds the bound for c2.
>
> Build and tested on x86-64-linux with no new failures.*
> OK for the trunk?
>
> Tobias
>
> * I get: FAIL for gfortran.dg/lto/pr45586, 
> gfortran.dg/realloc_on_assign_5.f03 and gfortran.dg/reassoc_4.f and 
> XPASS for gfortran.dg/do_1.f90.

Patch

2012-11-26  Tobias Burnus  <burnus@net-b.de>

	PR fortran/55475
	* scanner.c (gfc_next_char_literal): Fix setting locus
	to free_line_length for the error message.
	* error.c (show_locus): Fix potential out-of-bounds
	read.

diff --git a/gcc/fortran/error.c b/gcc/fortran/error.c
index 4b06156..611540c 100644
--- a/gcc/fortran/error.c
+++ b/gcc/fortran/error.c
@@ -387,7 +387,7 @@  show_locus (locus *loc, int c1, int c2)
   cmax -= offset;
 
   p = &(lb->line[offset]);
-  for (i = 0; i <= cmax; i++)
+  for (i = 0; i < cmax; i++)
     {
       int spaces, j;
       spaces = gfc_widechar_display_length (*p++);
@@ -401,6 +401,11 @@  show_locus (locus *loc, int c1, int c2)
 	error_char (' ');
     }
 
+  if (i == c1)
+    error_char ('1');
+  else if (i == c2)
+    error_char ('2');
+
   error_char ('\n');
 
 }
diff --git a/gcc/fortran/scanner.c b/gcc/fortran/scanner.c
index e0556a9..765c0f9 100644
--- a/gcc/fortran/scanner.c
+++ b/gcc/fortran/scanner.c
@@ -1068,10 +1068,12 @@  restart:
 	  && gfc_current_locus.lb->truncated)
 	{
 	  int maxlen = gfc_option.free_line_length;
+	  gfc_char_t *current_nextc = gfc_current_locus.nextc;
+
 	  gfc_current_locus.lb->truncated = 0;
-	  gfc_current_locus.nextc += maxlen;
+	  gfc_current_locus.nextc =  gfc_current_locus.lb->line + maxlen;
 	  gfc_warning_now ("Line truncated at %L", &gfc_current_locus);
-	  gfc_current_locus.nextc -= maxlen;
+	  gfc_current_locus.nextc = current_nextc;
 	}
 
       if (c != '&')