i386/62515: realloc occasionally corrupts end of realloc'd block

Alan Batie alan at agora.rdrop.com
Sat Feb 7 22:50:17 PST 2004


>Number:         62515
>Category:       i386
>Synopsis:       realloc occasionally corrupts end of realloc'd block
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-i386
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Feb 07 22:50:17 PST 2004
>Closed-Date:
>Last-Modified:
>Originator:     Alan Batie
>Release:        FreeBSD 4.7-STABLE i386
>Organization:
RainDrop Laboratories
>Environment:
System: FreeBSD agora.rdrop.com 4.7-STABLE FreeBSD 4.7-STABLE #0: Mon Feb 3 00:57:16 PST 2003 root at agora.rdrop.com:/usr/src/freebsd/src/sys/compile/AGORA i386


>Description:
	I have a web application to allow users to change their password
	and a few other account management activities.  I recently added
	support for updating street address info in a MySQL database using
	ODBC calls (iodbc).  After doing so, occasionally data in another
	flat text file database would be corrupted.  After much hair pulling,
	I found the following in code that implements a perl style "join":

	Debug output:

	    Feb  7 20:17:50 agora acctmgmt:     buf: 'login:User Name:503-nnn-nnnn:w'
	    Feb  7 20:17:50 agora acctmgmt:     realloc buf: 'login:User Name:503-nnn-nnnn:w:Mar-2004:61051 '

	Code segment:
	    syslog(LOG_WARNING, "    buf: '%s'", buf);
		    len += strlen(stack[i]);
		    buf = realloc(buf, len + 2);
	    syslog(LOG_WARNING, "    realloc buf: '%s'", buf);

	After adding code to detect the condition, it changed slightly:

	    Feb  7 21:43:14 agora acctmgmt: realloc failed!
	    Feb  7 21:43:14 agora acctmgmt:     before(0x0807b480)='login:User Name:503-nnn-nnnn:w'
	    Feb  7 21:43:14 agora acctmgmt:     after(0x0807b4c0)='login:User Name:503-nnn-nnnn:'


>How-To-Repeat:
	
>Fix:

	I've worked around the problem by saving the buffer before
	the realloc and recopying it if need be:

	    if (first) {
		before = NULL;
		blen = 0;
	    } else {
		before = strdup(buf);
		blen = strlen(buf);
	    }
	    buf = (char *) realloc(buf, len + 2);
	    alen = strlen(buf);
	    if (blen != 0 && alen != blen) {
		syslog(LOG_WARNING, "realloc failed!");
		syslog(LOG_WARNING, "    before(0x%08x)='%s'", before, before);
		syslog(LOG_WARNING, "    after(0x%08x)='%s'", buf, buf);
		strcpy(buf, before);
	    }
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-i386 mailing list