/*********************************************************************
*********************************************************************/
+
+// 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)
{
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)
{
finish:
return result;
}
+#endif // __clang_analyzer__
/*********************************************************************
* Not to be called by the kext being unloaded!
#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(
* 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.
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);
}
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;
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;
}
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;
}
* 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;
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