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);
}
Esempio n. 2
0
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;
}