Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Jan 2011 09:58:41 +0000 (UTC)
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r216988 - head/sys/kern
Message-ID:  <201101050958.p059wfTN072208@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trasz
Date: Wed Jan  5 09:58:41 2011
New Revision: 216988
URL: http://svn.freebsd.org/changeset/base/216988

Log:
  Fix page fault that occurred when trying to initialize preloaded kernel module,
  the dependency of which was preloaded, but failed to initialize.  Previously,
  kernel dereferenced NULL pointer returned by modlist_lookup2(); now, when this
  happens, we unload the dependent module.  Since the depended_files list is
  sorted in dependency order, this properly propagates, unloading modules that
  depend on failed ones.
  
  From the user point of view, this prevents the kernel from panicing when
  trying to boot kernel compiled without KDTRACE_HOOKS with dtraceall_load="YES"
  in /boot/loader.conf.
  
  Reviewed by:	kib

Modified:
  head/sys/kern/kern_linker.c

Modified: head/sys/kern/kern_linker.c
==============================================================================
--- head/sys/kern/kern_linker.c	Wed Jan  5 09:45:20 2011	(r216987)
+++ head/sys/kern/kern_linker.c	Wed Jan  5 09:58:41 2011	(r216988)
@@ -1584,6 +1584,12 @@ restart:
 				modname = mp->md_cval;
 				verinfo = mp->md_data;
 				mod = modlist_lookup2(modname, verinfo);
+				if (mod == NULL) {
+					printf("KLD file %s - cannot find "
+					    "dependency \"%s\"\n",
+					    lf->filename, modname);
+					goto fail;
+				}
 				/* Don't count self-dependencies */
 				if (lf == mod->container)
 					continue;
@@ -1600,11 +1606,9 @@ restart:
 		 */
 		error = LINKER_LINK_PRELOAD_FINISH(lf);
 		if (error) {
-			TAILQ_REMOVE(&depended_files, lf, loaded);
 			printf("KLD file %s - could not finalize loading\n",
 			    lf->filename);
-			linker_file_unload(lf, LINKER_UNLOAD_FORCE);
-			continue;
+			goto fail;
 		}
 		linker_file_register_modules(lf);
 		if (linker_file_lookup_set(lf, "sysinit_set", &si_start,
@@ -1612,6 +1616,10 @@ restart:
 			sysinit_add(si_start, si_stop);
 		linker_file_register_sysctls(lf);
 		lf->flags |= LINKER_FILE_LINKED;
+		continue;
+fail:
+		TAILQ_REMOVE(&depended_files, lf, loaded);
+		linker_file_unload(lf, LINKER_UNLOAD_FORCE);
 	}
 	/* woohoo! we made it! */
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201101050958.p059wfTN072208>