Date: Sat, 7 Feb 2004 22:42:58 -0800 (PST) From: Alan Batie <alan@agora.rdrop.com> To: FreeBSD-gnats-submit@FreeBSD.org Subject: i386/62515: realloc occasionally corrupts end of realloc'd block Message-ID: <200402080642.i186gw7s089485@agora.rdrop.com> Resent-Message-ID: <200402080650.i186oHul008310@freefall.freebsd.org>
index | next in thread | raw e-mail
>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@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:
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200402080642.i186gw7s089485>
