diff options
author | jhb <jhb@FreeBSD.org> | 2012-04-12 14:49:25 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2012-04-12 14:49:25 +0000 |
commit | 51ec6999bbb416b507036479196ef593938c435a (patch) | |
tree | 4aeb18418694af5809e9bf3bd7d69b6e6d708143 /sys/kern | |
parent | 6f01bcaac2b7eb091386d4274ea4700c864b70be (diff) | |
download | FreeBSD-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')
-rw-r--r-- | sys/kern/kern_linker.c | 15 |
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) { |