> I hate the startup file.
> Look, this is a use after free, but I can't find it...
> 
> #0  0x00001b9de0b1b77f in definemacro (f=0, n=1)
>     at /usr/src/usr.bin/mg/macro.c:43
> 43                              lp2 = lp1->l_fp;
> (gdb) p *maclhead
> $1 = {l_fp = 0xdfdfdfdfdfdfdfdf, l_bp = 0xdfdfdfdfdfdfdfdf, 
>   l_size = -538976289, l_used = -538976289, 
>   l_text = 0xdfdfdfdfdfdfdfdf <Address 0xdfdfdfdfdfdfdfdf out of bounds>}

seems that it is in excline(), look:

src/usr.bin/mg/extend.c:907
        lp = maclcur->l_fp;
        while (lp != maclcur) {
                np = lp->l_fp;
                free(lp);
                lp = np;
        }
        free(lp);
        return (status);

excline() loads .mg file and free(lp) lines afterwards. 

following diff add a cleanline check to make sure that the cleanup was already 
done or not.
avoid user after free in definemacro()/macro.c:45 in cases where excline() take 
care of the free lines cleanup. 

? mg
Index: extend.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/extend.c,v
retrieving revision 1.61
diff -u -p -u -p -r1.61 extend.c
--- extend.c    24 Mar 2015 22:28:10 -0000      1.61
+++ extend.c    11 Apr 2015 04:41:38 -0000
@@ -910,6 +910,7 @@ cleanup:
                free(lp);
                lp = np;
        }
+       cleanline = 1;
        free(lp);
        return (status);
 }
Index: macro.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/macro.c,v
retrieving revision 1.16
diff -u -p -u -p -r1.16 macro.c
--- macro.c     19 Mar 2015 21:22:15 -0000      1.16
+++ macro.c     11 Apr 2015 04:41:38 -0000
@@ -15,6 +15,7 @@
 #include "key.h"
 #include "macro.h"
 
+int cleanline = 0;
 int inmacro = FALSE;   /* Macro playback in progess */
 int macrodef = FALSE;  /* Macro recording in progress */
 int macrocount = 0;
@@ -38,7 +39,7 @@ definemacro(int f, int n)
        }
 
        /* free lines allocated for string arguments */
-       if (maclhead != NULL) {
+       if (!cleanline && maclhead != NULL) {
                for (lp1 = maclhead->l_fp; lp1 != maclhead; lp1 = lp2) {
                        lp2 = lp1->l_fp;
                        free(lp1);
Index: macro.h
===================================================================
RCS file: /cvs/src/usr.bin/mg/macro.h,v
retrieving revision 1.7
diff -u -p -u -p -r1.7 macro.h
--- macro.h     18 Nov 2005 20:56:53 -0000      1.7
+++ macro.h     11 Apr 2015 04:41:38 -0000
@@ -6,6 +6,7 @@
 
 #define MAXMACRO 256           /* maximum functs in a macro */
 
+extern int cleanline;
 extern int inmacro;
 extern int macrodef;
 extern int macrocount;

Reply via email to