]> git.saurik.com Git - apple/xnu.git/blobdiff - libkern/OSKextLib.cpp
xnu-7195.101.1.tar.gz
[apple/xnu.git] / libkern / OSKextLib.cpp
index 4fff0ba813a182d45c32fcdba0e7988c646dc707..4a2cc377b49074a377309abfa3f97a7afc2b74fe 100644 (file)
@@ -74,6 +74,12 @@ finish:
 
 /*********************************************************************
 *********************************************************************/
+
+// FIXME: Implementation of this function is hidden from the static analyzer.
+// The analyzer is worried about the lack of release and suggests
+// refactoring the code into the typical non-owning container pattern.
+// Feel free to remove the #ifndef and address the warning!
+#ifndef __clang_analyzer__
 OSReturn
 OSKextRetainKextWithLoadTag(uint32_t loadTag)
 {
@@ -108,9 +114,16 @@ OSKextRetainKextWithLoadTag(uint32_t loadTag)
 finish:
        return result;
 }
+#endif // __clang_analyzer__
 
 /*********************************************************************
 *********************************************************************/
+
+// FIXME: Implementation of this function is hidden from the static analyzer.
+// The analyzer is worried about the double release and suggests
+// refactoring the code into the typical non-owning container pattern.
+// Feel free to remove the #ifndef and address the warning!
+#ifndef __clang_analyzer__
 OSReturn
 OSKextReleaseKextWithLoadTag(uint32_t loadTag)
 {
@@ -146,6 +159,7 @@ OSKextReleaseKextWithLoadTag(uint32_t loadTag)
 finish:
        return result;
 }
+#endif // __clang_analyzer__
 
 /*********************************************************************
 * Not to be called by the kext being unloaded!
@@ -190,9 +204,12 @@ OSKextCancelRequest(
 #pragma mark MIG Functions & Wrappers
 #endif
 /*********************************************************************
-* IMPORTANT: Once we have done the vm_map_copyout(), we *must* return
-* KERN_SUCCESS or the kernel map gets messed up (reason as yet
-* unknown). We use op_result to return the real result of our work.
+* IMPORTANT: vm_map_copyout_size() consumes the requestIn copy
+* object on success. Therefore once it has been invoked successfully,
+* this routine *must* return KERN_SUCCESS, regardless of our actual
+* result. Our contract with the caller is that requestIn must be
+* caller-deallocated if we return an error. We use op_result to return
+* the real result of our work.
 *********************************************************************/
 kern_return_t
 kext_request(
@@ -222,9 +239,9 @@ kext_request(
         * just in case, or MIG will try to copy out bogus data.
         */
        *op_result = KERN_FAILURE;
-       *responseOut = NULL;
+       *responseOut = 0;
        *responseLengthOut = 0;
-       *logDataOut = NULL;
+       *logDataOut = 0;
        *logDataLengthOut = 0;
 
        /* Check for input. Don't discard what isn't there, though.
@@ -238,17 +255,17 @@ kext_request(
                goto finish;
        }
 
-       /* Once we have done the vm_map_copyout(), we *must* return KERN_SUCCESS
-        * or the kernel map gets messed up (reason as yet unknown). We will use
-        * op_result to return the real result of our work.
-        */
-       result = vm_map_copyout(kernel_map, &map_addr, (vm_map_copy_t)requestIn);
+       result = vm_map_copyout_size(kernel_map, &map_addr, (vm_map_copy_t)requestIn, requestLengthIn);
        if (result != KERN_SUCCESS) {
                OSKextLog(/* kext */ NULL,
                    kOSKextLogErrorLevel |
                    kOSKextLogIPCFlag,
                    "vm_map_copyout() failed for request from user space.");
-               vm_map_copy_discard((vm_map_copy_t)requestIn);
+               /*
+                * If we return an error it is our caller's responsibility to
+                * deallocate the requestIn copy object, so do not deallocate it
+                * here. See comment above.
+                */
                goto finish;
        }
        request = CAST_DOWN(char *, map_addr);
@@ -267,7 +284,7 @@ kext_request(
        }
 
        if (isMkext) {
-#ifdef SECURE_KERNEL
+#if defined(SECURE_KERNEL) || !CONFIG_KXLD
                // xxx - something tells me if we have a secure kernel we don't even
                // xxx - want to log a message here. :-)
                *op_result = KERN_NOT_SUPPORTED;
@@ -314,7 +331,7 @@ kext_request(
                            kOSKextLogIPCFlag,
                            "Failed to copy response to request from user space.");
                        *op_result = copyin_result; // xxx - should we map to our own code?
-                       *responseOut = NULL;
+                       *responseOut = 0;
                        *responseLengthOut = 0;
                        goto finish;
                }
@@ -334,7 +351,7 @@ kext_request(
                            kOSKextLogIPCFlag,
                            "Failed to copy log data for request from user space.");
                        *op_result = copyin_result; // xxx - should we map to our own code?
-                       *logDataOut = NULL;
+                       *logDataOut = 0;
                        *logDataLengthOut = 0;
                        goto finish;
                }
@@ -360,21 +377,32 @@ finish:
 * Gets the vm_map for the current kext
 *********************************************************************/
 extern vm_offset_t segPRELINKTEXTB;
+extern vm_offset_t segLINKB;
 extern unsigned long segSizePRELINKTEXT;
-extern int kth_started;
 extern vm_map_t g_kext_map;
 
 vm_map_t
 kext_get_vm_map(kmod_info_t *info)
 {
        vm_map_t kext_map = NULL;
-
-       /* Set the vm map */
-       if ((info->address >= segPRELINKTEXTB) &&
-           (info->address < (segPRELINKTEXTB + segSizePRELINKTEXT))) {
-               kext_map = kernel_map;
+       kc_format_t kcformat;
+
+       if (PE_get_primary_kc_format(&kcformat) && kcformat == KCFormatFileset) {
+               /* Check if the kext is from the boot KC */
+               assert(segLINKB >= (segPRELINKTEXTB + segSizePRELINKTEXT));
+               if ((info->address >= segPRELINKTEXTB) &&
+                   (info->address < segLINKB)) {
+                       kext_map = kernel_map;
+               } else {
+                       kext_map = g_kext_map;
+               }
        } else {
-               kext_map = g_kext_map;
+               if ((info->address >= segPRELINKTEXTB) &&
+                   (info->address < (segPRELINKTEXTB + segSizePRELINKTEXT))) {
+                       kext_map = kernel_map;
+               } else {
+                       kext_map = g_kext_map;
+               }
        }
 
        return kext_map;
@@ -392,7 +420,7 @@ kext_weak_symbol_referenced(void)
        panic("A kext referenced an unresolved weak symbol\n");
 }
 
-const void *gOSKextUnresolved = (const void *)&kext_weak_symbol_referenced;
+const void * const gOSKextUnresolved = (const void *)&kext_weak_symbol_referenced;
 
 #if PRAGMA_MARK
 #pragma mark Kernel-Internal C Functions