X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/0a7de7458d150b5d4dffc935ba399be265ef0a1a..c3c9b80d004dbbfdf763edeb97968c6997e3b45b:/libkern/OSKextLib.cpp diff --git a/libkern/OSKextLib.cpp b/libkern/OSKextLib.cpp index 4fff0ba81..4a2cc377b 100644 --- a/libkern/OSKextLib.cpp +++ b/libkern/OSKextLib.cpp @@ -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