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