Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Fix dlopen()/dlclose()+RUMP_USE_CTOR to not leave dangli...



details:   https://anonhg.NetBSD.org/src/rev/44048bf21534
branches:  trunk
changeset: 343011:44048bf21534
user:      pooka <pooka%NetBSD.org@localhost>
date:      Mon Jan 18 16:46:08 2016 +0000

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

diffstat:

 sys/rump/librump/rumpkern/rump.c         |  25 ++++++++++++++++++++++---
 sys/rump/librump/rumpkern/rump_private.h |   8 +++++++-
 sys/sys/module.h                         |  29 ++++++++++++++++++++++++-----
 sys/sys/sysctl.h                         |  25 +++++++++++++++++++------
 4 files changed, 72 insertions(+), 15 deletions(-)

diffs (199 lines):

diff -r 52093118849d -r 44048bf21534 sys/rump/librump/rumpkern/rump.c
--- a/sys/rump/librump/rumpkern/rump.c  Mon Jan 18 15:53:38 2016 +0000
+++ b/sys/rump/librump/rumpkern/rump.c  Mon Jan 18 16:46:08 2016 +0000
@@ -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 @@
        {
                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 @@
 {
        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 @@
        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)
 {
diff -r 52093118849d -r 44048bf21534 sys/rump/librump/rumpkern/rump_private.h
--- a/sys/rump/librump/rumpkern/rump_private.h  Mon Jan 18 15:53:38 2016 +0000
+++ b/sys/rump/librump/rumpkern/rump_private.h  Mon Jan 18 16:46:08 2016 +0000
@@ -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)                                  \
 {                                                                      \
        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 @@
 #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);
 
diff -r 52093118849d -r 44048bf21534 sys/sys/module.h
--- a/sys/sys/module.h  Mon Jan 18 15:53:38 2016 +0000
+++ b/sys/sys/module.h  Mon Jan 18 16:46:08 2016 +0000
@@ -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 @@
 
 #ifdef _KERNEL
 
+#include <sys/kernel.h>
 #include <sys/mutex.h>
 
 #include <prop/proplib.h>
@@ -105,6 +106,12 @@
  * 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 @@
 };
 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 */
diff -r 52093118849d -r 44048bf21534 sys/sys/sysctl.h
--- a/sys/sys/sysctl.h  Mon Jan 18 15:53:38 2016 +0000
+++ b/sys/sys/sysctl.h  Mon Jan 18 16:46:08 2016 +0000
@@ -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 @@
 };
 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 */



Home | Main Index | Thread Index | Old Index