Subject: kern/35524: panic from free in pathname_get
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Brian de Alwis <bsd@cs.ubc.ca>
List: netbsd-bugs
Date: 01/30/2007 21:00:00
>Number: 35524
>Category: kern
>Synopsis: panic from free in pathname_get
>Confidential: no
>Severity: critical
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Jan 30 21:00:00 +0000 2007
>Originator: Brian de Alwis
>Release: NetBSD 4.99.7
>Organization:
Brian de Alwis | Software Practices Lab | UBC | http://www.cs.ubc.ca/~bsd/
"Amusement to an observing mind is study." - Benjamin Disraeli
>Environment:
From -current as of Jan 7, 2007.
System: NetBSD monolith 4.99.7 NetBSD 4.99.7 (LAPTOP.MPACPI) #8: Tue Jan 30 09:50:57 CST 2007 bsd@monolith:/usr/obj/sys/arch/i386/compile/LAPTOP.MPACPI i386
Architecture: i386
Machine: i386
>Description:
I'm encountering a panic from a script that builds up a
CLASSPATH string for use by a JVM.
The panic is (cribbed by hand)
panic: free: addr 0xcc366b68 not within kmem_map
pathname_get(806f800,0,cc366b68,0,cb8cc2e4) at netbsd:pathname_get+0xde
vn_open(cc366ba8,5,0,ffffffff,cb832000) at netbsd:vn_open+0x78
sys_open(...)
[...]
The script does a series of:
append CLASSPATH $WS/Exploration_Analysis/lib/*.jar
where append() is a shell function that checks if the entry
is found in the provided var name, and appends it if not.
append() does not do any path checking of its own: the
problems occur from the shell expanding the wildcards
specified.
The actual problem is triggered by one of three appends
that reference a non-existant paths. Fixing up those
non-existant paths prevents the panic.
>How-To-Repeat:
I've attached my run script here. The problem unfortunately
seems specific to my local layout here (I can't trigger it
if I change any variables), and I couldn't find a way to
shorten it with a couple of minutes. But it is (very!)
reproducible on my laptop.
>Fix:
Looking at the implementation of pathname_get in
kern/vfs_loopup.c, it looks like the call to free isn't
properly indirecting the pointer, nor is it NULLing out
the reference. This is essential, since the pointer was
provided by the caller. A proposed fix is below -- I'm
running with it now, and haven't had a panic.
diff -w -b -u -r1.79 vfs_lookup.c
--- sys/kern/vfs_lookup.c 7 Jan 2007 21:33:24 -0000 1.79
+++ sys/kern/vfs_lookup.c 30 Jan 2007 20:39:18 -0000
@@ -213,7 +213,8 @@
NULL);
if (error) {
PNBUF_PUT((*path)->pathbuf);
- free(path, M_TEMP);
+ free(*path, M_TEMP);
+ *path = NULL;
return (error);
}
(*path)->needfree = TRUE;
Reproducing script:
#!/bin/sh
# Add to the path variable named by $1 the component $2. $3 must be
# "append" or "prepend" to indicate where the component is added.
_addpath () {
#local value result
eval value=\"\$$1\"
case "$value" in
*:$2:*|*:$2|$2:*|$2)
result="$value"
;;
"")
result="$2"
;;
*)
case "$3" in
p*)
result="$2:${value}"
;;
*)
result="${value}:$2"
;;
esac
esac
eval $1=$result
unset result value
}
# convenience routine which appends a string to a path.
append () {
_varname=$1; shift
for _value in "$@"; do
_addpath "$_varname" "$_value" append
done
unset _varname _value
}
WS=$HOME/research/eclipse/workspace-mylar-redux
ECLIPSEDIR=/usr/local/installs/eclipse-3.3M3/plugins
ASMDIR=$HOME/research/eclipse/eclipse-packages/eclipse/plugins/org.objectweb.asm_2.2.1/output/dist/lib/
append CLASSPATH $WS/Exploration_Analysis/bin
append CLASSPATH $WS/Exploration_Analysis/lib/*.jar
append CLASSPATH $WS/RelevantElements/bin
append CLASSPATH $WS/edu.uci.ics.jung/bin
append CLASSPATH $WS/edu.uci.ics.jung/lib/*.jar
append CLASSPATH $WS/org.eclipse.mylar.context.core/bin
append CLASSPATH $WS/org.eclipse.mylar.monitor/bin
append CLASSPATH $WS/org.eclipse.mylar.monitor.usage/bin
append CLASSPATH $WS/org.eclipse.mylar.tasks.core/bin
append CLASSPATH $WS/ca.ubc.cs.mylar.monitors.parts/bin
append CLASSPATH $WS/ca.ubc.cs.mylar.monitors.parts.examples/bin
append CLASSPATH $ECLIPSEDIR/plugins/org.eclipse.osgi*
append CLASSPATH $ECLIPSEDIR/plugins/org.eclipse.equinox*
append CLASSPATH $ECLIPSEDIR/plugins/org.eclipse.core.*
append CLASSPATH $ECLIPSEDIR/org.eclipse.jface_*.jar
append CLASSPATH $ECLIPSEDIR/org.eclipse.jface.text_*.jar
append CLASSPATH $ECLIPSEDIR/org.eclipse.jdt.core_*.jar
append CLASSPATH $ASMDIR/*.jar
export CLASSPATH
echo $CLASSPATH
--
Brian de Alwis | Software Practices Lab | UBC | http://www.cs.ubc.ca/~bsd/
"Amusement to an observing mind is study." - Benjamin Disraeli