]> git.saurik.com Git - apple/xnu.git/blobdiff - libsa/catalogue.cpp
xnu-792.18.15.tar.gz
[apple/xnu.git] / libsa / catalogue.cpp
index 1c4c563bf13cac959779fb2f9f6a314aae3f9388..8d8b019db91a2b446c14a426c471940929cb2c6b 100644 (file)
@@ -29,6 +29,7 @@
 #include <IOKit/IODeviceTreeSupport.h>
 #include <IOKit/IORegistryEntry.h>
 #include <IOKit/IOCatalogue.h>
 #include <IOKit/IODeviceTreeSupport.h>
 #include <IOKit/IORegistryEntry.h>
 #include <IOKit/IOCatalogue.h>
+#include <IOKit/IOKitKeysPrivate.h>
 #include <libkern/c++/OSUnserialize.h>
 #include <libkern/OSByteOrder.h>
 #include <libsa/catalogue.h>
 #include <libkern/c++/OSUnserialize.h>
 #include <libkern/OSByteOrder.h>
 #include <libsa/catalogue.h>
@@ -117,6 +118,7 @@ bool validateExtensionDict(OSDictionary * extension, int index) {
     bool id_missing = false;
     bool is_kernel_resource = false;
     bool has_executable = false;
     bool id_missing = false;
     bool is_kernel_resource = false;
     bool has_executable = false;
+    bool ineligible_for_safe_boot = false;
     OSString * bundleIdentifier = NULL;    // do not release
     OSObject * rawValue = NULL;            // do not release
     OSString * stringValue = NULL;         // do not release
     OSString * bundleIdentifier = NULL;    // do not release
     OSObject * rawValue = NULL;            // do not release
     OSString * stringValue = NULL;         // do not release
@@ -127,6 +129,7 @@ bool validateExtensionDict(OSDictionary * extension, int index) {
     OSString * key = NULL;                 // do not release
     VERS_version vers;
     VERS_version compatible_vers;
     OSString * key = NULL;                 // do not release
     VERS_version vers;
     VERS_version compatible_vers;
+    char namep[16];      // unused but needed for PE_parse_boot_arg()
 
     // Info dict is a dictionary
     if (!OSDynamicCast(OSDictionary, extension)) {
 
     // Info dict is a dictionary
     if (!OSDynamicCast(OSDictionary, extension)) {
@@ -349,9 +352,10 @@ bool validateExtensionDict(OSDictionary * extension, int index) {
         keyIterator = NULL;
     }
 
         keyIterator = NULL;
     }
 
-    // OSBundleRequired is a legal value - *not* required at boot time
-    // so we can do install CDs and the like with mkext files containing
-    // all normally-used drivers.
+    // OSBundleRequired, if present, must have a legal value.
+    // If it is not present and if we are safe-booting,
+    // then the kext is not eligible.
+    //
     rawValue = extension->getObject("OSBundleRequired");
     if (rawValue) {
         stringValue = OSDynamicCast(OSString, rawValue);
     rawValue = extension->getObject("OSBundleRequired");
     if (rawValue) {
         stringValue = OSDynamicCast(OSString, rawValue);
@@ -369,6 +373,10 @@ bool validateExtensionDict(OSDictionary * extension, int index) {
             goto finish;
         }
 
             goto finish;
         }
 
+    } else if (PE_parse_boot_arg("-x", namep)) { /* safe boot */
+        ineligible_for_safe_boot = true;
+        result = false;
+        goto finish;
     }
 
 
     }
 
 
@@ -376,19 +384,24 @@ finish:
     if (keyIterator)   keyIterator->release();
 
     if (!result) {
     if (keyIterator)   keyIterator->release();
 
     if (!result) {
-        if (not_a_dict) {
+        if (ineligible_for_safe_boot) {
+            IOLog(VTYELLOW "Skipping extension \"%s\" during safe boot "
+                "(no OSBundleRequired property)\n"
+                VTRESET,
+                bundleIdentifier->getCStringNoCopy());
+        } else if (not_a_dict) {
             if (index > -1) {
             if (index > -1) {
-                IOLog(VTYELLOW "mkext entry %d:." VTRESET, index);
+                IOLog(VTYELLOW "mkext entry %d: " VTRESET, index);
             } else {
             } else {
-                IOLog(VTYELLOW "kernel extension" VTRESET);
+                IOLog(VTYELLOW "kernel extension " VTRESET);
             }
             IOLog(VTYELLOW "info dictionary isn't a dictionary\n"
                 VTRESET);
         } else if (id_missing) {
             if (index > -1) {
             }
             IOLog(VTYELLOW "info dictionary isn't a dictionary\n"
                 VTRESET);
         } else if (id_missing) {
             if (index > -1) {
-                IOLog(VTYELLOW "mkext entry %d:." VTRESET, index);
+                IOLog(VTYELLOW "mkext entry %d: " VTRESET, index);
             } else {
             } else {
-                IOLog(VTYELLOW "kernel extension" VTRESET);
+                IOLog(VTYELLOW "kernel extension " VTRESET);
             }
             IOLog(VTYELLOW "\"CFBundleIdentifier\" property is "
                 "missing or not a string\n"
             }
             IOLog(VTYELLOW "\"CFBundleIdentifier\" property is "
                 "missing or not a string\n"
@@ -712,13 +725,12 @@ OSDictionary * readExtension(OSDictionary * propertyDict,
         bootxDriverDataObject->getBytesNoCopy(0,
         sizeof(MemoryMapFileInfo));
 #if defined (__ppc__)
         bootxDriverDataObject->getBytesNoCopy(0,
         sizeof(MemoryMapFileInfo));
 #if defined (__ppc__)
-    dataBuffer = (BootxDriverInfo *)ml_static_ptovirt(
-      driverInfo->paddr);
+    dataBuffer = (BootxDriverInfo *)ml_static_ptovirt(driverInfo->paddr);
 #elif defined (__i386__)
 #elif defined (__i386__)
-    dataBuffer = (BootxDriverInfo *)driverInfo->paddr;
-    dataBuffer->plistAddr = ml_static_ptovirt(dataBuffer->plistAddr);
+    dataBuffer = (BootxDriverInfo *)ml_boot_ptovirt(driverInfo->paddr);
+    dataBuffer->plistAddr = (char *)ml_boot_ptovirt((vm_address_t)dataBuffer->plistAddr);
     if (dataBuffer->moduleAddr)
     if (dataBuffer->moduleAddr)
-      dataBuffer->moduleAddr = ml_static_ptovirt(dataBuffer->moduleAddr);
+      dataBuffer->moduleAddr = (void *)ml_boot_ptovirt((vm_address_t)dataBuffer->moduleAddr);
 #else
 #error unsupported architecture
 #endif
 #else
 #error unsupported architecture
 #endif
@@ -807,7 +819,7 @@ OSDictionary * readExtension(OSDictionary * propertyDict,
 finish:
 
     if (loaded_kmod) {
 finish:
 
     if (loaded_kmod) {
-        kfree((unsigned int)loaded_kmod, sizeof(kmod_info_t));
+        kfree(loaded_kmod, sizeof(kmod_info_t));
     }
 
     // do not release bootxDriverDataObject
     }
 
     // do not release bootxDriverDataObject
@@ -957,7 +969,7 @@ bool extractExtensionsFromArchive(MemoryMapFileInfo * mkext_file_info,
 #if defined (__ppc__)
     mkext_data = (mkext_header *)mkext_file_info->paddr;
 #elif defined (__i386__)
 #if defined (__ppc__)
     mkext_data = (mkext_header *)mkext_file_info->paddr;
 #elif defined (__i386__)
-    mkext_data = (mkext_header *)ml_static_ptovirt(mkext_file_info->paddr);
+    mkext_data = (mkext_header *)ml_boot_ptovirt(mkext_file_info->paddr);
 #else
 #error unsupported architecture
 #endif
 #else
 #error unsupported architecture
 #endif
@@ -989,6 +1001,16 @@ bool extractExtensionsFromArchive(MemoryMapFileInfo * mkext_file_info,
         goto finish;
     }
 
         goto finish;
     }
 
+    IORegistryEntry * root = IORegistryEntry::getRegistryRoot();
+    assert(root);
+    OSData * checksumObj = OSData::withBytes((void *)&checksum,
+        sizeof(checksum));
+    assert(checksumObj);
+    if (checksumObj) {
+        root->setProperty(kIOStartupMkextCRC, checksumObj);
+        checksumObj->release();
+    }
+
    /* If the MKEXT archive isn't fat, check that the CPU type & subtype
     * match that of the running kernel.
     */
    /* If the MKEXT archive isn't fat, check that the CPU type & subtype
     * match that of the running kernel.
     */
@@ -1030,7 +1052,7 @@ bool extractExtensionsFromArchive(MemoryMapFileInfo * mkext_file_info,
          i++) {
 
         if (loaded_kmod) {
          i++) {
 
         if (loaded_kmod) {
-            kfree((unsigned int)loaded_kmod, sizeof(kmod_info_t));
+            kfree(loaded_kmod, sizeof(kmod_info_t));
             loaded_kmod = 0;
         }
 
             loaded_kmod = 0;
         }
 
@@ -1208,7 +1230,7 @@ bool extractExtensionsFromArchive(MemoryMapFileInfo * mkext_file_info,
 
 finish:
 
 
 finish:
 
-    if (loaded_kmod) kfree((unsigned int)loaded_kmod, sizeof(kmod_info_t));
+    if (loaded_kmod) kfree(loaded_kmod, sizeof(kmod_info_t));
     if (driverPlistDataObject) {
         kmem_free(kernel_map,
             (unsigned int)driverPlistDataObject->getBytesNoCopy(),
     if (driverPlistDataObject) {
         kmem_free(kernel_map,
             (unsigned int)driverPlistDataObject->getBytesNoCopy(),