m4-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

branch-1_4 allocation overflow


From: Eric Blake
Subject: branch-1_4 allocation overflow
Date: Wed, 25 Oct 2006 22:45:07 -0600
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.7) Gecko/20060909 Thunderbird/1.5.0.7 Mnenhy/0.7.4.666

-----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  <address@hidden>

        * 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             address@hidden
-----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-----
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
+
address@hidden We also need to test allocation overflow.  On 32-bit
address@hidden platforms, this should fail outright.  But on 64-bit platforms
address@hidden with enough memory, the allocation might succeed (hopefully
address@hidden testers don't mind the memory thrashing), so fake the same
address@hidden output for test success.
+
address@hidden
+divert(eval(`1<<28'))
+divert(`2')
+errprint(__program__`: memory exhausted
+')m4exit(`1')
address@hidden: memory exhausted
address@hidden 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++)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]