bin/130632: gpart assert failure if used from FreeBSD Live CD
Dimitry Andric
dimitry at andric.com
Fri Jan 16 14:10:02 PST 2009
>Number: 130632
>Category: bin
>Synopsis: gpart assert failure if used from FreeBSD Live CD
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Fri Jan 16 22:10:01 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator: Dimitry Andric
>Release: FreeBSD 8.0-CURRENT i386
>Organization:
n/a
>Environment:
System: FreeBSD vfbsd8.home.andric.com 8.0-CURRENT FreeBSD 8.0-CURRENT #0: Thu Jan 15 23:55:45 CET 2009 dim at vfbsd8.home.andric.com:/usr/obj/usr/src/sys/GENERIC i386
>Description:
If you run gpart(8) from a recent FreeBSD -CURRENT Live CD, it will
crash with the following assertion failure:
Assertion failed: (diff == regind * size), function arena_run_reg_dalloc, file /usr/src/lib/libc/stdlib/malloc.c, line 2536.
Abort trap: 6 (core dumped)
This is due to incorrect usage of strsep(3) in the function
load_library() in /usr/src/sbin/geom/core/geom.c, and caused by the
Live CD having set GEOM_LIBRARY_PATH to "/mnt2/lib/geom:/lib/geom".
In load_library(), you see the following:
totalpath = strdup(libpath);
...
if (strchr(totalpath, ':') != NULL)
curpath = strsep(&totalpath, ":");
...
free(totalpath);
The problem here is that strsep(3) modifies totalpath, to point at the
next token. If you then attempt to free it later, the behaviour is
undefined. The newer malloc in -CURRENT apparently catches this.
Note this ONLY occurs if GEOM_LIBRARY_PATH exists, contains more than
one directory, and the geom .so files are found in the first
directory.
>How-To-Repeat:
This is easily reproduced on -CURRENT, by running:
$ GEOM_LIBRARY_PATH=/lib/geom:/foo /sbin/gpart
Assertion failed: (diff == regind * size), function arena_run_reg_dalloc, file /usr/src/lib/libc/stdlib/malloc.c, line 2536.
Abort trap: 6 (core dumped)
>Fix:
Here is a patch, following the strsep(3) manpage example.
Index: sbin/geom/core/geom.c
===================================================================
RCS file: /home/ncvs/src/sbin/geom/core/geom.c,v
retrieving revision 1.36
diff -u -p -r1.36 geom.c
--- sbin/geom/core/geom.c 4 Jun 2008 20:07:59 -0000 1.36
+++ sbin/geom/core/geom.c 16 Jan 2009 21:40:54 -0000
@@ -487,13 +487,13 @@ library_path(void)
static void
load_library(void)
{
- char *curpath, path[MAXPATHLEN], *totalpath;
+ char *curpath, path[MAXPATHLEN], *totalpath, *tofree;
uint32_t *lib_version;
void *dlh;
int ret;
ret = 0;
- totalpath = strdup(library_path());
+ tofree = totalpath = strdup(library_path());
if (totalpath == NULL)
err(EXIT_FAILURE, "Not enough memory for library path");
@@ -519,7 +519,7 @@ load_library(void)
}
break;
}
- free(totalpath);
+ free(tofree);
/* No library was found, but standard commands can still be used */
if (ret == -1)
return;
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list