Subject: lib/14975: regexec(3) memory leak
To: None <gnats-bugs@gnats.netbsd.org>
From: None <t-kouchi@mud.biglobe.ne.jp>
List: netbsd-bugs
Date: 12/16/2001 22:07:09
>Number:         14975
>Category:       lib
>Synopsis:       regexec(3) memory leak
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Dec 16 22:07:00 PST 2001
>Closed-Date:
>Last-Modified:
>Originator:     Takayoshi Kochi
>Release:        1.5.2
>Organization:
>Environment:
NetBSD vmnetbsd 1.5.2 NetBSD 1.5.2 (VMWARE) #6: Mon Oct 15 01:05:38 PDT 2001     kochi@vmnetbsd:/usr/src/sys/arch/i386/compile/VMWARE i386

>Description:
I'm hit by a memory leak problem in regexec(3) on 1.5 and very
recent 1.5-current.

This case is easily repeatable by attached program.
If you give it a regular expression (e.g. '^[a-z]+'), the program
searches the pattern against the same string forever.
In special case, when I give it '\(.\)\1\1\1' (any 4 sequential
characters), its size will be increasing to its limit (which
can be monitord by top(1)).
But strangely, when I give '\(.\)\1\1' (any 3 sequential characters)
the problem won't occur.

>How-To-Repeat:
run this program with argument '\(.\)\1\1\1'.

----------------
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <regex.h>

main(int argc, char *argv[])
{
        int c, ret, cflags;
        regex_t re;
        char buf[BUFSIZ];

        cflags = REG_ICASE;

        while(1) {
                ret = regcomp(&re, argv[1], cflags);
                if (ret) {
                        regerror(ret, &re, buf, BUFSIZ);
                        fprintf(stderr, "%s\n", buf);
                        regfree(&re);
                        exit(1);
                }
                ret = regexec(&re, "bbbddeeefffefjaidf", 0, 0, 0);
                regfree(&re);
        }
}

>Fix:
enami-san gave me a quick patch for this problem.
It seems that my problem is fixed with this patch.
------------

Date: Mon, 10 Dec 2001 15:23:18 +0900 (JST)
Message-Id: <200112100623.PAA03524@decoy.but-b.or.jp>

At a first glance, following free()s are missing.

enami.
Index: engine.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/regex/engine.c,v
retrieving revision 1.12
diff -u -r1.12 engine.c
--- engine.c	1999/09/16 11:45:20	1.12
+++ engine.c	2001/12/10 06:17:25
@@ -202,6 +202,10 @@
 	for (;;) {
 		endp = fast(m, start, stop, gf, gl);
 		if (endp == NULL) {		/* a miss */
+			if (m->pmatch != NULL)
+				free(m->pmatch);
+			if (m->lastpos != NULL)
+				free(m->lastpos);
 			STATETEARDOWN(m);
 			return(REG_NOMATCH);
 		}

>Release-Note:
>Audit-Trail:
>Unformatted: