branch-1_4 allocation overflow

Eric Blake <[email protected]>
Newsgroups gmane.comp.gnu.m4.patches
Message-ID <[email protected]>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

$ m4
divert(eval(1<<28))

hi
hi
Hangup
$ echo $?
129

Whoops.  This wrapped around to a 0-size allocation, diverted output to
the wrong location, and crashed on exit, rather than properly failing (at
least on my machine, with 32-bit size_t, and less than 2 GB of memory)
with a more appropriate memory exhausted.

On head, I wonder if it would be nicer to use a sorted list of active
diversions, rather than allocating such a sparse array, so that memory is
only allocated for used diversions.

I hope the testsuite addition is not too harsh on a 64-bit machine, since
it allocates several gigabytes of memory before exiting.  But I did
validate that on a 32-bit platform, I get a coredump pre-patch, and the
desired "memory exhausted" post-patch.

2006-10-25  Eric Blake  <[email protected]>

	* src/output.c (make_diversion): Avoid size_t overflow.
	* doc/m4.texinfo (Diversions): Test this fix.
	* src/input.c (input_block): Remove unused member.  Reduce size
	of struct.
	(push_file, pop_input): Avoid useless assignment.
	* NEWS: Document the bug fix.

- --
Life is short - so eat dessert first!

Eric Blake             [email protected]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.1 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFFQD1S84KuGfSFAYARAupfAKCOlI3LqKzPquM/Q7FG5RtkSh8BhgCg16yk
ug+2sxdZs/yHUFV0wolVajA=
=z1Sb
-----END PGP SIGNATURE-----

_______________________________________________
M4-patches mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/m4-patches
m4.patch198 (text/plain, 3.6 KB)
Index: NEWS
===================================================================
RCS file: /sources/m4/m4/NEWS,v
retrieving revision 1.1.1.1.2.74
diff -u -p -r1.1.1.1.2.74 NEWS
--- NEWS	21 Oct 2006 02:55:56 -0000	1.1.1.1.2.74
+++ NEWS	26 Oct 2006 04:40:23 -0000
@@ -4,6 +4,8 @@ Foundation, Inc.
 
 Version 1.4.8 - ?? ??? 2006, by ??  (CVS version 1.4.7a)
 
+* The `divert' macro no longer causes a core dump when handed extra large
+  values.
 * The `--help' and `--version' command line options now consistently
   override all earlier options.  For example, `m4 --debugfile=trace
   --help' now no longer accidentally creates an empty file `trace'.
Index: doc/m4.texinfo
===================================================================
RCS file: /sources/m4/m4/doc/m4.texinfo,v
retrieving revision 1.1.1.1.2.93
diff -u -p -r1.1.1.1.2.93 m4.texinfo
--- doc/m4.texinfo	25 Oct 2006 20:54:39 -0000	1.1.1.1.2.93
+++ doc/m4.texinfo	26 Oct 2006 04:40:24 -0000
@@ -3561,6 +3561,20 @@ divert(`1')
 f
 divert(`-1')undivert
 @end example
+
+@comment We also need to test allocation overflow.  On 32-bit
+@comment platforms, this should fail outright.  But on 64-bit platforms
+@comment with enough memory, the allocation might succeed (hopefully
+@comment testers don't mind the memory thrashing), so fake the same
+@comment output for test success.
+
+@example
+divert(eval(`1<<28'))
+divert(`2')
+errprint(__program__`: memory exhausted
+')m4exit(`1')
+@error{}m4: memory exhausted
+@end example
 @end ignore
 
 @c FIXME: need some explanation here why this is a useful feature, not
Index: src/input.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/input.c,v
retrieving revision 1.1.1.1.2.28
diff -u -p -r1.1.1.1.2.28 input.c
--- src/input.c	25 Oct 2006 20:54:39 -0000	1.1.1.1.2.28
+++ src/input.c	26 Oct 2006 04:40:24 -0000
@@ -87,10 +87,9 @@ struct input_block
       struct
 	{
 	  FILE *fp;		/* input file handle */
-	  boolean end;		/* true if peek has seen EOF */
-	  boolean close;	/* true if we should close file on pop */
-	  int out_line;		/* current output line of previous file */
-	  boolean advance_line;	/* start_of_input_line from next_char () */
+	  boolean end : 1;	/* true if peek has seen EOF */
+	  boolean close : 1;	/* true if we should close file on pop */
+	  boolean advance_line : 1; /* track previous start_of_input_line */
 	}
 	u_f;	/* INPUT_FILE */
       builtin_func *func;	/* pointer to macro's function */
@@ -198,7 +197,6 @@ push_file (FILE *fp, const char *title, 
   i->u.u_f.fp = fp;
   i->u.u_f.end = FALSE;
   i->u.u_f.close = close;
-  i->u.u_f.out_line = output_current_line;
   i->u.u_f.advance_line = start_of_input_line;
   output_current_line = -1;
 
@@ -354,7 +352,6 @@ pop_input (void)
 	  M4ERROR ((warning_status, errno, "error reading file"));
 	  retcode = EXIT_FAILURE;
 	}
-      output_current_line = isp->u.u_f.out_line;
       start_of_input_line = isp->u.u_f.advance_line;
       if (tmp == NULL)
 	{
Index: src/output.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/output.c,v
retrieving revision 1.1.1.1.2.11
diff -u -p -r1.1.1.1.2.11 output.c
--- src/output.c	13 Oct 2006 22:25:32 -0000	1.1.1.1.2.11
+++ src/output.c	26 Oct 2006 04:40:24 -0000
@@ -439,7 +439,7 @@ make_diversion (int divnum)
   if (divnum >= diversions)
     {
       diversion_table = (struct diversion *)
-	xrealloc (diversion_table, (divnum + 1) * sizeof (struct diversion));
+	xnrealloc (diversion_table, divnum + 1, sizeof (struct diversion));
       for (diversion = diversion_table + diversions;
 	   diversion <= diversion_table + divnum;
 	   diversion++)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.