return true;
}
+/*********************************************************************
+*********************************************************************/
+static
+Boolean kextIsADependency(OSString * name) {
+ Boolean result = true;
+ OSDictionary * extensionsDict = 0; // don't release
+ OSDictionary * extDict = 0; // don't release
+ OSDictionary * extPlist = 0; // don't release
+ OSBoolean * isKernelResourceObj = 0; // don't release
+ OSData * driverCode = 0; // don't release
+ OSData * compressedCode = 0; // don't release
+
+ extensionsDict = getStartupExtensions();
+ if (!extensionsDict) {
+ IOLog("kextIsADependency(): No extensions dictionary.\n");
+ LOG_DELAY();
+ result = false;
+ goto finish;
+ }
+
+
+ extDict = OSDynamicCast(OSDictionary,
+ extensionsDict->getObject(name));
+ if (!extDict) {
+ IOLog("kextIsADependency(): "
+ "Extension \"%s\" cannot be found.\n",
+ name->getCStringNoCopy());
+ LOG_DELAY();
+ result = false;
+ goto finish;
+ }
+
+ extPlist = OSDynamicCast(OSDictionary, extDict->getObject("plist"));
+ if (!extPlist) {
+ IOLog("getDependencyListForKmod(): "
+ "Extension \"%s\" has no property list.\n",
+ name->getCStringNoCopy());
+ LOG_DELAY();
+ result = false;
+ goto finish;
+ }
+
+ /* A kext that is a kernel component is still a dependency, as there
+ * are fake kmod entries for them.
+ */
+ isKernelResourceObj = OSDynamicCast(OSBoolean,
+ extPlist->getObject("OSKernelResource"));
+ if (isKernelResourceObj && isKernelResourceObj->isTrue()) {
+ result = true;
+ goto finish;
+ }
+
+ driverCode = OSDynamicCast(OSData, extDict->getObject("code"));
+ compressedCode = OSDynamicCast(OSData,
+ extDict->getObject("compressedCode"));
+
+ if (!driverCode && !compressedCode) {
+ result = false;
+ goto finish;
+ }
+
+finish:
+
+ return result;
+}
+
/*********************************************************************
* This function builds a uniqued, in-order list of modules that need
* to be loaded in order for kmod_name to be successfully loaded. This
OSDictionary * extPlist; // don't release
OSString * extName; // don't release
OSArray * dependencyList = NULL; // return value, caller releases
- OSBoolean * isKernelResourceObj = 0; // don't release
- bool isKernelResource = false;
- bool declaresExecutable = false;
unsigned int i;
/* These are used to remove duplicates from the dependency list.
goto finish;
}
- /* A kext that's not a kernel extension and declares no executable has nothing
- * to load, so just return an empty array.
- */
- isKernelResourceObj = OSDynamicCast(OSBoolean,
- extPlist->getObject("OSKernelResource"));
- if (isKernelResourceObj && isKernelResourceObj->isTrue()) {
- isKernelResource = true;
- } else {
- isKernelResource = false;
- }
-
- if (extPlist->getObject("CFBundleExecutable")) {
- declaresExecutable = true;
- } else {
- declaresExecutable = false;
- }
-
- if (!isKernelResource && !declaresExecutable) {
- error = 0;
- goto finish;
- }
/* Okay, let's get started.
*/
goto finish;
}
- /* Don't add any entries that are not kernel resources and that declare no
- * executable. Such kexts have nothing to load and so don't belong in the
- * dependency list. Entries that are kernel resource *do* get added,
- * however, because such kexts get fake kmod entries for reference counting.
- */
- isKernelResourceObj = OSDynamicCast(OSBoolean,
- curExtPlist->getObject("OSKernelResource"));
- if (isKernelResourceObj && isKernelResourceObj->isTrue()) {
- isKernelResource = true;
- } else {
- isKernelResource = false;
- }
- if (curExtPlist->getObject("CFBundleExecutable")) {
- declaresExecutable = true;
- } else {
- declaresExecutable = false;
- }
-
- if (!isKernelResource && !declaresExecutable) {
- continue;
- }
-
dependencyList->setObject(curDepName);
}
/* Go backward through the original list, using the encounteredNames
* dictionary to check for duplicates. We put originalList in as the
- * value because we need some non-NULL value.
+ * value because we need some non-NULL value. Here we also drop any
+ * extensions that aren't proper dependencies (that is, any that are
+ * nonkernel kexts without code).
*/
i = originalList->getCount();
OSString * item = OSDynamicCast(OSString,
originalList->getObject(i));
- if ( ! encounteredNames->getObject(item) ) {
+ if ( (!encounteredNames->getObject(item)) &&
+ kextIsADependency(item)) {
+
encounteredNames->setObject(item, originalList);
dependencyList->setObject(item);
}
IOLog("kmod id %d successfully created at 0x%lx, size %ld.\n",
(unsigned int)kmod_id, link_buffer_address, link_buffer_size);
LOG_DELAY();
-#endif DEBUG
+#endif /* DEBUG */
/* Record dependencies for the newly-loaded kmod.
*/
finish:
if (kmod_info_freeme) {
- kfree(kmod_info_freeme, sizeof(kmod_info_t));
+ kfree((unsigned int)kmod_info_freeme, sizeof(kmod_info_t));
}
/* Only do a kld_unload_all() if at least one load happened.
if (kmod_dependencies) {
for (i = 0; i < num_dependencies; i++) {
if (kmod_dependencies[i]) {
- kfree(kmod_dependencies[i], sizeof(kmod_info_t));
+ kfree((unsigned int)kmod_dependencies[i], sizeof(kmod_info_t));
}
}
kfree((unsigned int)kmod_dependencies,
finish:
if (kmod_info) {
- kfree(kmod_info, sizeof(kmod_info_t));
+ kfree((unsigned int)kmod_info, sizeof(kmod_info_t));
}
if (dependencyList) {