6863148 fn_move() still can dereference a NULL fn_parent
authorPavel Filipensky <Pavel.Filipensky@Sun.COM>
Sat, 01 Aug 2009 04:52:37 +0100
changeset 10238 666582d3aac7
parent 10237 1cca4617b3a8
child 10239 29a005902445
6863148 fn_move() still can dereference a NULL fn_parent
usr/src/uts/common/fs/nfs/nfs4_client.c
--- a/usr/src/uts/common/fs/nfs/nfs4_client.c	Fri Jul 31 16:55:33 2009 -0700
+++ b/usr/src/uts/common/fs/nfs/nfs4_client.c	Sat Aug 01 04:52:37 2009 +0100
@@ -4254,14 +4254,19 @@
 
 	/*
 	 * Remove fnp from its current parent, change its name, then add it
-	 * to newparent.
+	 * to newparent. It might happen that fnp was replaced by another
+	 * nfs4_fname_t with the same fn_name in parent->fn_children.
+	 * In such case, fnp->fn_parent is NULL and we skip the removal
+	 * of fnp from its current parent.
 	 */
 	mutex_enter(&fnp->fn_lock);
 	parent = fnp->fn_parent;
-	mutex_enter(&parent->fn_lock);
-	avl_remove(&parent->fn_children, fnp);
-	mutex_exit(&parent->fn_lock);
-	fn_rele(&fnp->fn_parent);
+	if (parent != NULL) {
+		mutex_enter(&parent->fn_lock);
+		avl_remove(&parent->fn_children, fnp);
+		mutex_exit(&parent->fn_lock);
+		fn_rele(&fnp->fn_parent);
+	}
 
 	newlen = strlen(newname);
 	if (newlen != fnp->fn_len) {