Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Dec 2004 16:11:01 +0200 (EET)
From:      Diomidis Spinellis <dds@istlab.dmst.aueb.gr>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   bin/75656: libc/regexp leaks memory
Message-ID:  <200412301411.iBUEB12S019499@istlab.dmst.aueb.gr>
Resent-Message-ID: <200412301420.iBUEKMRT066311@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         75656
>Category:       bin
>Synopsis:       libc/regexp leaks memory
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Dec 30 14:20:22 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator:     Diomidis Spinellis
>Release:        FreeBSD 4.10-STABLE i386
>Organization:
AUEB
>Environment:
System: FreeBSD istlab.dmst.aueb.gr 4.10-STABLE FreeBSD 4.10-STABLE #23: Fri Oct 8 15:53:45 EEST 2004 dds@istlab.dmst.aueb.gr:/usr/obj/usr/src/sys/ISTLAB i386
>Description:
The C library regular expression code will leak memory
by not freeing in one case the m->pmatch and m->lastpos
pointers before freing the m block in engine.c:matcher
>How-To-Repeat:
While writing a chapter on memory management for the "Code Properties"
book, run the sed(1) Towers of Hanoi test case under Valgrind's memcheck
tool (http://valgrind.kde.org/tools.html):

$ echo ':abc: : :' | valgrind  --tool=memcheck --leak-check=yes ./sed -f TEST/hanoi.sed
==19363== Memcheck, a memory error detector for x86-linux.
==19363== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward.
==19363== Using valgrind-2.1.2.CVS, a program supervision framework for x86-linux.
==19363== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward.
==19363== For more details, rerun with: -v
==19363==
==19363== Warning: ignoring --pointercheck=yes, because i386_set_ldt failed (errno=45)
:abc:   :   :
:ab :c  :   :
:a  :c  :b  :
:a  :   :bc :
:   :a  :bc :
:c  :a  :b  :
:c  :ab :   :
:   :abc:   :
Done!  Try another, or end with ^D.
==19363==
==19363== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==19363== malloc/free: in use at exit: 54476 bytes in 435 blocks.
==19363== malloc/free: 746 allocs, 311 frees, 205173 bytes allocated.
==19363== For counts of detected errors, rerun with: -v
==19363== searching for pointers to 435 not-freed blocks.
==19363== checked 903192 bytes.
==19363==
==19363== 136 bytes in 17 blocks are definitely lost in loss record 8 of 22
==19363==    at 0x3C026659: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck.so)
==19363==    by 0x8054D9E: lmatcher (engine.c:285)
==19363==    by 0x8057918: regexec (regexec.c:180)
==19363==    by 0x804D1D6: regexec_e (process.c:535)
==19363==
==19363==
==19363== 296 bytes in 37 blocks are definitely lost in loss record 11 of 22
==19363==    at 0x3C026659: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck.so)
==19363==    by 0x8051E1A: smatcher (engine.c:285)
==19363==    by 0x80578F2: regexec (regexec.c:178)
==19363==    by 0x804D1D6: regexec_e (process.c:535)
==19363==
==19363==
==19363== 1184 bytes in 37 blocks are definitely lost in loss record 14 of 22
==19363==    at 0x3C026659: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck.so)
==19363==    by 0x8051D05: smatcher (engine.c:272)
==19363==    by 0x80578F2: regexec (regexec.c:178)
==19363==    by 0x804D1D6: regexec_e (process.c:535)
==19363==
==19363==
==19363== 1360 bytes in 17 blocks are definitely lost in loss record 16 of 22
==19363==    at 0x3C026659: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck.so)
==19363==    by 0x8054C79: lmatcher (engine.c:272)
==19363==    by 0x8057918: regexec (regexec.c:180)
==19363==    by 0x804D1D6: regexec_e (process.c:535)
==19363==
==19363== LEAK SUMMARY:
==19363==    definitely lost: 2976 bytes in 108 blocks.
==19363==    possibly lost:   0 bytes in 0 blocks.
==19363==    still reachable: 51500 bytes in 327 blocks.
==19363==         suppressed: 0 bytes in 0 blocks.
==19363== Reachable blocks (those to which a pointer was found) are not shown.
==19363== To see them, rerun with: --show-reachable=yes

Repeat the process with more elements and you will get even more leaked
blocks:
$ echo ':abcd: : :' | valgrind  --tool=memcheck --leak-check=yes ./sed -f TEST/hanoi.sed
[...]
==19457== LEAK SUMMARY:
==19457==    definitely lost: 6016 bytes in 212 blocks.
==19457==    possibly lost:   0 bytes in 0 blocks.
==19457==    still reachable: 51503 bytes in 327 blocks.
==19457==         suppressed: 0 bytes in 0 blocks.

>Fix:

	Apply the following patch:

Index: engine.c
===================================================================
RCS file: /home/ncvs/src/lib/libc/regex/engine.c,v
retrieving revision 1.5.8.1
diff -u -r1.5.8.1 engine.c
--- engine.c	31 Jul 2000 06:30:37 -0000	1.5.8.1
+++ engine.c	30 Dec 2004 14:08:27 -0000
@@ -242,6 +242,10 @@
 	for (;;) {
 		endp = fast(m, start, stop, gf, gl);
 		if (endp == NULL) {		/* a miss */
+			if (m->pmatch != NULL)
+				free((char *)m->pmatch);
+			if (m->lastpos != NULL)
+				free((char *)m->lastpos);
 			STATETEARDOWN(m);
 			return(REG_NOMATCH);
 		}

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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200412301411.iBUEB12S019499>