VirtualBox

Changeset 74656 in vbox


Ignore:
Timestamp:
Oct 7, 2018 6:28:21 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
125548
Message:

IPRT/ldr: Working on parsing Mach-O code signing structures... bugref:9232

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/err.h

    r74638 r74656  
    23402340#define VERR_ASN1_CURSOR_BAD_LENGTH_ENCODING        (-22831)
    23412341/** Indefinite length form is against the rules. */
    2342 #define VERR_ASN1_CURSOR_ILLEGAL_IDEFINITE_LENGTH   (-22832)
    2343 /** Indefinite length form is not implemented. */
    2344 #define VERR_ASN1_CURSOR_IDEFINITE_LENGTH_NOT_SUP   (-22833)
     2342#define VERR_ASN1_CURSOR_ILLEGAL_INDEFINITE_LENGTH  (-22832)
     2343/** Malformed indefinite length encoding. */
     2344#define VERR_ASN1_CURSOR_BAD_INDEFINITE_LENGTH      (-22833)
    23452345/** ASN.1 object length goes beyond the end of the byte stream being decoded. */
    23462346#define VERR_ASN1_CURSOR_BAD_LENGTH                 (-22834)
     
    24712471/** Image hash mismatch. */
    24722472#define VERR_LDRVI_IMAGE_HASH_MISMATCH              (-22929)
     2473/** Malformed code signing structure. */
     2474#define VERR_LDRVI_BAD_CERT_FORMAT                  (-22930)
    24732475
    24742476/** Cannot resolve symbol because it's a forwarder. */
  • trunk/src/VBox/Runtime/common/asn1/asn1-cursor.cpp

    r73662 r74656  
    314314            /* Indefinite form. */
    315315            else if (pCursor->fFlags & RTASN1CURSOR_FLAGS_DER)
    316                 return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_ILLEGAL_IDEFINITE_LENGTH,
     316                return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_ILLEGAL_INDEFINITE_LENGTH,
    317317                                           "%s: Indefinite length form not allowed in DER mode (uTag=%#x).", pszErrorTag, uTag);
     318            else if (pCursor->cbLeft < 2)
     319                return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_BAD_INDEFINITE_LENGTH,
     320                                           "%s: Too little data left for indefinite BER/CER encoding (uTag=%#x)", pszErrorTag, uTag);
    318321            else
    319                 return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_IDEFINITE_LENGTH_NOT_SUP,
    320                                            "%s: Indefinite BER/CER length not supported (uTag=%#x)", pszErrorTag, uTag);
     322            {
     323                /* Search forward till we find the two terminating zero bytes. */
     324                cb = 0;
     325                for (;;)
     326                {
     327                    uint8_t const *pb = (uint8_t const *)memchr(&pCursor->pbCur[cb], 0x00, pCursor->cbLeft - cb - 1);
     328                    if (pb && pb[1] == 0x00)
     329                    {
     330                        cb = &pb[2] - pCursor->pbCur;
     331                        break;
     332                    }
     333                    if (!pb)
     334                        return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_BAD_INDEFINITE_LENGTH,
     335                                                   "%s: Could not find end of indefinite BER/CER record (uTag=%#x)", pszErrorTag, uTag);
     336                    cb = &pb[1] - pCursor->pbCur;
     337                }
     338            }
    321339        }
    322340
  • trunk/src/VBox/Runtime/common/ldr/ldrMachO.cpp

    r74650 r74656  
    55
    66/*
     7 * Copyright (C) 2018 Oracle Corporation
     8 *
     9 * This file is part of VirtualBox Open Source Edition (OSE), as
     10 * available from http://www.virtualbox.org. This file is free software;
     11 * you can redistribute it and/or modify it under the terms of the GNU
     12 * General Public License (GPL) as published by the Free Software
     13 * Foundation, in version 2 as it comes in the "COPYING" file of the
     14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
     15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
     16 * --------------------------------------------------------------------
     17 *
     18 * This code is based on:
     19 *
    720 * Copyright (c) 2006-2013 Knut St. Osmundsen <[email protected]>
    821 *
     
    4558
    4659#include <iprt/formats/mach-o.h>
     60#include <iprt/crypto/applecodesign.h>
    4761#include "internal/ldr.h"
    4862
     
    201215    uint8_t                 abImageUuid[16];
    202216
     217    /** The code signature offset.   */
     218    uint32_t                offCodeSignature;
     219    /** The code signature size (0 if not signed). */
     220    uint32_t                cbCodeSignature;
     221    /** Pointer to the code signature blob if loaded. */
     222    union
     223    {
     224        uint8_t                *pb;
     225        PCRTCRAPLCSSUPERBLOB    pSuper;
     226    }                       PtrCodeSignature;
     227
    203228    /** The RVA of the Global Offset Table. */
    204229    RTLDRADDR               GotRVA;
     
    228253
    229254
    230 static int  kldrModMachOPreParseLoadCommands(uint8_t *pbLoadCommands, const mach_header_32_t *pHdr, PRTLDRREADER pRdr, RTFOFF   offImage,
     255static int  kldrModMachOPreParseLoadCommands(uint8_t *pbLoadCommands, const mach_header_32_t *pHdr, PRTLDRREADER pRdr, RTFOFF offImage,
    231256                                             uint32_t fOpenFlags, uint32_t *pcSegments, uint32_t *pcSections, uint32_t *pcbStringPool,
    232257                                             bool *pfCanLoad, PRTLDRADDR pLinkAddress, uint8_t *puEffFileType, PRTERRINFO pErrInfo);
     
    467492    pThis->pchStrings = NULL;
    468493    memset(pThis->abImageUuid, 0, sizeof(pThis->abImageUuid));
     494    pThis->offCodeSignature = 0;
     495    pThis->cbCodeSignature = 0;
     496    pThis->PtrCodeSignature.pb = NULL;
    469497    pThis->GotRVA = NIL_RTLDRADDR;
    470498    pThis->JmpStubsRVA = NIL_RTLDRADDR;
     
    10741102    union
    10751103    {
    1076         const uint8_t              *pb;
    1077         const load_command_t       *pLoadCmd;
    1078         const segment_command_32_t *pSeg32;
    1079         const segment_command_64_t *pSeg64;
    1080         const symtab_command_t     *pSymTab;
    1081         const uuid_command_t       *pUuid;
     1104        const uint8_t                 *pb;
     1105        const load_command_t          *pLoadCmd;
     1106        const segment_command_32_t    *pSeg32;
     1107        const segment_command_64_t    *pSeg64;
     1108        const symtab_command_t        *pSymTab;
     1109        const uuid_command_t          *pUuid;
     1110        const linkedit_data_command_t *pData;
    10821111    } u;
    10831112    uint32_t cLeft = pThis->Hdr.ncmds;
     
    12751304                break;
    12761305
     1306            case LC_CODE_SIGNATURE:
     1307                pThis->offCodeSignature = u.pData->dataoff;
     1308                pThis->cbCodeSignature  = u.pData->datasize;
     1309                break;
     1310
    12771311            default:
    12781312                break;
     
    14431477    RTMemFree(pThis->pvaSymbols);
    14441478    pThis->pvaSymbols = NULL;
     1479    RTMemFree(pThis->PtrCodeSignature.pb);
     1480    pThis->PtrCodeSignature.pb = NULL;
    14451481
    14461482    return VINF_SUCCESS;
     
    37573793
    37583794
     3795/**
     3796 * Loads the code signing blob if necessary (RTLDRMODMACHO::PtrCodeSignature).
     3797 *
     3798 * @returns IPRT status code.
     3799 * @param   pThis               The mach-o instance.
     3800 */
     3801static int rtldrMachO_LoadSignatureBlob(PRTLDRMODMACHO pThis)
     3802{
     3803    Assert(pThis->cbCodeSignature > 0);
     3804    if (pThis->PtrCodeSignature.pb != NULL)
     3805        return VINF_SUCCESS;
     3806
     3807    if (   pThis->cbCodeSignature > sizeof(RTCRAPLCSHDR)
     3808        && pThis->cbCodeSignature <= _1M)
     3809    {
     3810        /* Allocate and read. */
     3811        void *pv = RTMemAllocZ(RT_ALIGN_Z(pThis->cbCodeSignature, 16));
     3812        AssertReturn(pv, VERR_NO_MEMORY);
     3813        int rc = pThis->Core.pReader->pfnRead(pThis->Core.pReader, pv, pThis->cbCodeSignature, pThis->offCodeSignature);
     3814        if (RT_SUCCESS(rc))
     3815        {
     3816            /* Check blob signature. */
     3817            PCRTCRAPLCSSUPERBLOB pSuper = (PCRTCRAPLCSSUPERBLOB)pv;
     3818            if (pSuper->Hdr.uMagic == RTCRAPLCS_MAGIC_EMBEDDED_SIGNATURE)
     3819            {
     3820                uint32_t cbHdr  = RT_BE2H_U32(pSuper->Hdr.cb);
     3821                uint32_t cSlots = RT_BE2H_U32(pSuper->cSlots);
     3822                if (   cbHdr  <= pThis->cbCodeSignature
     3823                    && cbHdr  >  RT_UOFFSETOF(RTCRAPLCSSUPERBLOB, aSlots)
     3824                    && cSlots >  0
     3825                    && cSlots <  128
     3826                    && RT_UOFFSETOF_DYN(RTCRAPLCSSUPERBLOB, aSlots[cSlots]) <= cbHdr)
     3827                {
     3828                    pThis->PtrCodeSignature.pSuper = pSuper;
     3829                    return VINF_SUCCESS;
     3830                }
     3831                rc = VERR_LDRVI_BAD_CERT_HDR_LENGTH;
     3832            }
     3833            else
     3834                rc = VERR_LDRVI_BAD_CERT_HDR_TYPE;
     3835        }
     3836        RTMemFree(pv);
     3837        return rc;
     3838    }
     3839    return VERR_LDRVI_INVALID_SECURITY_DIR_ENTRY;
     3840}
     3841
     3842
     3843/**
     3844 * Handles a RTLDRPROP_PKCS7_SIGNED_DATA query.
     3845 */
     3846static int rtldrMachO_QueryPkcs7SignedData(PRTLDRMODMACHO pThis, void *pvBuf, size_t cbBuf, size_t *pcbRet)
     3847{
     3848    int rc = rtldrMachO_LoadSignatureBlob(pThis);
     3849    if (RT_SUCCESS(rc))
     3850    {
     3851        /*
     3852         * Locate the signature slot.
     3853         */
     3854        uint32_t            iSlot = RT_BE2H_U32(pThis->PtrCodeSignature.pSuper->cSlots);
     3855        PCRTCRAPLCSBLOBSLOT pSlot = &pThis->PtrCodeSignature.pSuper->aSlots[iSlot];
     3856        while (iSlot-- > 0)
     3857        {
     3858            pSlot--;
     3859            if (pSlot->uType == RTCRAPLCS_SLOT_SIGNATURE)
     3860            {
     3861                /*
     3862                 * Validate the data offset.
     3863                 */
     3864                uint32_t offData = RT_BE2H_U32(pSlot->offData);
     3865                if (   offData < pThis->cbCodeSignature - sizeof(RTCRAPLCSHDR)
     3866                    || !(offData & 3) )
     3867                {
     3868                    /*
     3869                     * The data is prefixed by a header with magic set to blob wrapper.
     3870                     * Check that the size is within the bounds of the code signing blob.
     3871                     */
     3872                    PCRTCRAPLCSHDR pHdr = (PCRTCRAPLCSHDR)&pThis->PtrCodeSignature.pb[offData];
     3873                    if (pHdr->uMagic == RTCRAPLCS_MAGIC_BLOBWRAPPER)
     3874                    {
     3875                        uint32_t cbData = RT_BE2H_U32(pHdr->cb);
     3876                        uint32_t cbMax  = pThis->cbCodeSignature - offData ;
     3877                        if (   cbData <= cbMax
     3878                            && cbData > sizeof(RTCRAPLCSHDR))
     3879                        {
     3880                            /*
     3881                             * Copy out the requirest data.
     3882                             */
     3883                            *pcbRet = cbData;
     3884                            if (cbData <= cbBuf)
     3885                            {
     3886                                memcpy(pvBuf, pHdr + 1, cbData);
     3887                                return VINF_SUCCESS;
     3888                            }
     3889                            memcpy(pvBuf, pHdr + 1, cbBuf);
     3890                            return VERR_BUFFER_OVERFLOW;
     3891                        }
     3892                    }
     3893                }
     3894                return VERR_LDRVI_BAD_CERT_FORMAT;
     3895            }
     3896        }
     3897        rc = VERR_NOT_FOUND;
     3898    }
     3899    return rc;
     3900}
     3901
     3902
    37593903/** @interface_method_impl{RTLDROPS,pfnQueryProp} */
    37603904static DECLCALLBACK(int) rtldrMachO_QueryProp(PRTLDRMODINTERNAL pMod, RTLDRPROP enmProp, void const *pvBits,
    37613905                                              void *pvBuf, size_t cbBuf, size_t *pcbRet)
    37623906{
    3763     PRTLDRMODMACHO pThis = RT_FROM_MEMBER(pMod, RTLDRMODMACHO, Core);
    3764     int           rc;
     3907    PRTLDRMODMACHO  pThis = RT_FROM_MEMBER(pMod, RTLDRMODMACHO, Core);
     3908    int             rc    = VERR_NOT_FOUND;
    37653909    switch (enmProp)
    37663910    {
     
    37713915                *pcbRet = sizeof(pThis->abImageUuid);
    37723916                memcpy(pvBuf, pThis->abImageUuid, sizeof(pThis->abImageUuid));
    3773                 rc = VINF_SUCCESS;
     3917                return VINF_SUCCESS;
    37743918            }
     3919            break;
     3920
     3921        case RTLDRPROP_FILE_OFF_HEADER:
     3922            Assert(cbBuf == sizeof(uint32_t) || cbBuf == sizeof(uint64_t));
     3923            if (cbBuf == sizeof(uint32_t))
     3924                *(uint32_t *)pvBuf = pThis->offImage;
    37753925            else
    3776                 rc = VERR_NOT_FOUND;
     3926                *(uint64_t *)pvBuf = pThis->offImage;
     3927            return VINF_SUCCESS;
     3928
     3929        case RTLDRPROP_IS_SIGNED:
     3930            Assert(cbBuf == sizeof(bool));
     3931            Assert(*pcbRet == cbBuf);
     3932            *(bool *)pvBuf = pThis->cbCodeSignature > 0;
     3933            return VINF_SUCCESS;
     3934
     3935        case RTLDRPROP_PKCS7_SIGNED_DATA:
     3936            if (pThis->cbCodeSignature > 0)
     3937                return rtldrMachO_QueryPkcs7SignedData(pThis, pvBuf, cbBuf, pcbRet);
    37773938            break;
     3939
    37783940
    37793941#if 0 /** @todo return LC_ID_DYLIB */
     
    37823944
    37833945        default:
    3784             rc = VERR_NOT_FOUND;
    37853946            break;
    37863947    }
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette