summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_linker.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2012-04-12 14:49:25 +0000
committerjhb <jhb@FreeBSD.org>2012-04-12 14:49:25 +0000
commit51ec6999bbb416b507036479196ef593938c435a (patch)
tree4aeb18418694af5809e9bf3bd7d69b6e6d708143 /sys/kern/kern_linker.c
parent6f01bcaac2b7eb091386d4274ea4700c864b70be (diff)
downloadFreeBSD-src-51ec6999bbb416b507036479196ef593938c435a.zip
FreeBSD-src-51ec6999bbb416b507036479196ef593938c435a.tar.gz
If a linker file contains at least one module, but all of the modules
fail to load (the MOD_LOAD event fails) during a kldload(2), unload the linker file and fail the kldload(2) with ENOEXEC. Reported by: gcooper MFC after: 1 week
Diffstat (limited to 'sys/kern/kern_linker.c')
-rw-r--r--sys/kern/kern_linker.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c
index cb3b2d7..ef7ee39 100644
--- a/sys/kern/kern_linker.c
+++ b/sys/kern/kern_linker.c
@@ -380,7 +380,7 @@ linker_load_file(const char *filename, linker_file_t *result)
{
linker_class_t lc;
linker_file_t lf;
- int foundfile, error;
+ int foundfile, error, modules;
/* Refuse to load modules if securelevel raised */
if (prison0.pr_securelevel > 0)
@@ -419,11 +419,22 @@ linker_load_file(const char *filename, linker_file_t *result)
linker_file_unload(lf, LINKER_UNLOAD_FORCE);
return (error);
}
+ modules = !TAILQ_EMPTY(&lf->modules);
KLD_UNLOCK();
linker_file_register_sysctls(lf);
linker_file_sysinit(lf);
KLD_LOCK();
lf->flags |= LINKER_FILE_LINKED;
+
+ /*
+ * If all of the modules in this file failed
+ * to load, unload the file and return an
+ * error of ENOEXEC.
+ */
+ if (modules && TAILQ_EMPTY(&lf->modules)) {
+ linker_file_unload(lf, LINKER_UNLOAD_FORCE);
+ return (ENOEXEC);
+ }
*result = lf;
return (0);
}
@@ -627,7 +638,7 @@ linker_file_unload(linker_file_t file, int flags)
/*
* Inform any modules associated with this file that they are
- * being be unloaded.
+ * being unloaded.
*/
MOD_XLOCK;
for (mod = TAILQ_FIRST(&file->modules); mod; mod = next) {
OpenPOWER on IntegriCloud