tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Proposal, again: Disable autoload of compat_xyz modules
In article <20190927125444.GB12813%pony.stderr.spb.ru@localhost>,
Valery Ushakov <uwe%stderr.spb.ru@localhost> 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. */
Home |
Main Index |
Thread Index |
Old Index