In article <20190927125444.gb12...@pony.stderr.spb.ru>,
Valery Ushakov  <u...@stderr.spb.ru> wrote:
>
>May be we should take a look at how SNMP did tables in MIB, b/c we are
>trying to create just such a table indexed by module name.

I think it is simpler than that.

>
>Also, I'm not that sure about autoload of compat stuff especially
>since iirc it currently implies auto-unload too.  I vaguely remember
>when I was debugging something in sh3 kobj_machdep.c I had some
>printfs there that made the autoloads visibile and (iirc) each vi
>invocation would trigger an autoload of compat ioctl code (which
>wouldn't recognize the ioctl, and that would be auto-unloaded a few
>seconds later).
>
>-uwe


Here's what I've implemented:

kern.module.noautoload="compat_linux* compat_[0-4]?"

This disables autoload for all compat_linux modules as well
as compat_netbsd < NetBSD-5.0

Comments?

christos

Index: kern_exec.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_exec.c,v
retrieving revision 1.481
diff -u -u -r1.481 kern_exec.c
--- kern_exec.c 17 Sep 2019 15:19:27 -0000      1.481
+++ kern_exec.c 28 Sep 2019 01:27:00 -0000
@@ -626,6 +626,8 @@
                "exec_ecoff",
                "compat_aoutm68k",
                "compat_netbsd32",
+               "compat_linux",
+               "compat_linux32",
                "compat_sunos",
                "compat_sunos32",
                "compat_ultrix",
Index: kern_module.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_module.c,v
retrieving revision 1.138
diff -u -u -r1.138 kern_module.c
--- kern_module.c       8 Aug 2019 18:08:41 -0000       1.138
+++ kern_module.c       28 Sep 2019 01:27:00 -0000
@@ -53,10 +53,16 @@
 #include <sys/module.h>
 #include <sys/kthread.h>
 #include <sys/sysctl.h>
+#include <sys/queue.h>
 #include <sys/lock.h>
 
 #include <uvm/uvm_extern.h>
 
+#ifndef MODULE_NOAUTOLOAD
+// Disable compat_linux and compat_linux32 by default for now
+#define MODULE_NOAUTOLOAD "compat_linux*"
+#endif
+
 struct vm_map *module_map;
 const char *module_machine;
 char   module_base[MODULE_BASE_SIZE];
@@ -93,6 +99,7 @@
 u_int          module_gen = 1;
 static kcondvar_t module_thread_cv;
 static kmutex_t module_thread_lock;
+static kmutex_t module_noautoload_lock;
 static int     module_thread_ticks;
 int (*module_load_vfs_vec)(const char *, int, bool, module_t *,
                           prop_dictionary_t *) = (void *)eopnotsupp;
@@ -120,6 +127,8 @@
 static void    module_enqueue(module_t *);
 
 static bool    module_merge_dicts(prop_dictionary_t, const prop_dictionary_t);
+static bool    module_allow_autoload(const char *);
+static void    module_noautoload_update(const char *);
 
 static void    sysctl_module_setup(void);
 static int     sysctl_module_autotime(SYSCTLFN_PROTO);
@@ -412,6 +421,7 @@
        }
        cv_init(&module_thread_cv, "mod_unld");
        mutex_init(&module_thread_lock, MUTEX_DEFAULT, IPL_NONE);
+       mutex_init(&module_noautoload_lock, MUTEX_DEFAULT, IPL_NONE);
        TAILQ_INIT(&modcblist);
 
 #ifdef MODULAR /* XXX */
@@ -444,6 +454,8 @@
        module_netbsd = module_newmodule(MODULE_SOURCE_KERNEL);
        module_netbsd->mod_refcnt = 1;
        module_netbsd->mod_info = &module_netbsd_modinfo;
+
+       module_noautoload_update(MODULE_NOAUTOLOAD);
 }
 
 /*
@@ -503,6 +515,100 @@
        return (0);
 }
 
+struct noautoload {
+       const char *name;
+       SLIST_ENTRY(noautoload) next;
+};
+
+static SLIST_HEAD(, noautoload) noautoload_list =
+    SLIST_HEAD_INITIALIZER(noautoload_list);
+
+static char noautoload_buf[1024];
+static char noautoload_nbuf[sizeof(noautoload_buf)];
+
+static void
+module_noautoload_update(const char *cbuf)
+{
+       static const char SEP[] = " \t\n,";
+       struct noautoload *e, *te;
+       char buf[sizeof(noautoload_buf)];
+
+       strlcpy(buf, cbuf, sizeof(buf));
+
+       mutex_enter(&module_noautoload_lock);
+
+       SLIST_FOREACH_SAFE(e, &noautoload_list, next, te) {
+               SLIST_REMOVE(&noautoload_list, e, noautoload, next);
+               kmem_free(e, sizeof(*e));
+       }
+
+       noautoload_nbuf[0] = noautoload_buf[0] = '\0';
+
+       size_t pos = 0;
+       char *p, *str = buf;
+
+       while ((p = strsep(&str, SEP)) != NULL) {
+               size_t len = strlen(p);
+               if (len == 0)
+                       break;
+               e = kmem_alloc(sizeof(*e), KM_SLEEP);
+               e->name = noautoload_nbuf + pos;
+               SLIST_INSERT_HEAD(&noautoload_list, e, next);
+
+               memcpy(noautoload_buf + pos, p, len);
+               memcpy(noautoload_nbuf + pos, p, len);
+               pos += len;
+               noautoload_buf[pos] = ' ';
+               noautoload_nbuf[pos] = '\0';
+               pos++;
+       }
+
+       if (pos)
+               noautoload_buf[pos - 1] = '\0'; /* space to NUL */
+
+       mutex_exit(&module_noautoload_lock);
+}
+
+static int
+sysctl_module_noautoload(SYSCTLFN_ARGS)
+{
+       struct sysctlnode node;
+       int error;
+       char newbuf[sizeof(noautoload_buf)];
+
+       strlcpy(newbuf, noautoload_buf, sizeof(newbuf));
+
+       node = *rnode;
+       node.sysctl_data = newbuf;
+       node.sysctl_size = sizeof(noautoload_buf);
+       error = sysctl_lookup(SYSCTLFN_CALL(&node));
+       if (error || newp == NULL || strcmp(newbuf, noautoload_buf) == 0)
+               return error;
+
+       module_noautoload_update(newbuf);
+
+       return 0;
+}
+
+
+static bool
+module_allow_autoload(const char *name)
+{
+       struct noautoload *e;
+
+       mutex_enter(&module_noautoload_lock);
+       SLIST_FOREACH(e, &noautoload_list, next) {
+               if (pmatch(name, e->name, NULL) > 0) {
+                       mutex_exit(&module_noautoload_lock);
+                       module_print("module `%s' matched `%s'"
+                           " and will not autoload", name, e->name);
+                       return false;
+               }
+       }
+       mutex_exit(&module_noautoload_lock);
+       return true;
+}
+
 static void
 sysctl_module_setup(void)
 {
@@ -542,6 +648,12 @@
                SYSCTL_DESCR("Auto-unload delay"),
                sysctl_module_autotime, 0, &module_autotime, 0,
                CTL_CREATE, CTL_EOL);
+       sysctl_createv(&module_sysctllog, 0, &node, NULL,
+               CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
+               CTLTYPE_STRING, "noautoload",
+               SYSCTL_DESCR("List of module patterns not to be autoloaded"),
+               sysctl_module_noautoload, 0, NULL, sizeof(noautoload_buf),
+               CTL_CREATE, CTL_EOL);
 }
 
 /*
@@ -677,6 +789,9 @@
 {
        int error;
 
+       if (!module_allow_autoload(filename))
+               return EACCES;
+
        kernconfig_lock();
 
        /* Nothing if the user has disabled it. */


Reply via email to