void logUsedKexts( KcgenArgs * toolArgs, CFArrayRef prelinkKexts) { int fd; int ret; char * kextTracePath; char tmpBuffer[PATH_MAX + 1 + 1]; size_t tmpBufLen; ssize_t writeSize; CFIndex count, i; /* Log used kext bundle identifiers to out-of-band log file */ kextTracePath = getenv("KEXT_TRACE_FILE"); if (!kextTracePath) { return; } fd = open(kextTracePath, O_WRONLY|O_APPEND|O_CREAT, DEFFILEMODE); if (fd < 0) { return; } snprintf(tmpBuffer, sizeof(tmpBuffer), "%s\n", toolArgs->prelinkedKernelPath); tmpBufLen = strlen(tmpBuffer); writeSize = write(fd, tmpBuffer, tmpBufLen); if (writeSize != (ssize_t)tmpBufLen) { close(fd); return; } count = CFArrayGetCount(prelinkKexts); for (i = 0; i < count; i++) { CFStringRef kextID; OSKextRef theKext = (OSKextRef)CFArrayGetValueAtIndex(prelinkKexts, i); kextID = OSKextGetIdentifier(theKext); if (kextID) { char kextIDCString[KMOD_MAX_NAME]; CFStringGetCString(kextID, kextIDCString, sizeof(kextIDCString), kCFStringEncodingUTF8); snprintf(tmpBuffer, sizeof(tmpBuffer), "[Logging for XBS] Used kext bundle identifier: %s\n", kextIDCString); tmpBufLen = strlen(tmpBuffer); writeSize = write(fd, tmpBuffer, tmpBufLen); if (writeSize != (ssize_t)tmpBufLen) { close(fd); return; } } } close(fd); }
void printKext( OSKextRef theKext, PathSpec pathSpec, Boolean extra_info, char lineEnd) { CFStringRef bundleID = NULL; // do NOT release CFStringRef bundleVersion = NULL; // do NOT release CFStringRef kextPath = NULL; // must release char * kext_path = NULL; // must free char * bundle_id = NULL; // must free char * bundle_version = NULL; // must free kextPath = copyPathForKext(theKext, pathSpec); if (!kextPath) { OSKextLogMemError(); goto finish; } kext_path = createUTF8CStringForCFString(kextPath); if (!kext_path) { OSKextLogMemError(); goto finish; } if (extra_info) { bundleID = OSKextGetIdentifier(theKext); bundleVersion = OSKextGetValueForInfoDictionaryKey(theKext, kCFBundleVersionKey); bundle_id = createUTF8CStringForCFString(bundleID); bundle_version = createUTF8CStringForCFString(bundleVersion); if (!bundle_id || !bundle_version) { OSKextLogMemError(); goto finish; } fprintf(stdout, "%s\t%s\t%s%c", kext_path, bundle_id, bundle_version, lineEnd); } else { fprintf(stdout, "%s%c", kext_path, lineEnd); } finish: SAFE_RELEASE(kextPath); SAFE_FREE(kext_path); SAFE_FREE(bundle_id); SAFE_FREE(bundle_version); return; }
CFDataRef createMkext1ForArch(const NXArchInfo * arch, CFArrayRef archiveKexts, boolean_t compress) { CFMutableDataRef result = NULL; CFMutableDictionaryRef kextsByIdentifier = NULL; Mkext1Context context; mkext1_header * mkextHeader = NULL; // do not free const uint8_t * adler_point = 0; CFIndex count, i; result = CFDataCreateMutable(kCFAllocatorDefault, /* capaacity */ 0); if (!result || !createCFMutableDictionary(&kextsByIdentifier)) { OSKextLogMemError(); goto finish; } /* mkext1 can only contain 1 kext for a given bundle identifier, so we * have to pick out the most recent versions. */ count = CFArrayGetCount(archiveKexts); for (i = 0; i < count; i++) { OSKextRef theKext = (OSKextRef)CFArrayGetValueAtIndex(archiveKexts, i); CFStringRef bundleIdentifier = OSKextGetIdentifier(theKext); OSKextRef savedKext = (OSKextRef)CFDictionaryGetValue(kextsByIdentifier, bundleIdentifier); OSKextVersion thisVersion, savedVersion; if (!OSKextSupportsArchitecture(theKext, arch)) { continue; } if (!savedKext) { CFDictionarySetValue(kextsByIdentifier, bundleIdentifier, theKext); continue; } thisVersion = OSKextGetVersion(theKext); savedVersion = OSKextGetVersion(savedKext); if (thisVersion > savedVersion) { CFDictionarySetValue(kextsByIdentifier, bundleIdentifier, theKext); } } /* Add room for the mkext header and kext descriptors. */ CFDataSetLength(result, sizeof(mkext1_header) + CFDictionaryGetCount(kextsByIdentifier) * sizeof(mkext_kext)); context.mkext = result; context.kextIndex = 0; context.compressOffset = (uint32_t)CFDataGetLength(result); context.arch = arch; context.fatal = false; context.compress = compress; CFDictionaryApplyFunction(kextsByIdentifier, addToMkext1, &context); if (context.fatal) { SAFE_RELEASE_NULL(result); goto finish; } mkextHeader = (mkext1_header *)CFDataGetBytePtr(result); mkextHeader->magic = OSSwapHostToBigInt32(MKEXT_MAGIC); mkextHeader->signature = OSSwapHostToBigInt32(MKEXT_SIGN); mkextHeader->version = OSSwapHostToBigInt32(0x01008000); // 'vers' 1.0.0 mkextHeader->numkexts = OSSwapHostToBigInt32((__uint32_t)CFDictionaryGetCount(kextsByIdentifier)); mkextHeader->cputype = OSSwapHostToBigInt32(arch->cputype); mkextHeader->cpusubtype = OSSwapHostToBigInt32(arch->cpusubtype); mkextHeader->length = OSSwapHostToBigInt32((__uint32_t)CFDataGetLength(result)); adler_point = (UInt8 *)&mkextHeader->version; mkextHeader->adler32 = OSSwapHostToBigInt32(local_adler32( (UInt8 *)&mkextHeader->version, (int)(CFDataGetLength(result) - (adler_point - (uint8_t *)mkextHeader)))); OSKextLog(/* kext */ NULL, kOSKextLogProgressLevel | kOSKextLogArchiveFlag, "Created mkext for %s containing %lu kexts.", arch->name, CFDictionaryGetCount(kextsByIdentifier)); finish: SAFE_RELEASE(kextsByIdentifier); return result; }