Module Name:    src
Committed By:   pooka
Date:           Mon Jan 18 16:46:08 UTC 2016

Modified Files:
        src/sys/rump/librump/rumpkern: rump.c rump_private.h
        src/sys/sys: module.h sysctl.h

Log Message:
Fix dlopen()/dlclose()+RUMP_USE_CTOR to not leave dangling pointers around.


To generate a diff of this commit:
cvs rdiff -u -r1.325 -r1.326 src/sys/rump/librump/rumpkern/rump.c
cvs rdiff -u -r1.92 -r1.93 src/sys/rump/librump/rumpkern/rump_private.h
cvs rdiff -u -r1.39 -r1.40 src/sys/sys/module.h
cvs rdiff -u -r1.217 -r1.218 src/sys/sys/sysctl.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/rump/librump/rumpkern/rump.c
diff -u src/sys/rump/librump/rumpkern/rump.c:1.325 src/sys/rump/librump/rumpkern/rump.c:1.326
--- src/sys/rump/librump/rumpkern/rump.c:1.325	Mon Aug 31 07:38:48 2015
+++ src/sys/rump/librump/rumpkern/rump.c	Mon Jan 18 16:46:08 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: rump.c,v 1.325 2015/08/31 07:38:48 ozaki-r Exp $	*/
+/*	$NetBSD: rump.c,v 1.326 2016/01/18 16:46:08 pooka Exp $	*/
 
 /*
  * Copyright (c) 2007-2011 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.325 2015/08/31 07:38:48 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.326 2016/01/18 16:46:08 pooka Exp $");
 
 #include <sys/systm.h>
 #define ELFSIZE ARCH_ELFSIZE
@@ -314,7 +314,8 @@ rump_init(void)
 	{
 		struct sysctl_setup_chain *ssc;
 
-		LIST_FOREACH(ssc, &sysctl_boot_chain, ssc_entries) {
+		while ((ssc = LIST_FIRST(&sysctl_boot_chain)) != NULL) {
+			LIST_REMOVE(ssc, ssc_entries);
 			ssc->ssc_func(NULL);
 		}
 	}
@@ -544,6 +545,10 @@ rump_component_load(const struct rump_co
 {
 	struct rump_component *rc, *rc_iter;
 
+	/* time for rump component loading and unloading has passed */
+	if (!cold)
+		return;
+
 	/*
 	 * XXX: this is ok since the "const" was removed from the
 	 * definition of RUMP_COMPONENT().
@@ -565,6 +570,20 @@ rump_component_load(const struct rump_co
 	compcounter[rc->rc_type]++;
 }
 
+void
+rump_component_unload(struct rump_component *rc)
+{
+
+	/*
+	 * Checking for cold is enough because rump_init() both
+	 * flips it and handles component loading.
+	 */
+	if (!cold)
+		return;
+
+	LIST_REMOVE(rc, rc_entries);
+}
+
 int
 rump_component_count(enum rump_component_type type)
 {

Index: src/sys/rump/librump/rumpkern/rump_private.h
diff -u src/sys/rump/librump/rumpkern/rump_private.h:1.92 src/sys/rump/librump/rumpkern/rump_private.h:1.93
--- src/sys/rump/librump/rumpkern/rump_private.h:1.92	Wed Apr 22 17:38:33 2015
+++ src/sys/rump/librump/rumpkern/rump_private.h	Mon Jan 18 16:46:08 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: rump_private.h,v 1.92 2015/04/22 17:38:33 pooka Exp $	*/
+/*	$NetBSD: rump_private.h,v 1.93 2016/01/18 16:46:08 pooka Exp $	*/
 
 /*
  * Copyright (c) 2007-2011 Antti Kantee.  All Rights Reserved.
@@ -90,6 +90,11 @@ static void rumpcomp_ctor##type(void) __
 static void rumpcomp_ctor##type(void)					\
 {									\
 	rump_component_load(&rumpcomp##type);				\
+}									\
+static void rumpcomp_dtor##type(void) __attribute__((destructor));	\
+static void rumpcomp_dtor##type(void)					\
+{									\
+	rump_component_unload(&rumpcomp##type);				\
 }
 
 #else /* RUMP_USE_CTOR */
@@ -130,6 +135,7 @@ struct rump_spctl {
 #define RUMP_SPVM2CTL(vm) (((struct rump_spctl *)vm)->spctl)
 
 void		rump_component_load(const struct rump_component *);
+void		rump_component_unload(struct rump_component *);
 void		rump_component_init(enum rump_component_type);
 int		rump_component_count(enum rump_component_type);
 

Index: src/sys/sys/module.h
diff -u src/sys/sys/module.h:1.39 src/sys/sys/module.h:1.40
--- src/sys/sys/module.h:1.39	Wed Nov  4 04:28:58 2015
+++ src/sys/sys/module.h	Mon Jan 18 16:46:08 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: module.h,v 1.39 2015/11/04 04:28:58 pgoyette Exp $	*/
+/*	$NetBSD: module.h,v 1.40 2016/01/18 16:46:08 pooka Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -65,6 +65,7 @@ typedef enum modcmd {
 
 #ifdef _KERNEL
 
+#include <sys/kernel.h>
 #include <sys/mutex.h>
 
 #include <prop/proplib.h>
@@ -105,6 +106,12 @@ typedef struct module {
  * Alternatively, in some environments rump kernels use
  * __attribute__((constructor)) due to link sets being
  * difficult (impossible?) to implement (e.g. GNU gold, OS X, etc.)
+ * If we're cold (read: rump_init() has not been called), we lob the
+ * module onto the list to be handled when rump_init() runs.
+ * nb. it's not possible to use in-kernel locking mechanisms here since
+ * the code runs before rump_init().  We solve the problem by decreeing
+ * that thou shalt not call dlopen()/dlclose() for rump kernel components
+ * from multiple threads before calling rump_init().
  */
 
 #ifdef RUMP_USE_CTOR
@@ -114,14 +121,26 @@ struct modinfo_chain {
 };
 LIST_HEAD(modinfo_boot_chain, modinfo_chain);
 #define _MODULE_REGISTER(name)						\
+static struct modinfo_chain __CONCAT(mc,name) = {			\
+	.mc_info = &__CONCAT(name,_modinfo),				\
+};									\
 static void __CONCAT(modctor_,name)(void) __attribute__((__constructor__));\
 static void __CONCAT(modctor_,name)(void)				\
 {									\
-	static struct modinfo_chain mc = {				\
-		.mc_info = &__CONCAT(name,_modinfo),			\
-	};								\
 	extern struct modinfo_boot_chain modinfo_boot_chain;		\
-	LIST_INSERT_HEAD(&modinfo_boot_chain, &mc, mc_entries);		\
+	if (cold) {							\
+		struct modinfo_chain *mc = &__CONCAT(mc,name);		\
+		LIST_INSERT_HEAD(&modinfo_boot_chain, mc, mc_entries);	\
+	}								\
+}									\
+									\
+static void __CONCAT(moddtor_,name)(void) __attribute__((__destructor__));\
+static void __CONCAT(moddtor_,name)(void)				\
+{									\
+	struct modinfo_chain *mc = &__CONCAT(mc,name);			\
+	if (cold) {							\
+		LIST_REMOVE(mc, mc_entries);				\
+	}								\
 }
 
 #else /* RUMP_USE_CTOR */

Index: src/sys/sys/sysctl.h
diff -u src/sys/sys/sysctl.h:1.217 src/sys/sys/sysctl.h:1.218
--- src/sys/sys/sysctl.h:1.217	Sat Sep 26 20:28:37 2015
+++ src/sys/sys/sysctl.h	Mon Jan 18 16:46:08 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: sysctl.h,v 1.217 2015/09/26 20:28:37 christos Exp $	*/
+/*	$NetBSD: sysctl.h,v 1.218 2016/01/18 16:46:08 pooka Exp $	*/
 
 /*
  * Copyright (c) 1989, 1993
@@ -50,6 +50,8 @@
 #include <sys/ucontext.h>
 #include <sys/mallocvar.h>
 #include <uvm/uvm_extern.h>
+
+#include <sys/kernel.h>
 #endif
 
 
@@ -1154,14 +1156,25 @@ struct sysctl_setup_chain {
 };
 LIST_HEAD(sysctl_boot_chain, sysctl_setup_chain);
 #define _SYSCTL_REGISTER(name)						\
+static struct sysctl_setup_chain __CONCAT(ssc,name) = {			\
+	.ssc_func = name,						\
+};									\
 static void sysctlctor_##name(void) __attribute__((constructor));	\
 static void sysctlctor_##name(void)					\
 {									\
-        static struct sysctl_setup_chain ssc = {			\
-		.ssc_func = name,					\
-        };								\
-        extern struct sysctl_boot_chain sysctl_boot_chain;		\
-        LIST_INSERT_HEAD(&sysctl_boot_chain, &ssc, ssc_entries);	\
+	struct sysctl_setup_chain *ssc = &__CONCAT(ssc,name);		\
+	extern struct sysctl_boot_chain sysctl_boot_chain;		\
+	if (cold) {							\
+		LIST_INSERT_HEAD(&sysctl_boot_chain, ssc, ssc_entries);	\
+	}								\
+}									\
+static void sysctldtor_##name(void) __attribute__((destructor));	\
+static void sysctldtor_##name(void)					\
+{									\
+	struct sysctl_setup_chain *ssc = &__CONCAT(ssc,name);		\
+	if (cold) {							\
+		LIST_REMOVE(ssc, ssc_entries);				\
+	}								\
 }
 
 #else /* RUMP_USE_CTOR */

Reply via email to