6943440 race in solookup() can cause smod_refcnt to be bumped multiple times for a single sockparams
diff --git a/usr/src/uts/common/fs/sockfs/sockparams.c b/usr/src/uts/common/fs/sockfs/sockparams.c
index e20870d..5c4872f 100644
--- a/usr/src/uts/common/fs/sockfs/sockparams.c
+++ b/usr/src/uts/common/fs/sockfs/sockparams.c
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include <sys/types.h>
@@ -316,7 +315,7 @@
 	sockparams_sdev_fini(sp);
 
 	if (sp->sp_smod_info != NULL)
-		SMOD_DEC_REF(sp, sp->sp_smod_info);
+		SMOD_DEC_REF(sp->sp_smod_info, sp->sp_smod_name);
 	kmem_free(sp->sp_smod_name, strlen(sp->sp_smod_name) + 1);
 	sp->sp_smod_name = NULL;
 	sp->sp_smod_info = NULL;
@@ -770,8 +769,9 @@
 	rw_exit(&splist_lock);
 
 	if (sp->sp_smod_info == NULL) {
-		sp->sp_smod_info = smod_lookup_byname(sp->sp_smod_name);
-		if (sp->sp_smod_info == NULL) {
+		smod_info_t *smod = smod_lookup_byname(sp->sp_smod_name);
+
+		if (smod == NULL) {
 			/*
 			 * We put a hold on the sockparams entry
 			 * earlier, hoping everything would work out.
@@ -787,6 +787,18 @@
 			 */
 			return (ENXIO);
 		}
+		/*
+		 * Another thread might have already looked up the socket
+		 * module for this entry. In that case we need to drop our
+		 * reference to `smod' to ensure that the sockparams entry
+		 * only holds one reference.
+		 */
+		mutex_enter(&sp->sp_lock);
+		if (sp->sp_smod_info == NULL)
+			sp->sp_smod_info = smod;
+		else
+			SMOD_DEC_REF(smod, sp->sp_smod_name);
+		mutex_exit(&sp->sp_lock);
 	}
 
 	/*