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