Exemple #1
0
/**
 * Internal. Free all allocated space for representing an image except pImage,
 * and optionally delete the image from disk.
 */
static int rawFreeImage(PRAWIMAGE pImage, bool fDelete)
{
    int rc = VINF_SUCCESS;

    /* Freeing a never allocated image (e.g. because the open failed) is
     * not signalled as an error. After all nothing bad happens. */
    if (pImage)
    {
        if (pImage->pStorage)
        {
            /* No point updating the file that is deleted anyway. */
            if (!fDelete)
            {
                /* For newly created images in sequential mode fill it to
                 * the nominal size. */
                if (   pImage->uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL
                    && !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
                    && pImage->fCreate)
                {
                    /* Fill rest of image with zeroes, a must for sequential
                     * images to reach the nominal size. */
                    uint64_t uOff;
                    void *pvBuf = RTMemTmpAllocZ(RAW_FILL_SIZE);
                    if (!pvBuf)
                        goto out;

                    uOff = pImage->offAccess;
                    /* Write data to all image blocks. */
                    while (uOff < pImage->cbSize)
                    {
                        unsigned cbChunk = (unsigned)RT_MIN(pImage->cbSize - uOff,
                                                            RAW_FILL_SIZE);

                        rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage,
                                                    uOff, pvBuf, cbChunk);
                        if (RT_FAILURE(rc))
                            goto out;

                        uOff += cbChunk;
                    }
out:
                    if (pvBuf)
                        RTMemTmpFree(pvBuf);
                }
                rawFlushImage(pImage);
            }

            rc = vdIfIoIntFileClose(pImage->pIfIo, pImage->pStorage);
            pImage->pStorage = NULL;
        }

        if (fDelete && pImage->pszFilename)
            vdIfIoIntFileDelete(pImage->pIfIo, pImage->pszFilename);
    }

    LogFlowFunc(("returns %Rrc\n", rc));
    return rc;
}
Exemple #2
0
/**
 * Adds an entry for a file with the specified set of attributes.
 *
 * @returns IPRT status code.
 *
 * @param   hManifest           The manifest handle.
 * @param   hVfsIos             The I/O stream handle of the entry.  This will
 *                              be processed to its end on successful return.
 *                              (Must be positioned at the start to get
 *                              the expected results.)
 * @param   pszEntry            The entry name.
 * @param   fAttrs              The attributes to create for this stream.
 */
RTDECL(int) RTManifestEntryAddIoStream(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos, const char *pszEntry, uint32_t fAttrs)
{
    /*
     * Note! This is a convenicence function, so just use the available public
     *       methods to get the job done.
     */
    AssertReturn(fAttrs < RTMANIFEST_ATTR_END, VERR_INVALID_PARAMETER);
    AssertPtr(pszEntry);

    /*
     * Allocate and initialize the hash contexts, hash digests and I/O buffer.
     */
    PRTMANIFESTHASHES pHashes = rtManifestHashesCreate(fAttrs);
    if (!pHashes)
        return VERR_NO_TMP_MEMORY;

    int         rc;
    size_t      cbBuf = _1M;
    void       *pvBuf = RTMemTmpAlloc(cbBuf);
    if (RT_UNLIKELY(!pvBuf))
    {
        cbBuf = _4K;
        pvBuf = RTMemTmpAlloc(cbBuf);
    }
    if (RT_LIKELY(pvBuf))
    {
        /*
         * Process the stream data.
         */
        for (;;)
        {
            size_t cbRead;
            rc = RTVfsIoStrmRead(hVfsIos, pvBuf, cbBuf, true /*fBlocking*/, &cbRead);
            if (   (rc == VINF_EOF && cbRead == 0)
                || RT_FAILURE(rc))
                break;
            rtManifestHashesUpdate(pHashes, pvBuf, cbRead);
        }
        RTMemTmpFree(pvBuf);
        if (RT_SUCCESS(rc))
        {
            /*
             * Add the entry with the finalized hashes.
             */
            rtManifestHashesFinal(pHashes);
            rc = RTManifestEntryAdd(hManifest, pszEntry);
            if (RT_SUCCESS(rc))
                rc = rtManifestHashesSetAttrs(pHashes, hManifest, pszEntry);
        }
    }
    else
    {
        rtManifestHashesDestroy(pHashes);
        rc = VERR_NO_TMP_MEMORY;
    }
    return rc;
}
static void tst1(size_t cTest, size_t cchDigits, char chSep)
{
    RTTestISubF("tst #%u (digits: %u; sep: %c)", cTest, cchDigits, chSep ? chSep : ' ');

    /* We try to create max possible + one. */
    size_t cTimes = 1;
    for (size_t i = 0; i < cchDigits; ++i)
        cTimes *= 10;

    /* Allocate the result array. */
    char **papszNames = (char **)RTMemTmpAllocZ(cTimes * sizeof(char *));
    RTTESTI_CHECK_RETV(papszNames != NULL);

    int rc = VERR_INTERNAL_ERROR;
    /* The test loop. */
    size_t i;
    for (i = 0; i < cTimes; i++)
    {
        char szName[RTPATH_MAX];
        RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), "RTDirCreateUniqueNumbered"), VINF_SUCCESS);
        if (RT_FAILURE(rc))
            break;

        RTTESTI_CHECK_RC(rc = RTDirCreateUniqueNumbered(szName, sizeof(szName), 0700, cchDigits, chSep), VINF_SUCCESS);
        if (RT_FAILURE(rc))
        {
            RTTestIFailed("RTDirCreateUniqueNumbered(%s) call #%u -> %Rrc\n", szName, i, rc);
            break;
        }

        RTTESTI_CHECK(papszNames[i] = RTStrDup(szName));
        if (!papszNames[i])
            break;

        RTTestIPrintf(RTTESTLVL_DEBUG, "%s\n", papszNames[i]);
    }

    /* Try to create one more, which shouldn't be possible. */
    if (RT_SUCCESS(rc))
    {
        char szName[RTPATH_MAX];
        RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), "RTDirCreateUniqueNumbered"), VINF_SUCCESS);
        if (RT_SUCCESS(rc))
            RTTESTI_CHECK_RC(rc = RTDirCreateUniqueNumbered(szName, sizeof(szName), 0700, cchDigits, chSep), VERR_ALREADY_EXISTS);
    }

    /* cleanup */
    while (i-- > 0)
    {
        RTTESTI_CHECK_RC(RTDirRemove(papszNames[i]), VINF_SUCCESS);
        RTStrFree(papszNames[i]);
    }
    RTMemTmpFree(papszNames);
}
Exemple #4
0
RTR3DECL(int) RTManifestVerifyFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles, size_t *piFailed,
                                    PFNRTPROGRESS pfnProgressCallback, void *pvUser)
{
    /* Validate input */
    AssertPtrReturn(pszManifestFile, VERR_INVALID_POINTER);
    AssertPtrReturn(papszFiles, VERR_INVALID_POINTER);
    AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_POINTER);

    int rc = VINF_SUCCESS;

    /* Create our compare list */
    PRTMANIFESTTEST paFiles = (PRTMANIFESTTEST)RTMemTmpAllocZ(sizeof(RTMANIFESTTEST) * cFiles);
    if (!paFiles)
        return VERR_NO_MEMORY;

    RTMANIFESTCALLBACKDATA callback = { pfnProgressCallback, pvUser, cFiles, 0 };
    /* Fill our compare list */
    for (size_t i = 0; i < cFiles; ++i)
    {
        char *pszDigest;
        if (pfnProgressCallback)
        {
            callback.cCurrentFile = i;
            rc = RTSha1DigestFromFile(papszFiles[i], &pszDigest, rtSHAProgressCallback, &callback);
        }
        else
            rc = RTSha1DigestFromFile(papszFiles[i], &pszDigest, NULL, NULL);
        if (RT_FAILURE(rc))
            break;
        paFiles[i].pszTestFile = (char*)papszFiles[i];
        paFiles[i].pszTestDigest = pszDigest;
    }

    /* Do the verification */
    if (RT_SUCCESS(rc))
        rc = RTManifestVerify(pszManifestFile, paFiles, cFiles, piFailed);

    /* Cleanup */
    for (size_t i = 0; i < cFiles; ++i)
    {
        if (paFiles[i].pszTestDigest)
            RTStrFree((char*)paFiles[i].pszTestDigest);
    }
    RTMemTmpFree(paFiles);

    return rc;
}
static void tstDirCreateTemp(const char *pszSubTest, const char *pszTemplate, unsigned cTimes, bool fSkipXCheck)
{
    RTTestISub(pszSubTest);

    /* Allocate the result array. */
    char **papszNames = (char **)RTMemTmpAllocZ(cTimes * sizeof(char *));
    RTTESTI_CHECK_RETV(papszNames != NULL);

    /* The test loop. */
    unsigned i;
    for (i = 0; i < cTimes; i++)
    {
        int rc;
        char szName[RTPATH_MAX];
        RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), pszTemplate), VINF_SUCCESS);
        if (RT_FAILURE(rc))
            break;

        RTTESTI_CHECK(papszNames[i] = RTStrDup(szName));
        if (!papszNames[i])
            break;

        rc = RTDirCreateTemp(papszNames[i]);
        if (rc != VINF_SUCCESS)
        {
            RTTestIFailed("RTDirCreateTemp(%s) call #%u -> %Rrc\n", szName, i, rc);
            RTStrFree(papszNames[i]);
            papszNames[i] = NULL;
            break;
        }
        RTTestIPrintf(RTTESTLVL_DEBUG, "%s\n", papszNames[i]);
        RTTESTI_CHECK_MSG(strlen(szName) == strlen(papszNames[i]), ("szName   %s\nReturned %s\n", szName, papszNames[i]));
        if (!fSkipXCheck)
            RTTESTI_CHECK_MSG(strchr(RTPathFilename(papszNames[i]), 'X') == NULL, ("szName   %s\nReturned %s\n", szName, papszNames[i]));
    }

    /* cleanup */
    while (i-- > 0)
    {
        RTTESTI_CHECK_RC(RTDirRemove(papszNames[i]), VINF_SUCCESS);
        RTStrFree(papszNames[i]);
    }
    RTMemTmpFree(papszNames);
}
/**
 * Output processing task, handles outgoing frames
 */
static void vboxNetFltFreeBSDoutput(void *arg, int pending)
{
    PVBOXNETFLTINS pThis = (PVBOXNETFLTINS)arg;
    struct mbuf *m, *m0;
    struct ifnet *ifp = pThis->u.s.ifp;
    unsigned int cSegs = 0;
    bool fDropIt = false, fActive;
    PINTNETSG pSG;

    VBOXCURVNET_SET(ifp->if_vnet);
    vboxNetFltRetain(pThis, true /* fBusy */);
    for (;;)
    {
        mtx_lock_spin(&pThis->u.s.outq.ifq_mtx);
        _IF_DEQUEUE(&pThis->u.s.outq, m);
        mtx_unlock_spin(&pThis->u.s.outq.ifq_mtx);
        if (m == NULL)
            break;

        for (m0 = m; m0 != NULL; m0 = m0->m_next)
            if (m0->m_len > 0)
                cSegs++;

#ifdef PADD_RUNT_FRAMES_FROM_HOST
        if (m_length(m, NULL) < 60)
            cSegs++;
#endif
        /* Create a copy and deliver to the virtual switch */
        pSG = RTMemTmpAlloc(RT_OFFSETOF(INTNETSG, aSegs[cSegs]));
        vboxNetFltFreeBSDMBufToSG(pThis, m, pSG, cSegs, 0);
        fDropIt = pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, NULL /* pvIf */, pSG, INTNETTRUNKDIR_HOST);
        RTMemTmpFree(pSG);

        if (fDropIt)
            m_freem(m);
        else
            ether_output_frame(ifp, m);
    }
    vboxNetFltRelease(pThis, true /* fBusy */);
    VBOXCURVNET_RESTORE();
}
Exemple #7
0
/**
 * Frees allocated pages, for bailing out on failure.
 *
 * This will not call VMSetError on failure but will use AssertLogRel instead.
 *
 * @param   pVM         The cross context VM structure.
 * @param   pAllocReq   The allocation request to undo.
 */
GMMR3DECL(void) GMMR3FreeAllocatedPages(PVM pVM, GMMALLOCATEPAGESREQ const *pAllocReq)
{
    uint32_t cb = RT_OFFSETOF(GMMFREEPAGESREQ, aPages[pAllocReq->cPages]);
    PGMMFREEPAGESREQ pReq = (PGMMFREEPAGESREQ)RTMemTmpAllocZ(cb);
    AssertLogRelReturnVoid(pReq);

    pReq->Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
    pReq->Hdr.cbReq = cb;
    pReq->enmAccount = pAllocReq->enmAccount;
    pReq->cPages = pAllocReq->cPages;
    uint32_t iPage = pAllocReq->cPages;
    while (iPage-- > 0)
    {
        Assert(pAllocReq->aPages[iPage].idPage != NIL_GMM_PAGEID);
        pReq->aPages[iPage].idPage = pAllocReq->aPages[iPage].idPage;
    }

    int rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_FREE_PAGES, 0, &pReq->Hdr);
    AssertLogRelRC(rc);

    RTMemTmpFree(pReq);
}
/**
 * Gets an entry.
 *
 * @returns IPRT status code.
 * @param   pThis               The manifest to work with.
 * @param   pszEntry            The entry name.
 * @param   fNeedNormalization  Whether rtManifestValidateNameEntry said it
 *                              needed normalization.
 * @param   cchEntry            The length of the name.
 * @param   ppEntry             Where to return the entry pointer on success.
 */
static int rtManifestGetEntry(RTMANIFESTINT *pThis, const char *pszEntry, bool fNeedNormalization, size_t cchEntry,
                              PRTMANIFESTENTRY *ppEntry)
{
    PRTMANIFESTENTRY pEntry;

    AssertCompileMemberOffset(RTMANIFESTATTR, StrCore, 0);
    if (!fNeedNormalization)
        pEntry = (PRTMANIFESTENTRY)RTStrSpaceGet(&pThis->Entries, pszEntry);
    else
    {
        char *pszCopy = (char *)RTMemTmpAlloc(cchEntry + 1);
        if (RT_UNLIKELY(!pszCopy))
            return VERR_NO_TMP_MEMORY;
        memcpy(pszCopy, pszEntry, cchEntry + 1);
        rtManifestNormalizeEntry(pszCopy);

        pEntry = (PRTMANIFESTENTRY)RTStrSpaceGet(&pThis->Entries, pszCopy);
        RTMemTmpFree(pszCopy);
    }

    *ppEntry = pEntry;
    return pEntry ? VINF_SUCCESS : VERR_NOT_FOUND;
}
Exemple #9
0
RTDECL(int) RTEnvSetUtf8(const char *pszVar, const char *pszValue)
{
    AssertReturn(strchr(pszVar, '=') == NULL, VERR_ENV_INVALID_VAR_NAME);

    size_t cwcVar;
    int rc = RTStrCalcUtf16LenEx(pszVar, RTSTR_MAX, &cwcVar);
    if (RT_SUCCESS(rc))
    {
        size_t cwcValue;
        rc = RTStrCalcUtf16LenEx(pszVar, RTSTR_MAX, &cwcValue);
        if (RT_SUCCESS(rc))
        {
            PRTUTF16 pwszTmp = (PRTUTF16)RTMemTmpAlloc((cwcVar + 1 + cwcValue + 1) * sizeof(RTUTF16));
            if (pwszTmp)
            {
                rc = RTStrToUtf16Ex(pszVar, RTSTR_MAX, &pwszTmp, cwcVar + 1, NULL);
                if (RT_SUCCESS(rc))
                {
                    PRTUTF16 pwszTmpValue = &pwszTmp[cwcVar];
                    *pwszTmpValue++ = '=';
                    rc = RTStrToUtf16Ex(pszValue, RTSTR_MAX, &pwszTmpValue, cwcValue + 1, NULL);
                    if (RT_SUCCESS(rc))
                    {
                        if (!_wputenv(pwszTmp))
                            rc = VINF_SUCCESS;
                        else
                            rc = RTErrConvertFromErrno(errno);
                    }
                }
                RTMemTmpFree(pwszTmp);
            }
            else
                rc = VERR_NO_TMP_MEMORY;
        }
    }
    return rc;
}
/**
 * Check the credentials and return the gid/uid of user.
 *
 * @param    pszUser     username
 * @param    pszPasswd   password
 * @param    gid         where to store the GID of the user
 * @param    uid         where to store the UID of the user
 * @returns IPRT status code
 */
static int rtCheckCredentials(const char *pszUser, const char *pszPasswd, gid_t *pGid, uid_t *pUid)
{
#if defined(RT_OS_LINUX)
    struct passwd *pw;

    pw = getpwnam(pszUser);
    if (!pw)
        return VERR_AUTHENTICATION_FAILURE;

    if (!pszPasswd)
        pszPasswd = "";

    struct spwd *spwd;
    /* works only if /etc/shadow is accessible */
    spwd = getspnam(pszUser);
    if (spwd)
        pw->pw_passwd = spwd->sp_pwdp;

    /* Default fCorrect=true if no password specified. In that case, pw->pw_passwd
     * must be NULL (no password set for this user). Fail if a password is specified
     * but the user does not have one assigned. */
    int fCorrect = !pszPasswd || !*pszPasswd;
    if (pw->pw_passwd && *pw->pw_passwd)
    {
        struct crypt_data *data = (struct crypt_data*)RTMemTmpAllocZ(sizeof(*data));
        /* be reentrant */
        char *pszEncPasswd = crypt_r(pszPasswd, pw->pw_passwd, data);
        fCorrect = pszEncPasswd && !strcmp(pszEncPasswd, pw->pw_passwd);
        RTMemTmpFree(data);
    }
    if (!fCorrect)
        return VERR_AUTHENTICATION_FAILURE;

    *pGid = pw->pw_gid;
    *pUid = pw->pw_uid;
    return VINF_SUCCESS;

#elif defined(RT_OS_SOLARIS)
    struct passwd *ppw, pw;
    char szBuf[1024];

    if (getpwnam_r(pszUser, &pw, szBuf, sizeof(szBuf), &ppw) != 0 || ppw == NULL)
        return VERR_AUTHENTICATION_FAILURE;

    if (!pszPasswd)
        pszPasswd = "";

    struct spwd spwd;
    char szPwdBuf[1024];
    /* works only if /etc/shadow is accessible */
    if (getspnam_r(pszUser, &spwd, szPwdBuf, sizeof(szPwdBuf)) != NULL)
        ppw->pw_passwd = spwd.sp_pwdp;

    char *pszEncPasswd = crypt(pszPasswd, ppw->pw_passwd);
    if (strcmp(pszEncPasswd, ppw->pw_passwd))
        return VERR_AUTHENTICATION_FAILURE;

    *pGid = ppw->pw_gid;
    *pUid = ppw->pw_uid;
    return VINF_SUCCESS;

#else
    NOREF(pszUser); NOREF(pszPasswd); NOREF(pGid); NOREF(pUid);
    return VERR_AUTHENTICATION_FAILURE;
#endif
}
Exemple #11
0
/**
 * VMMR3Init worker that initiates the switcher code (aka core code).
 *
 * This is core per VM code which might need fixups and/or for ease of use are
 * put on linear contiguous backing.
 *
 * @returns VBox status code.
 * @param   pVM     Pointer to the VM.
 */
int vmmR3SwitcherInit(PVM pVM)
{
#ifndef VBOX_WITH_RAW_MODE
    return VINF_SUCCESS;
#else
    /*
     * Calc the size.
     */
    unsigned cbCoreCode = 0;
    for (unsigned iSwitcher = 0; iSwitcher < RT_ELEMENTS(s_apSwitchers); iSwitcher++)
    {
        pVM->vmm.s.aoffSwitchers[iSwitcher] = cbCoreCode;
        PVMMSWITCHERDEF pSwitcher = s_apSwitchers[iSwitcher];
        if (pSwitcher)
        {
            AssertRelease((unsigned)pSwitcher->enmType == iSwitcher);
            cbCoreCode += RT_ALIGN_32(pSwitcher->cbCode + 1, 32);
        }
    }

    /*
     * Allocate contiguous pages for switchers and deal with
     * conflicts in the intermediate mapping of the code.
     */
    pVM->vmm.s.cbCoreCode = RT_ALIGN_32(cbCoreCode, PAGE_SIZE);
    pVM->vmm.s.pvCoreCodeR3 = SUPR3ContAlloc(pVM->vmm.s.cbCoreCode >> PAGE_SHIFT, &pVM->vmm.s.pvCoreCodeR0, &pVM->vmm.s.HCPhysCoreCode);
    int rc = VERR_NO_MEMORY;
    if (pVM->vmm.s.pvCoreCodeR3)
    {
        rc = PGMR3MapIntermediate(pVM, pVM->vmm.s.pvCoreCodeR0, pVM->vmm.s.HCPhysCoreCode, cbCoreCode);
        if (rc == VERR_PGM_INTERMEDIATE_PAGING_CONFLICT)
        {
            /* try more allocations - Solaris, Linux.  */
            const unsigned cTries = 8234;
            struct VMMInitBadTry
            {
                RTR0PTR  pvR0;
                void    *pvR3;
                RTHCPHYS HCPhys;
                RTUINT   cb;
            } *paBadTries = (struct VMMInitBadTry *)RTMemTmpAlloc(sizeof(*paBadTries) * cTries);
            AssertReturn(paBadTries, VERR_NO_TMP_MEMORY);
            unsigned i = 0;
            do
            {
                paBadTries[i].pvR3 = pVM->vmm.s.pvCoreCodeR3;
                paBadTries[i].pvR0 = pVM->vmm.s.pvCoreCodeR0;
                paBadTries[i].HCPhys = pVM->vmm.s.HCPhysCoreCode;
                i++;
                pVM->vmm.s.pvCoreCodeR0 = NIL_RTR0PTR;
                pVM->vmm.s.HCPhysCoreCode = NIL_RTHCPHYS;
                pVM->vmm.s.pvCoreCodeR3 = SUPR3ContAlloc(pVM->vmm.s.cbCoreCode >> PAGE_SHIFT, &pVM->vmm.s.pvCoreCodeR0, &pVM->vmm.s.HCPhysCoreCode);
                if (!pVM->vmm.s.pvCoreCodeR3)
                    break;
                rc = PGMR3MapIntermediate(pVM, pVM->vmm.s.pvCoreCodeR0, pVM->vmm.s.HCPhysCoreCode, cbCoreCode);
            } while (   rc == VERR_PGM_INTERMEDIATE_PAGING_CONFLICT
                     && i < cTries - 1);

            /* cleanup */
            if (RT_FAILURE(rc))
            {
                paBadTries[i].pvR3   = pVM->vmm.s.pvCoreCodeR3;
                paBadTries[i].pvR0   = pVM->vmm.s.pvCoreCodeR0;
                paBadTries[i].HCPhys = pVM->vmm.s.HCPhysCoreCode;
                paBadTries[i].cb     = pVM->vmm.s.cbCoreCode;
                i++;
                LogRel(("Failed to allocated and map core code: rc=%Rrc\n", rc));
            }
            while (i-- > 0)
            {
                LogRel(("Core code alloc attempt #%d: pvR3=%p pvR0=%p HCPhys=%RHp\n",
                        i, paBadTries[i].pvR3, paBadTries[i].pvR0, paBadTries[i].HCPhys));
                SUPR3ContFree(paBadTries[i].pvR3, paBadTries[i].cb >> PAGE_SHIFT);
            }
            RTMemTmpFree(paBadTries);
        }
    }
/**
 * Destroys the hashes.
 *
 * @param   pHashes             The hashes structure.  NULL is ignored.
 */
static void rtManifestHashesDestroy(PRTMANIFESTHASHES pHashes)
{
    RTMemTmpFree(pHashes);
}
Exemple #13
0
/**
 * Reads the extension pack descriptor.
 *
 * @returns NULL on success, pointer to an error message on failure (caller
 *          deletes it).
 * @param   a_pszDir        The directory containing the description file.
 * @param   a_pExtPackDesc  Where to store the extension pack descriptor.
 * @param   a_pObjInfo      Where to store the object info for the file (unix
 *                          attribs). Optional.
 */
RTCString *VBoxExtPackLoadDescFromVfsFile(RTVFSFILE hVfsFile, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo)
{
    vboxExtPackClearDesc(a_pExtPackDesc);

    /*
     * Query the object info.
     */
    RTFSOBJINFO ObjInfo;
    int rc = RTVfsFileQueryInfo(hVfsFile, &ObjInfo, RTFSOBJATTRADD_UNIX);
    if (RT_FAILURE(rc))
        return &(new RTCString)->printf("RTVfsFileQueryInfo failed: %Rrc", rc);
    if (a_pObjInfo)
        *a_pObjInfo = ObjInfo;

    /*
     * The simple approach, read the whole thing into memory and pass this to
     * the XML parser.
     */

    /* Check the file size. */
    if (ObjInfo.cbObject > _1M || ObjInfo.cbObject < 0)
        return &(new RTCString)->printf("The XML file is too large (%'RU64 bytes)", ObjInfo.cbObject);
    size_t const cbFile = (size_t)ObjInfo.cbObject;

    /* Rewind to the start of the file. */
    rc = RTVfsFileSeek(hVfsFile, 0, RTFILE_SEEK_BEGIN, NULL);
    if (RT_FAILURE(rc))
        return &(new RTCString)->printf("RTVfsFileSeek(,0,BEGIN) failed: %Rrc", rc);

    /* Allocate memory and read the file content into it. */
    void *pvFile = RTMemTmpAlloc(cbFile);
    if (!pvFile)
        return &(new RTCString)->printf("RTMemTmpAlloc(%zu) failed", cbFile);

    RTCString *pstrErr = NULL;
    rc = RTVfsFileRead(hVfsFile, pvFile, cbFile, NULL);
    if (RT_FAILURE(rc))
        pstrErr = &(new RTCString)->printf("RTVfsFileRead failed: %Rrc", rc);

    /*
     * Parse the file.
     */
    xml::Document Doc;
    if (RT_SUCCESS(rc))
    {
        xml::XmlMemParser   Parser;
        RTCString           strFileName = VBOX_EXTPACK_DESCRIPTION_NAME;
        try
        {
            Parser.read(pvFile, cbFile, strFileName, Doc);
        }
        catch (xml::XmlError Err)
        {
            pstrErr = new RTCString(Err.what());
            rc = VERR_PARSE_ERROR;
        }
    }
    RTMemTmpFree(pvFile);

    /*
     * Hand the xml doc over to the common code.
     */
    if (RT_SUCCESS(rc))
        pstrErr = vboxExtPackLoadDescFromDoc(&Doc, a_pExtPackDesc);

    return pstrErr;
}
static int VBoxUSBMonSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArg, int Mode, cred_t *pCred, int *pVal)
{
    LogFunc((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl Dev=%d Cmd=%d pArg=%p Mode=%d\n", Dev, Cmd, pArg));

    /*
     * Get the session from the soft state item.
     */
    vboxusbmon_state_t *pState = ddi_get_soft_state(g_pVBoxUSBMonSolarisState, getminor(Dev));
    if (!pState)
    {
        LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: no state data for %d\n", getminor(Dev)));
        return EINVAL;
    }

    /*
     * Read the request wrapper. Though We don't really need wrapper struct. now
     * it's room for the future as Solaris isn't generous regarding the size.
     */
    VBOXUSBREQ ReqWrap;
    if (IOCPARM_LEN(Cmd) != sizeof(ReqWrap))
    {
        LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: bad request %#x size=%d expected=%d\n", Cmd, IOCPARM_LEN(Cmd), sizeof(ReqWrap)));
        return ENOTTY;
    }

    int rc = ddi_copyin((void *)pArg, &ReqWrap, sizeof(ReqWrap), Mode);
    if (RT_UNLIKELY(rc))
    {
        LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: ddi_copyin failed to read header pArg=%p Cmd=%d. rc=%d.\n", pArg, Cmd, rc));
        return EINVAL;
    }

    if (ReqWrap.u32Magic != VBOXUSBMON_MAGIC)
    {
        LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: bad magic %#x; pArg=%p Cmd=%d.\n", ReqWrap.u32Magic, pArg, Cmd));
        return EINVAL;
    }
    if (RT_UNLIKELY(   ReqWrap.cbData == 0
                    || ReqWrap.cbData > _1M*16))
    {
        LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: bad size %#x; pArg=%p Cmd=%d.\n", ReqWrap.cbData, pArg, Cmd));
        return EINVAL;
    }

    /*
     * Read the request.
     */
    void *pvBuf = RTMemTmpAlloc(ReqWrap.cbData);
    if (RT_UNLIKELY(!pvBuf))
    {
        LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: RTMemTmpAlloc failed to alloc %d bytes.\n", ReqWrap.cbData));
        return ENOMEM;
    }

    rc = ddi_copyin((void *)(uintptr_t)ReqWrap.pvDataR3, pvBuf, ReqWrap.cbData, Mode);
    if (RT_UNLIKELY(rc))
    {
        RTMemTmpFree(pvBuf);
        LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: ddi_copyin failed; pvBuf=%p pArg=%p Cmd=%d. rc=%d\n", pvBuf, pArg, Cmd, rc));
        return EFAULT;
    }
    if (RT_UNLIKELY(   ReqWrap.cbData != 0
                    && !VALID_PTR(pvBuf)))
    {
        RTMemTmpFree(pvBuf);
        LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: pvBuf invalid pointer %p\n", pvBuf));
        return EINVAL;
    }
    Log((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: pid=%d.\n", (int)RTProcSelf()));

    /*
     * Process the IOCtl.
     */
    size_t cbDataReturned;
    rc = vboxUSBMonSolarisProcessIOCtl(Cmd, pState, pvBuf, ReqWrap.cbData, &cbDataReturned);
    ReqWrap.rc = rc;
    rc = 0;

    if (RT_UNLIKELY(cbDataReturned > ReqWrap.cbData))
    {
        LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: too much output data %d expected %d\n", cbDataReturned, ReqWrap.cbData));
        cbDataReturned = ReqWrap.cbData;
    }

    ReqWrap.cbData = cbDataReturned;

    /*
     * Copy the request back to user space.
     */
    rc = ddi_copyout(&ReqWrap, (void *)pArg, sizeof(ReqWrap), Mode);
    if (RT_LIKELY(!rc))
    {
        /*
         * Copy the payload (if any) back to user space.
         */
        if (cbDataReturned > 0)
        {
            rc = ddi_copyout(pvBuf, (void *)(uintptr_t)ReqWrap.pvDataR3, cbDataReturned, Mode);
            if (RT_UNLIKELY(rc))
            {
                LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: ddi_copyout failed; pvBuf=%p pArg=%p Cmd=%d. rc=%d\n", pvBuf, pArg, Cmd, rc));
                rc = EFAULT;
            }
        }
    }
    else
    {
        LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: ddi_copyout(1) failed pArg=%p Cmd=%d\n", pArg, Cmd));
        rc = EFAULT;
    }

    *pVal = rc;
    RTMemTmpFree(pvBuf);
    return rc;
}
Exemple #15
0
/**
 * Cleans up a GMMR0FreePages request.
 * @param   pReq        Pointer to the request (returned by GMMR3FreePagesPrepare).
 */
GMMR3DECL(void) GMMR3FreePagesCleanup(PGMMFREEPAGESREQ pReq)
{
    RTMemTmpFree(pReq);
}
Exemple #16
0
/**
 * Internal: Create a raw image.
 */
static int rawCreateImage(PRAWIMAGE pImage, uint64_t cbSize,
                          unsigned uImageFlags, const char *pszComment,
                          PCVDGEOMETRY pPCHSGeometry,
                          PCVDGEOMETRY pLCHSGeometry, unsigned uOpenFlags,
                          PFNVDPROGRESS pfnProgress, void *pvUser,
                          unsigned uPercentStart, unsigned uPercentSpan)
{
    int rc;
    RTFOFF cbFree = 0;
    uint64_t uOff;
    void *pvBuf = NULL;
    int32_t fOpen;

    uImageFlags |= VD_IMAGE_FLAGS_FIXED;

    pImage->uOpenFlags = uOpenFlags & ~VD_OPEN_FLAGS_READONLY;

    pImage->uImageFlags = uImageFlags;
    pImage->fCreate = true;
    pImage->PCHSGeometry = *pPCHSGeometry;
    pImage->LCHSGeometry = *pLCHSGeometry;

    pImage->pIfError = VDIfErrorGet(pImage->pVDIfsDisk);
    pImage->pIfIo = VDIfIoIntGet(pImage->pVDIfsImage);
    AssertPtrReturn(pImage->pIfIo, VERR_INVALID_PARAMETER);

    if (uImageFlags & VD_IMAGE_FLAGS_DIFF)
    {
        rc = vdIfError(pImage->pIfError, VERR_VD_RAW_INVALID_TYPE, RT_SRC_POS, N_("Raw: cannot create diff image '%s'"), pImage->pszFilename);
        goto out;
    }

    /* Create image file. */
    fOpen = VDOpenFlagsToFileOpenFlags(pImage->uOpenFlags, true /* fCreate */);
    if (uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL)
        fOpen &= ~RTFILE_O_READ;
    rc = vdIfIoIntFileOpen(pImage->pIfIo, pImage->pszFilename, fOpen, &pImage->pStorage);
    if (RT_FAILURE(rc))
    {
        rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("Raw: cannot create image '%s'"), pImage->pszFilename);
        goto out;
    }

    if (!(uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL))
    {
        /* Check the free space on the disk and leave early if there is not
         * sufficient space available. */
        rc = vdIfIoIntFileGetFreeSpace(pImage->pIfIo, pImage->pszFilename, &cbFree);
        if (RT_SUCCESS(rc) /* ignore errors */ && ((uint64_t)cbFree < cbSize))
        {
            rc = vdIfError(pImage->pIfError, VERR_DISK_FULL, RT_SRC_POS, N_("Raw: disk would overflow creating image '%s'"), pImage->pszFilename);
            goto out;
        }

        /* Allocate & commit whole file if fixed image, it must be more
         * effective than expanding file by write operations. */
        rc = vdIfIoIntFileSetSize(pImage->pIfIo, pImage->pStorage, cbSize);
        if (RT_FAILURE(rc))
        {
            rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("Raw: setting image size failed for '%s'"), pImage->pszFilename);
            goto out;
        }

        /* Fill image with zeroes. We do this for every fixed-size image since
         * on some systems (for example Windows Vista), it takes ages to write
         * a block near the end of a sparse file and the guest could complain
         * about an ATA timeout. */
        pvBuf = RTMemTmpAllocZ(RAW_FILL_SIZE);
        if (!pvBuf)
        {
            rc = VERR_NO_MEMORY;
            goto out;
        }

        uOff = 0;
        /* Write data to all image blocks. */
        while (uOff < cbSize)
        {
            unsigned cbChunk = (unsigned)RT_MIN(cbSize, RAW_FILL_SIZE);

            rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, uOff,
                                        pvBuf, cbChunk, NULL);
            if (RT_FAILURE(rc))
            {
                rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("Raw: writing block failed for '%s'"), pImage->pszFilename);
                goto out;
            }

            uOff += cbChunk;

            if (pfnProgress)
            {
                rc = pfnProgress(pvUser,
                                 uPercentStart + uOff * uPercentSpan * 98 / (cbSize * 100));
                if (RT_FAILURE(rc))
                    goto out;
            }
        }
    }

    if (RT_SUCCESS(rc) && pfnProgress)
        pfnProgress(pvUser, uPercentStart + uPercentSpan * 98 / 100);

    pImage->cbSize = cbSize;

    rc = rawFlushImage(pImage);

out:
    if (pvBuf)
        RTMemTmpFree(pvBuf);

    if (RT_SUCCESS(rc) && pfnProgress)
        pfnProgress(pvUser, uPercentStart + uPercentSpan);

    if (RT_FAILURE(rc))
        rawFreeImage(pImage, rc != VERR_ALREADY_EXISTS);
    return rc;
}
Exemple #17
0
/**
 * Parses any string and tests if it is an IPv6 Address
 *
 * This function should NOT be used directly. If you do, note
 * that no security checks are done at the moment. This can change.
 *
 * @returns iprt sstatus code.
 * @param pszAddress       The strin that holds the IPv6 address
 * @param addressLength    The length of pszAddress
 * @param pszAddressOut    Returns a plain, full blown IPv6 address
 *                         as a char array
 * @param addressOutSize   The size of pszAddressOut (length)
 * @param pPortOut         32 bit unsigned integer, holding the port
 *                         If pszAddress doesn't contain a port, it's 0
 * @param pszScopeOut      Returns the scope of the address, if none it's 0
 * @param scopeOutSize     sizeof(pszScopeOut)
 * @param pBrackets        returns true if the address was enclosed in brackets
 * @param pEmbeddedV4      returns true if the address is an embedded IPv4 address
 * @param followRfc        if set to true, the function follows RFC (default)
 */
static int rtStrParseAddrStr6(const char *pszAddress, size_t addressLength, char *pszAddressOut, size_t addressOutSize, uint32_t *pPortOut, char *pszIfIdOut, size_t ifIdOutSize, bool *pBrackets, bool *pEmbeddedV4, bool followRfc)
{
    /************************\
     *  Pointer Hell Ahead  *
    \************************/

    const char szIpV6AddressChars[] = "ABCDEF01234567890abcdef.:[]%"; // order IMPORTANT
    const char szIpV4AddressChars[] = "01234567890.:[]"; // order IMPORTANT
    const char szLinkLocalPrefix[] = "FfEe8800"; //
    const char *pszIpV6AddressChars = NULL, *pszIpV4AddressChars = NULL, *pszLinkLocalPrefix = NULL;

    char *pszSourceAddress = NULL, *pszSourceAddressStart = NULL;
    char *pszResultAddress = NULL, *pszResultAddressStart = NULL;
    char *pszResultAddress4 = NULL, *pszResultAddress4Start = NULL;
    char *pszResultPort = NULL, *pszResultPortStart = NULL;
    char *pszInternalAddress = NULL, *pszInternalAddressStart = NULL;
    char *pszInternalPort = NULL, *pszInternalPortStart = NULL;

    char *pStart = NULL, *pNow = NULL, *pNext = NULL, *pNowChar = NULL, *pIfId = NULL, *pIfIdEnd = NULL;
    char *pNowDigit = NULL, *pFrom = NULL, *pTo = NULL, *pLast = NULL;
    char *pGap = NULL, *pMisc = NULL, *pDotStart = NULL, *pFieldStart = NULL, *pFieldEnd = NULL;
    char *pFieldStartLongest = NULL, *pBracketOpen = NULL, *pBracketClose = NULL;
    char *pszRc = NULL;

    bool isLinkLocal = false;
    char szDummy[4];

    uint8_t *pByte = NULL;
    uint32_t byteOut = 0;
    uint16_t returnValue = 0;
    uint32_t colons = 0;
    uint32_t colonsOverAll = 0;
    uint32_t fieldLength = 0;
    uint32_t dots = 0;
    size_t gapSize = 0;
    uint32_t intPortOut = 0;

    pszIpV4AddressChars = &szIpV4AddressChars[0];
    pszIpV6AddressChars = &szIpV6AddressChars[6];
    pszLinkLocalPrefix = &szLinkLocalPrefix[6];

    if (!followRfc)
        pszIpV6AddressChars = &szIpV6AddressChars[0];

    if (addressLength<2)
        returnValue = 711;

    pszResultAddressStart = (char *)RTMemTmpAlloc(34);
    pszInternalAddressStart = (char *)RTMemTmpAlloc(34);
    pszInternalPortStart = (char * )RTMemTmpAlloc(10);

    if (! (pszResultAddressStart && pszInternalAddressStart && pszInternalPortStart))
    {
        if (pszResultAddressStart)
            RTMemTmpFree(pszResultAddressStart);

        if (pszInternalAddressStart)
            RTMemTmpFree(pszInternalAddressStart);

        if (pszInternalPortStart)
            RTMemTmpFree(pszInternalPortStart);

        return -701;
    }

    memset(szDummy, '\0', 4);

    pszResultAddress = pszResultAddressStart;
    memset(pszResultAddressStart, '\0', 34);

    pszInternalAddress = pszInternalAddressStart;
    memset(pszInternalAddressStart, '\0' , 34);

    pszInternalPort = pszInternalPortStart;
    memset(pszInternalPortStart, '\0', 10);

    pszSourceAddress = pszSourceAddressStart = (char *)pszAddress;

    pFrom = pTo = pStart = pLast = pszSourceAddressStart;

    while (*pszSourceAddress != '\0' && !returnValue)
    {
        pNow = NULL;
        pNext = NULL;
        pNowChar = NULL;
        pNowDigit = NULL;

        pNow = pszSourceAddress;
        pNext = pszSourceAddress + 1;

        if (!pFrom)
            pFrom = pTo = pNow;

        pNowChar = (char *)memchr(pszIpV6AddressChars, *pNow, strlen(pszIpV6AddressChars));
        pNowDigit = (char *)memchr(pszIpV6AddressChars, *pNow, strlen(pszIpV6AddressChars) - 5);

        if (pszResultPort)
        {
            if (pLast && (pszResultPort == pszSourceAddressStart))
            {
                if (*pLast == '\0')
                    returnValue = 721;

                pszResultPortStart = (char *)RTMemTmpAlloc(10);

                if (!pszResultPortStart)
                    returnValue = 702;

                memset(pszResultPortStart, '\0', 10);
                pszResultPort = pszResultPortStart;
                pszSourceAddress = pLast;
                pMisc = pLast;
                pLast = NULL;
                continue;
            }

            pNowDigit = NULL;
            pNowDigit = (char *)memchr(pszIpV4AddressChars, *pNow, strlen(pszIpV4AddressChars) - 4);

            if (strlen(pszResultPortStart) == 5)
                returnValue = 11;

            if (*pNow == '0' && pszResultPort == pszResultPortStart && *pNext != '\0' && (pNow - pMisc) < 5 )
            {
                pszSourceAddress++;
                continue;
            }

            if (pNowDigit)
            {
                *pszResultPort = *pNowDigit;
                pszResultPort++;
                pszSourceAddress++;
                continue;
            }
            else
                returnValue = 12;
        }

        if (pszResultAddress4)
        {
            if (pszResultAddress4 == pszSourceAddressStart && pLast)
            {
                dots = 0;
                pszResultAddress4 = NULL;
                pszResultAddress4Start = NULL;
                pszResultAddress4Start = (char *)RTMemTmpAlloc(20);

                if (!pszResultAddress4Start)
                {
                    returnValue = 401;
                    break;
                }

                memset(pszResultAddress4Start, '\0', 20);
                pszResultAddress4 = pszResultAddress4Start;
                pszSourceAddress = pLast;
                pFrom = pLast;
                pTo = pLast;
                pLast = NULL;
                continue;
            }

            pTo = pNow;
            pNowDigit = NULL;
            pNowDigit = (char *)memchr(pszIpV4AddressChars, *pNow, strlen(pszIpV4AddressChars) - 4);

            if (!pNowDigit && *pNow != '.' && *pNow != ']' && *pNow != ':' && *pNow != '%')
                returnValue = 412;

            if ((pNow - pFrom) > 3)
            {
                returnValue = 402;
                break;
            }

            if (pNowDigit && *pNext != '\0')
            {
                pszSourceAddress++;
                continue;
            }

            if (!pNowDigit  && !pBracketOpen && (*pNext == '.' || *pNext == ']' || *pNext == ':'))
                returnValue = 411;

            memset(pszResultAddress4, '0', 3);
            pMisc = pszResultAddress4 + 2;
            pszResultAddress4 = pszResultAddress4 + 3;

            if (*pNow != '.' && !pNowDigit && strlen(pszResultAddress4Start) < 9)
                returnValue = 403;

            if ((pTo - pFrom) > 0)
                pTo--;

            dots++;

            while (pTo >= pFrom)
            {
                *pMisc = *pTo;
                pMisc--;
                pTo--;
            }

            if (dots == 4 && *pNow == '.')
            {
                if (!pBracketOpen)
                {
                    pszResultPort = pszSourceAddressStart;
                    pLast = pNext;
                }
                else
                {
                    returnValue = 409;
                }
            }

            dots = 0;

            pFrom = pNext;
            pTo = pNext;

            if (strlen(pszResultAddress4Start) > 11)
                pszResultAddress4 = NULL;

            if ((*pNow == ':' || *pNow == '.') && strlen(pszResultAddress4Start) == 12)
            {
                pLast = pNext;
                pszResultPort = pszSourceAddressStart;
            }

            if (*pNow == '%')
            {
                pIfId =  pNow;
                pLast = pNow;
                continue;
            }
            pszSourceAddress = pNext;

            if (*pNow != ']')
                continue;

            pFrom = pNow;
            pTo = pNow;
        }

        if (pIfId && (!pIfIdEnd))
        {
            if (*pIfId == '%' && pIfId == pLast && *pNext != '\0')
            {
                pFrom = pNext;
                pIfId = pNext;
                pLast = NULL;

                pszSourceAddress++;
                continue;
            }

            if (*pNow == '%' && pIfId <= pNow)
            {
                returnValue = 442;
                break;
            }

            if (*pNow != ']' && *pNext != '\0')
            {
                pTo = pNow;
                pszSourceAddress++;
                continue;
            }

            if (*pNow == ']')
            {
                pIfIdEnd = pNow - 1;
                pFrom = pNow;
                pTo = pNow;
                continue;
            }
            else
            {
                pIfIdEnd = pNow;
                pFrom = NULL;
                pTo = NULL;
                pszSourceAddress++;
                continue;
            }
        }

        if (!pNowChar)
        {
            returnValue = 254;

            if (followRfc)
            {
                pMisc = (char *)memchr(&szIpV6AddressChars[0], *pNow, strlen(&szIpV6AddressChars[0]));

                if (pMisc)
                    returnValue = 253;
            }
        }

        if (strlen(pszResultAddressStart) > 32 && !pszResultAddress4Start)
            returnValue = 255;

        if (pNowDigit && *pNext != '\0' && colons == 0)
        {
            pTo = pNow;
            pszSourceAddress++;
            continue;
        }

        if (*pNow == ':' && *pNext != '\0')
        {
            colonsOverAll++;
            colons++;
            pszSourceAddress++;
            continue;
        }

        if (*pNow == ':' )
        {
            colons++;
            colonsOverAll++;
        }

        if (*pNow == '.')
        {
            pMisc = pNow;

            while (*pMisc != '\0' && *pMisc != ']')
            {
                if (*pMisc == '.')
                    dots++;

                pMisc++;
            }
        }

        if (*pNow == ']')
        {
            if (pBracketClose)
                returnValue = 77;

            if (!pBracketOpen)
                returnValue = 22;

            if (*pNext == ':' || *pNext == '.')
            {
                pszResultPort = pszSourceAddressStart;
                pLast = pNext + 1;
            }

            if (pFrom == pNow)
                pFrom = NULL;

            pBracketClose = pNow;
        }

        if (*pNow == '[')
        {
            if (pBracketOpen)
                returnValue = 23;

            if (pStart != pNow)
                returnValue = 24;

            pBracketOpen = pNow;
            pStart++;
            pFrom++;
            pszSourceAddress++;
            continue;
        }

        if (*pNow == '%')
        {
            if (pIfId)
                returnValue = 441;

            pLast = pNext;
            pIfId = pNext;
        }

        if (colons > 0)
        {
            if (colons == 1)
            {
                if (pStart + 1 == pNow )
                    returnValue = 31;

                if (*pNext == '\0' && !pNowDigit)
                    returnValue = 32;

                pLast = pNow;
            }

            if (colons == 2)
            {
                if (pGap)
                    returnValue = 33;

                pGap = pszResultAddress + 4;

                if (pStart + 1 == pNow || pStart + 2 == pNow)
                {
                    pGap = pszResultAddressStart;
                    pFrom = pNow;
                }

                if (*pNext == '\0' && !pNowDigit)
                    pszSourceAddress++;

                if (*pNext != ':' && *pNext != '.')
                    pLast = pNow;
            }

            if (colons == 3)
            {
                pFrom = pLast;
                pLast = pNow;

                if (*pNext == '\0' && !pNowDigit)
                    returnValue = 34;

                if (pBracketOpen)
                    returnValue = 35;

                if (pGap && followRfc)
                    returnValue = 36;

                if (!pGap)
                    pGap = pszResultAddress + 4;

                if (pStart + 3 == pNow)
                {
                    pszResultPort = pszSourceAddressStart;
                    pGap = pszResultAddress;
                    pFrom = NULL;
                }

                if (pNowDigit)
                {
                    pszResultPort = pszSourceAddressStart;
                }
            }
        }
        if (*pNext == '\0' && colons == 0 && !pIfIdEnd)
        {
            pFrom = pLast;

            if (pNowDigit)
                pTo = pNow;

            pLast = NULL;
        }

        if (dots > 0)
        {
            if (dots == 1)
            {
                pszResultPort = pszSourceAddressStart;
                pLast = pNext;
            }

            if (dots == 4 && pBracketOpen)
                returnValue = 601;

            if (dots == 3 || dots == 4)
            {
                pszResultAddress4 = pszSourceAddressStart;
                pLast = pFrom;
                pFrom = NULL;
            }

            if (dots > 4)
                returnValue = 603;

            dots = 0;
        }

        if (pFrom && pTo)
        {
            if (pTo - pFrom > 3)
            {
                returnValue = 51;
                break;
            }

            if (followRfc)
            {
                if ((pTo - pFrom > 0) && *pFrom == '0')
                    returnValue = 101;

                if ((pTo - pFrom) == 0 && *pFrom == '0' && colons == 2)
                    returnValue = 102;

                if ((pTo - pFrom) == 0 && *pFrom == '0' && pszResultAddress == pGap)
                    returnValue = 103;

                if ((pTo - pFrom) == 0 && *pFrom == '0')
                {
                    if (!pFieldStart)
                    {
                        pFieldStart = pszResultAddress;
                        pFieldEnd = pszResultAddress + 4;
                    }
                    else
                    {
                        pFieldEnd = pFieldEnd + 4;
                    }
                }
                else
                {
                    if ((size_t)(pFieldEnd - pFieldStart) > fieldLength)
                    {
                        fieldLength = pFieldEnd - pFieldStart;
                        pFieldStartLongest = pFieldStart;
                    }

                    pFieldStart = NULL;
                    pFieldEnd = NULL;
                }
            }
            if (!(pGap == pszResultAddressStart && (size_t)(pNow - pStart) == colons))
            {
                memset(pszResultAddress, '0', 4);
                pMisc = pszResultAddress + 3;
                pszResultAddress = pszResultAddress + 4;

                if (pFrom == pStart && (pTo - pFrom) == 3)
                {
                    isLinkLocal = true;

                    while (pTo >= pFrom)
                    {
                        *pMisc = *pTo;

                        if (*pTo != *pszLinkLocalPrefix && *pTo != *(pszLinkLocalPrefix + 1))
                            isLinkLocal = false;

                        pTo--;
                        pMisc--;
                        pszLinkLocalPrefix = pszLinkLocalPrefix - 2;
                    }
                }
                else
                {
                    while (pTo >= pFrom)
                    {
                        *pMisc = *pTo;
                        pMisc--;
                        pTo--;
                    }
                }
            }

            pFrom = pNow;
            pTo = pNow;

        }
        if (*pNext == '\0' && colons == 0)
            pszSourceAddress++;

        if (*pNext == '\0' && !pBracketClose && !pszResultPort)
            pTo = pNext;

        colons = 0;
    } // end of loop

    if (!returnValue && colonsOverAll < 2)
        returnValue = 252;

    if (!returnValue && (pBracketOpen && !pBracketClose))
        returnValue = 25;

    if (!returnValue && pGap)
    {
        gapSize = 32 - strlen(pszResultAddressStart);

        if (followRfc)
        {
            if (gapSize < 5)
                returnValue = 104;

            if (fieldLength > gapSize)
                returnValue = 105;

            if (fieldLength == gapSize && pFieldStartLongest < pGap)
                returnValue = 106;
        }

        pszResultAddress = pszResultAddressStart;
        pszInternalAddress = pszInternalAddressStart;

        if (!returnValue && pszResultAddress4Start)
        {
            if (strlen(pszResultAddressStart) > 4)
                returnValue = 405;

            pszResultAddress = pszResultAddressStart;

            if (pGap != pszResultAddressStart)
                returnValue = 407;

            memset(pszInternalAddressStart, '0', 20);
            pszInternalAddress = pszInternalAddressStart + 20;

            for (int i = 0; i < 4; i++)
            {
                if (*pszResultAddress != 'f' && *pszResultAddress != 'F')
                {
                    returnValue = 406;
                    break;
                }

                *pszInternalAddress = *pszResultAddress;
                pszResultAddress++;
                pszInternalAddress++;
            }
            pszResultAddress4 = pszResultAddress4Start;

            for (int i = 0; i<4; i++)
            {
                memcpy(szDummy, pszResultAddress4, 3);

                int rc = RTStrToUInt32Ex((const char *)&szDummy[0], NULL, 16, &byteOut);

                if (rc == 0 && byteOut < 256)
                {
                    RTStrPrintf(szDummy, 3, "%02x", byteOut);
                    memcpy(pszInternalAddress, szDummy, 2);
                    pszInternalAddress = pszInternalAddress + 2;
                    pszResultAddress4 = pszResultAddress4 + 3;
                    memset(szDummy, '\0', 4);
                }
                else
                {
                    returnValue = 499;
                }
            }
        }
        else
        {
            while (!returnValue && pszResultAddress != pGap)
            {
                *pszInternalAddress = *pszResultAddress;
                pszResultAddress++;
                pszInternalAddress++;
            }

            memset(pszInternalAddress, '0', gapSize);
            pszInternalAddress = pszInternalAddress + gapSize;

            while (!returnValue && *pszResultAddress != '\0')
            {
                *pszInternalAddress = *pszResultAddress;
                pszResultAddress++;
                pszInternalAddress++;
            }
        }
    }
    else
    {
        if (!returnValue)
        {
            if (strlen(pszResultAddressStart) != 32)
                returnValue = 111;

            if (followRfc)
            {
                if (fieldLength > 4)
                    returnValue = 112;
            }

            memcpy(pszInternalAddressStart, pszResultAddressStart, strlen(pszResultAddressStart));
        }
    }

    if (pszResultPortStart)
    {
        if (strlen(pszResultPortStart) > 0 && strlen(pszResultPortStart) < 6)
        {
            memcpy(pszInternalPortStart, pszResultPortStart, strlen(pszResultPortStart));

            intPortOut = 0;
            int rc = RTStrToUInt32Ex(pszInternalPortStart, NULL, 10, &intPortOut);

            if (rc == 0)
            {
                if (!(intPortOut > 0 && intPortOut < 65536))
                    intPortOut = 0;
            }
            else
            {
                returnValue = 888;
            }
        }
        else
        {
            returnValue = 889;
        }
    }

    /*
       full blown address 32 bytes, no colons -> pszInternalAddressStart
       port as string -> pszResultPortStart
       port as binary integer -> intPortOut
       interface id in pIfId and pIfIdEnd

       Now fill the out parameters.

     */

    if (!returnValue && pszAddressOut)
    {
        if (strlen(pszInternalAddressStart) < addressOutSize)
        {
            pszRc = NULL;
            pszRc = (char *)memset(pszAddressOut, '\0', addressOutSize);

            if (!pszRc)
                returnValue = 910;

            pszRc = NULL;

            pszRc = (char *)memcpy(pszAddressOut, pszInternalAddressStart, strlen(pszInternalAddressStart));

            if (!pszRc)
                returnValue = 911;
        }
        else
        {
            returnValue = 912;
        }
    }

    if (!returnValue && pPortOut)
    {
        *pPortOut = intPortOut;
    }

    if (!returnValue && pszIfIdOut)
    {
        if (pIfIdEnd && pIfId)
        {
            if ((size_t)(pIfIdEnd - pIfId) + 1 < ifIdOutSize)
            {
                pszRc = NULL;
                pszRc = (char *)memset(pszIfIdOut, '\0', ifIdOutSize);

                if (!pszRc)
                    returnValue = 913;

                pszRc = NULL;
                pszRc = (char *)memcpy(pszIfIdOut, pIfId, (pIfIdEnd - pIfId) + 1);

                if (!pszRc)
                    returnValue = 914;
            }
            else
            {
                returnValue = 915;
            }
        }
        else
        {
            pszRc = NULL;
            pszRc = (char *)memset(pszIfIdOut, '\0', ifIdOutSize);

            if (!pszRc)
                returnValue = 916;
        }
        // temporary hack
        if (isLinkLocal && (strlen(pszIfIdOut) < 1))
        {
            memset(pszIfIdOut, '\0', ifIdOutSize);
            *pszIfIdOut = '%';
            pszIfIdOut++;
            *pszIfIdOut = '0';
            pszIfIdOut++;
        }
    }

    if (pBracketOpen && pBracketClose && pBrackets)
        *pBrackets = true;

    if (pEmbeddedV4 && pszResultAddress4Start)
        *pEmbeddedV4 = true;

    if (pszResultAddressStart)
        RTMemTmpFree(pszResultAddressStart);

    if (pszResultPortStart)
        RTMemTmpFree(pszResultPortStart);

    if (pszResultAddress4Start)
        RTMemTmpFree(pszResultAddress4Start);

    if (pszInternalAddressStart)
        RTMemTmpFree(pszInternalAddressStart);

    if (pszInternalPortStart)
        RTMemTmpFree(pszInternalPortStart);

    return (uint32_t)(returnValue - (returnValue * 2)); // make it negative...
}
/**
 * Worker for VbgdDarwinIOCtl that takes the slow IOCtl functions.
 *
 * @returns Darwin errno.
 *
 * @param pSession  The session.
 * @param iCmd      The IOCtl command.
 * @param pData     Pointer to the kernel copy of the data buffer.
 * @param pProcess  The calling process.
 */
static int VbgdDarwinIOCtlSlow(PVBOXGUESTSESSION pSession, u_long iCmd, caddr_t pData, struct proc *pProcess)
{
    LogFlow(("VbgdDarwinIOCtlSlow: pSession=%p iCmd=%p pData=%p pProcess=%p\n", pSession, iCmd, pData, pProcess));


    /*
     * Buffered or unbuffered?
     */
    void *pvReqData;
    user_addr_t pUser = 0;
    void *pvPageBuf = NULL;
    uint32_t cbReq = IOCPARM_LEN(iCmd);
    if ((IOC_DIRMASK & iCmd) == IOC_INOUT)
    {
        /*
         * Raw buffered request data, common code validates it.
         */
        pvReqData = pData;
    }
    else if ((IOC_DIRMASK & iCmd) == IOC_VOID && !cbReq)
    {
        /*
         * Get the header and figure out how much we're gonna have to read.
         */
        VBGLBIGREQ Hdr;
        pUser = (user_addr_t)*(void **)pData;
        int rc = copyin(pUser, &Hdr, sizeof(Hdr));
        if (RT_UNLIKELY(rc))
        {
            Log(("VbgdDarwinIOCtlSlow: copyin(%llx,Hdr,) -> %#x; iCmd=%#lx\n", (unsigned long long)pUser, rc, iCmd));
            return rc;
        }
        if (RT_UNLIKELY(Hdr.u32Magic != VBGLBIGREQ_MAGIC))
        {
            Log(("VbgdDarwinIOCtlSlow: bad magic u32Magic=%#x; iCmd=%#lx\n", Hdr.u32Magic, iCmd));
            return EINVAL;
        }
        cbReq = Hdr.cbData;
        if (RT_UNLIKELY(cbReq > _1M*16))
        {
            Log(("VbgdDarwinIOCtlSlow: %#x; iCmd=%#lx\n", Hdr.cbData, iCmd));
            return EINVAL;
        }
        pUser = Hdr.pvDataR3;

        /*
         * Allocate buffer and copy in the data.
         */
        pvReqData = RTMemTmpAlloc(cbReq);
        if (!pvReqData)
            pvPageBuf = pvReqData = IOMallocAligned(RT_ALIGN_Z(cbReq, PAGE_SIZE), 8);
        if (RT_UNLIKELY(!pvReqData))
        {
            Log(("VbgdDarwinIOCtlSlow: failed to allocate buffer of %d bytes; iCmd=%#lx\n", cbReq, iCmd));
            return ENOMEM;
        }
        rc = copyin(pUser, pvReqData, Hdr.cbData);
        if (RT_UNLIKELY(rc))
        {
            Log(("VbgdDarwinIOCtlSlow: copyin(%llx,%p,%#x) -> %#x; iCmd=%#lx\n",
                 (unsigned long long)pUser, pvReqData, Hdr.cbData, rc, iCmd));
            if (pvPageBuf)
                IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cbReq, PAGE_SIZE));
            else
                RTMemTmpFree(pvReqData);
            return rc;
        }
    }
    else
    {
        Log(("VbgdDarwinIOCtlSlow: huh? cbReq=%#x iCmd=%#lx\n", cbReq, iCmd));
        return EINVAL;
    }

    /*
     * Process the IOCtl.
     */
    size_t cbReqRet = 0;
    int rc = VBoxGuestCommonIOCtl(iCmd, &g_DevExt, pSession, pvReqData, cbReq, &cbReqRet);
    if (RT_SUCCESS(rc))
    {
        /*
         * If not buffered, copy back the buffer before returning.
         */
        if (pUser)
        {
            if (cbReqRet > cbReq)
            {
                Log(("VbgdDarwinIOCtlSlow: too much output! %#x > %#x; uCmd=%#lx!\n", cbReqRet, cbReq, iCmd));
                cbReqRet = cbReq;
            }
            rc = copyout(pvReqData, pUser, cbReqRet);
            if (RT_UNLIKELY(rc))
                Log(("VbgdDarwinIOCtlSlow: copyout(%p,%llx,%#x) -> %d; uCmd=%#lx!\n",
                     pvReqData, (unsigned long long)pUser, cbReqRet, rc, iCmd));

            /* cleanup */
            if (pvPageBuf)
                IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cbReq, PAGE_SIZE));
            else
                RTMemTmpFree(pvReqData);
        }
        else
            rc = 0;
    }
    else
    {
        /*
         * The request failed, just clean up.
         */
        if (pUser)
        {
            if (pvPageBuf)
                IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cbReq, PAGE_SIZE));
            else
                RTMemTmpFree(pvReqData);
        }

        Log(("VbgdDarwinIOCtlSlow: pid=%d iCmd=%lx pData=%p failed, rc=%d\n", proc_pid(pProcess), iCmd, (void *)pData, rc));
        rc = EINVAL;
    }

    Log2(("VbgdDarwinIOCtlSlow: returns %d\n", rc));
    return rc;
}
Exemple #19
0
static void tstObjectCreateTemp(const char *pszSubTest, const char *pszTemplate, bool fFile, RTFMODE fMode, unsigned cTimes, bool fSkipXCheck)
{
    RTTestISub(pszSubTest);
    const char *pcszAPI = fFile ? "RTFileCreateTemp" : "RTDirCreateTemp";

    /* Allocate the result array. */
    char **papszNames = (char **)RTMemTmpAllocZ(cTimes * sizeof(char *));
    RTTESTI_CHECK_RETV(papszNames != NULL);

    /* The test loop. */
    unsigned i;
    for (i = 0; i < cTimes; i++)
    {
        int rc;
        char szName[RTPATH_MAX];
        RTFMODE fModeFinal;

        RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), pszTemplate), VINF_SUCCESS);
        if (RT_FAILURE(rc))
            break;

        RTTESTI_CHECK(papszNames[i] = RTStrDup(szName));
        if (!papszNames[i])
            break;

        rc =   fFile
             ? RTFileCreateTemp(papszNames[i], fMode)
             : RTDirCreateTemp(papszNames[i], fMode);
        if (rc != VINF_SUCCESS)
        {
            RTTestIFailed("%s(%s, %#o) call #%u -> %Rrc\n", pcszAPI, szName, (int)fMode, i, rc);
            RTStrFree(papszNames[i]);
            papszNames[i] = NULL;
            break;
        }
        /* Check that the final permissions are not more permissive than
         * the ones requested (less permissive is fine, c.f. umask etc.).
         * I mask out the group as I am not sure how we deal with that on
         * Windows. */
        RTTESTI_CHECK_RC_OK(rc = RTPathGetMode(papszNames[i], &fModeFinal));
        if (RT_SUCCESS(rc))
        {
            fModeFinal &= (RTFS_UNIX_IRWXU | RTFS_UNIX_IRWXO);
            RTTESTI_CHECK_MSG((fModeFinal & ~fMode) == 0,
                              ("%s: szName   %s\nfModeFinal ~= %#o, expected %#o\n",
                               pcszAPI, szName, fModeFinal, (int)fMode));
        }
        RTTestIPrintf(RTTESTLVL_DEBUG, "%s: %s\n", pcszAPI, papszNames[i]);
        RTTESTI_CHECK_MSG(strlen(szName) == strlen(papszNames[i]), ("%s: szName   %s\nReturned %s\n", pcszAPI, szName, papszNames[i]));
        if (!fSkipXCheck)
            RTTESTI_CHECK_MSG(strchr(RTPathFilename(papszNames[i]), 'X') == NULL, ("%s: szName   %s\nReturned %s\n", pcszAPI, szName, papszNames[i]));
    }

    /* cleanup */
    while (i-- > 0)
    {
        if (fFile)
            RTTESTI_CHECK_RC(RTFileDelete(papszNames[i]), VINF_SUCCESS);
        else
            RTTESTI_CHECK_RC(RTDirRemove(papszNames[i]), VINF_SUCCESS);
        RTStrFree(papszNames[i]);
    }
    RTMemTmpFree(papszNames);
}
/**
 * Worker for VBoxSupDrvIOCtl that takes the slow IOCtl functions.
 *
 * @returns Solaris errno.
 *
 * @param   pSession    The session.
 * @param   Cmd         The IOCtl command.
 * @param   Mode        Information bitfield (for specifying ownership of data)
 * @param   iArg        User space address of the request buffer.
 */
static int VBoxDrvSolarisIOCtlSlow(PSUPDRVSESSION pSession, int iCmd, int Mode, intptr_t iArg)
{
    int         rc;
    uint32_t    cbBuf = 0;
    union
    {
        SUPREQHDR   Hdr;
        uint8_t     abBuf[64];
    }           StackBuf;
    PSUPREQHDR  pHdr;


    /*
     * Read the header.
     */
    if (RT_UNLIKELY(IOCPARM_LEN(iCmd) != sizeof(StackBuf.Hdr)))
    {
        LogRel(("VBoxDrvSolarisIOCtlSlow: iCmd=%#x len %d expected %d\n", iCmd, IOCPARM_LEN(iCmd), sizeof(StackBuf.Hdr)));
        return EINVAL;
    }
    rc = ddi_copyin((void *)iArg, &StackBuf.Hdr, sizeof(StackBuf.Hdr), Mode);
    if (RT_UNLIKELY(rc))
    {
        LogRel(("VBoxDrvSolarisIOCtlSlow: ddi_copyin(,%#lx,) failed; iCmd=%#x. rc=%d\n", iArg, iCmd, rc));
        return EFAULT;
    }
    if (RT_UNLIKELY((StackBuf.Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) != SUPREQHDR_FLAGS_MAGIC))
    {
        LogRel(("VBoxDrvSolarisIOCtlSlow: bad header magic %#x; iCmd=%#x\n", StackBuf.Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK, iCmd));
        return EINVAL;
    }
    cbBuf = RT_MAX(StackBuf.Hdr.cbIn, StackBuf.Hdr.cbOut);
    if (RT_UNLIKELY(    StackBuf.Hdr.cbIn < sizeof(StackBuf.Hdr)
                    ||  StackBuf.Hdr.cbOut < sizeof(StackBuf.Hdr)
                    ||  cbBuf > _1M*16))
    {
        LogRel(("VBoxDrvSolarisIOCtlSlow: max(%#x,%#x); iCmd=%#x\n", StackBuf.Hdr.cbIn, StackBuf.Hdr.cbOut, iCmd));
        return EINVAL;
    }

    /*
     * Buffer the request.
     */
    if (cbBuf <= sizeof(StackBuf))
        pHdr = &StackBuf.Hdr;
    else
    {
        pHdr = RTMemTmpAlloc(cbBuf);
        if (RT_UNLIKELY(!pHdr))
        {
            LogRel(("VBoxDrvSolarisIOCtlSlow: failed to allocate buffer of %d bytes for iCmd=%#x.\n", cbBuf, iCmd));
            return ENOMEM;
        }
    }
    rc = ddi_copyin((void *)iArg, pHdr, cbBuf, Mode);
    if (RT_UNLIKELY(rc))
    {
        LogRel(("VBoxDrvSolarisIOCtlSlow: copy_from_user(,%#lx, %#x) failed; iCmd=%#x. rc=%d\n", iArg, cbBuf, iCmd, rc));
        if (pHdr != &StackBuf.Hdr)
            RTMemFree(pHdr);
        return EFAULT;
    }

    /*
     * Process the IOCtl.
     */
    rc = supdrvIOCtl(iCmd, &g_DevExt, pSession, pHdr, cbBuf);

    /*
     * Copy ioctl data and output buffer back to user space.
     */
    if (RT_LIKELY(!rc))
    {
        uint32_t cbOut = pHdr->cbOut;
        if (RT_UNLIKELY(cbOut > cbBuf))
        {
            LogRel(("VBoxDrvSolarisIOCtlSlow: too much output! %#x > %#x; iCmd=%#x!\n", cbOut, cbBuf, iCmd));
            cbOut = cbBuf;
        }
        rc = ddi_copyout(pHdr, (void *)iArg, cbOut, Mode);
        if (RT_UNLIKELY(rc != 0))
        {
            /* this is really bad */
            LogRel(("VBoxDrvSolarisIOCtlSlow: ddi_copyout(,%p,%d) failed. rc=%d\n", (void *)iArg, cbBuf, rc));
            rc = EFAULT;
        }
    }
    else
        rc = EINVAL;

    if (pHdr != &StackBuf.Hdr)
        RTMemTmpFree(pHdr);
    return rc;
}
RTDECL(int) RTCrStoreCertAddWantedFromFishingExpedition(RTCRSTORE hStore, uint32_t fFlags,
                                                        PCRTCRCERTWANTED paWanted, size_t cWanted,
                                                        bool *pafFound, PRTERRINFO pErrInfo)
{
    int rc = VINF_SUCCESS;
    int rc2;

    /*
     * Validate input.
     */
    AssertReturn(!(fFlags & ~(RTCRCERTCTX_F_ADD_IF_NOT_FOUND | RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR)), VERR_INVALID_FLAGS);
    fFlags |= RTCRCERTCTX_F_ADD_IF_NOT_FOUND | RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR; /* force these! */
    AssertReturn(cWanted, VERR_NOT_FOUND);
    for (uint32_t i = 0; i < cWanted; i++)
    {
        AssertReturn(!paWanted[i].pszSubject || *paWanted[i].pszSubject, VERR_INVALID_PARAMETER);
        AssertReturn(   paWanted[i].pszSubject
                     || paWanted[i].fSha1Fingerprint
                     || paWanted[i].fSha512Fingerprint,
                     VERR_INVALID_PARAMETER);
    }

    /*
     * Make sure we've got a result array.
     */
    bool *pafFoundFree = NULL;
    if (!pafFound)
    {
        pafFound = pafFoundFree = (bool *)RTMemTmpAllocZ(sizeof(bool) * cWanted);
        AssertReturn(pafFound, VERR_NO_TMP_MEMORY);
    }

    /*
     * Search the user and system stores first.
     */
    bool fAllFound = false;
    RTCRSTORE hTmpStore;
    for (int iStoreId = RTCRSTOREID_INVALID + 1; iStoreId < RTCRSTOREID_END; iStoreId++)
    {
        rc2 = RTCrStoreCreateSnapshotById(&hTmpStore, (RTCRSTOREID)iStoreId, NULL);
        if (RT_SUCCESS(rc2))
        {
            rc2 = RTCrStoreCertAddWantedFromStore(hStore, fFlags, hTmpStore, paWanted, cWanted, pafFound);
            RTCrStoreRelease(hTmpStore);
            fAllFound = rc2 == VINF_SUCCESS;
            if (fAllFound)
                break;
        }
    }

    /*
     * Search alternative file based stores.
     */
    if (!fAllFound)
    {
        static const char * const s_apszFiles[] =
        {
            PREFIX_UNIXROOT "/usr/share/ca-certificates/trust-source/mozilla.neutral-trust.crt",
            PREFIX_UNIXROOT "/usr/share/ca-certificates/trust-source/mozilla.trust.crt",
            PREFIX_UNIXROOT "/usr/share/doc/mutt/samples/ca-bundle.crt",
            PREFIX_UNIXROOT "/usr/jdk/latest/jre/lib/security/cacerts",
            PREFIX_UNIXROOT "/usr/share/curl/curl-ca-bundle.crt",
#ifdef RT_OS_DARWIN
            "/opt/local/share/curl/curl-ca-bundle.crt",
            "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/security/cacerts",
            "/System/Library/Java/Support/CoreDeploy.bundle/Contents/Home/lib/security/cacerts",
            "/System/Library/Java/Support/CoreDeploy.bundle/Contents/JavaAppletPlugin.plugin/Contents/Home/lib/security/cacerts",
            "/System/Library/Java/Support/Deploy.bundle/Contents/Home/lib/security/cacerts",
            "/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/MacOS/itms/java/lib/security/cacerts",
            "/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/itms/java/lib/security/cacerts",
            "/Applications/Xcode-beta.app/Contents/Applications/Application Loader.app/Contents/itms/java/lib/security/cacerts",
            "/System/Library/Java/JavaVirtualMachines/*/Contents/Home/lib/security/cacerts",
#endif
#ifdef RT_OS_LINUX
            PREFIX_UNIXROOT "/etc/ssl/certs/java/cacerts",
            PREFIX_UNIXROOT "/usr/lib/j*/*/jre/lib/security/cacerts",
            PREFIX_UNIXROOT "/opt/*/jre/lib/security/cacerts",
#endif
#ifdef RT_OS_SOLARIS
            PREFIX_UNIXROOT "/usr/java/jre/lib/security/cacerts",
            PREFIX_UNIXROOT "/usr/jdk/instances/*/jre/lib/security/cacerts",
#endif
#ifdef RT_OS_WINDOWS
            "${AllProgramFiles}/Git/bin/curl-ca-bundle.crt",
            "${AllProgramFiles}/Mercurial/hgrc.d/cacert.pem",
            "${AllProgramFiles}/Java/jre*/lib/security/cacerts",
            "${AllProgramFiles}/Java/jdk*/jre/lib/security/cacerts",
            "${AllProgramFiles}/HexChat/cert.pem",
            "${SystemDrive}/BitNami/*/git/bin/curl-ca-bundle.crt",
            "${SystemDrive}/BitNami/*/heroku/data/cacert.pem",
            "${SystemDrive}/BitNami/*/heroku/vendor/gems/excon*/data/cacert.pem",
            "${SystemDrive}/BitNami/*/php/PEAR/AWSSDKforPHP/lib/requstcore/cacert.pem",
#endif
        };
        for (uint32_t i = 0; i < RT_ELEMENTS(s_apszFiles) && !fAllFound; i++)
        {
            PCRTPATHGLOBENTRY pResultHead;
            rc2 = RTPathGlob(s_apszFiles[i], RTPATHGLOB_F_NO_DIRS, &pResultHead, NULL);
            if (RT_SUCCESS(rc2))
            {
                for (PCRTPATHGLOBENTRY pCur = pResultHead; pCur; pCur = pCur->pNext)
                {
                    rc2 = RTCrStoreCertAddWantedFromFile(hStore, fFlags, pCur->szPath, paWanted, cWanted, pafFound, pErrInfo);
                    fAllFound = rc2 == VINF_SUCCESS;
                    if (fAllFound)
                        break;
                }
                RTPathGlobFree(pResultHead);
            }
        }
    }

    /*
     * Search alternative directory based stores.
     */
    if (!fAllFound)
    {
        static const char * const s_apszFiles[] =
        {
            PREFIX_UNIXROOT "/usr/share/ca-certificates/mozilla/",
#ifdef RT_OS_DARWIN
            "/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/ssl_certs/",
#endif
#ifdef RT_OS_SOLARIS
            "/etc/certs/",
            "/etc/crypto/certs/",
#endif
#ifdef RT_OS_WINDOWS
            "${AllProgramFiles}/Git/ssl/certs/",
            "${AllProgramFiles}/Git/ssl/certs/expired/",
            "${AllProgramFiles}/Common Files/Apple/Internet Services/security.resources/roots/",
            "${AllProgramFiles}/Raptr/ca-certs/",
            "${SystemDrive}/Bitname/*/git/ssl/certs/",
            "${SystemDrive}/Bitnami/*/git/ssl/certs/expired/",
#endif
        };
        for (uint32_t i = 0; i < RT_ELEMENTS(s_apszFiles) && !fAllFound; i++)
        {
            PCRTPATHGLOBENTRY pResultHead;
            rc2 = RTPathGlob(s_apszFiles[i], RTPATHGLOB_F_ONLY_DIRS, &pResultHead, NULL);
            if (RT_SUCCESS(rc2))
            {
                for (PCRTPATHGLOBENTRY pCur = pResultHead; pCur; pCur = pCur->pNext)
                {
                    rc2 = RTCrStoreCertAddWantedFromDir(hStore, fFlags, pCur->szPath, NULL /*paSuffixes*/, 0 /*cSuffixes*/,
                                                        paWanted, cWanted, pafFound, pErrInfo);
                    fAllFound = rc2 == VINF_SUCCESS;
                    if (fAllFound)
                        break;
                }
                RTPathGlobFree(pResultHead);
            }
        }
    }

    /*
     * If all found, return VINF_SUCCESS, otherwise warn that we didn't find everything.
     */
    if (RT_SUCCESS(rc))
    {
        size_t cFound = rtCrStoreCountFound(pafFound, cWanted);
        Assert(cFound == cWanted || !fAllFound);
        if (cFound == cWanted)
            rc = VINF_SUCCESS;
        else if (cFound > 0)
            rc = VWRN_NOT_FOUND;
        else
            rc = VERR_NOT_FOUND;
    }

    if (pafFoundFree)
        RTMemTmpFree(pafFoundFree);
    return rc;
}
Exemple #22
0
/**
 * Converts a string from one charset to another without using the handle cache.
 *
 * @returns IPRT status code.
 *
 * @param   pvInput         Pointer to intput string.
 * @param   cbInput         Size (in bytes) of input string. Excludes any terminators.
 * @param   pszInputCS      Codeset of the input string.
 * @param   ppvOutput       Pointer to pointer to output buffer if cbOutput > 0.
 *                          If cbOutput is 0 this is where the pointer to the allocated
 *                          buffer is stored.
 * @param   cbOutput        Size of the passed in buffer.
 * @param   pszOutputCS     Codeset of the input string.
 * @param   cFactor         Input vs. output size factor.
 */
static int rtStrConvertUncached(const void *pvInput, size_t cbInput, const char *pszInputCS,
                                void **ppvOutput, size_t cbOutput, const char *pszOutputCS,
                                unsigned cFactor)
{
    /*
     * Allocate buffer
     */
    bool    fUcs2Term;
    void   *pvOutput;
    size_t  cbOutput2;
    if (!cbOutput)
    {
        cbOutput2 = cbInput * cFactor;
        pvOutput = RTMemTmpAlloc(cbOutput2 + sizeof(RTUTF16));
        if (!pvOutput)
            return VERR_NO_TMP_MEMORY;
        fUcs2Term = true;
    }
    else
    {
        pvOutput = *ppvOutput;
        fUcs2Term = !strcmp(pszOutputCS, "UCS-2");
        cbOutput2 = cbOutput - (fUcs2Term ? sizeof(RTUTF16) : 1);
        if (cbOutput2 > cbOutput)
            return VERR_BUFFER_OVERFLOW;
    }

    /*
     * Use a loop here to retry with bigger buffers.
     */
    for (unsigned cTries = 10; cTries > 0; cTries--)
    {
        /*
         * Create conversion object.
         */
#if defined(RT_OS_SOLARIS) || defined(RT_OS_NETBSD)
        /* Some systems don't grok empty codeset strings, so help them find the current codeset. */
        if (!*pszInputCS)
            pszInputCS = rtStrGetLocaleCodeset();
        if (!*pszOutputCS)
            pszOutputCS = rtStrGetLocaleCodeset();
#endif
        IPRT_ALIGNMENT_CHECKS_DISABLE(); /* glibc causes trouble */
        iconv_t icHandle = iconv_open(pszOutputCS, pszInputCS);
        IPRT_ALIGNMENT_CHECKS_ENABLE();
        if (icHandle != (iconv_t)-1)
        {
            /*
             * Do the conversion.
             */
            size_t      cbInLeft = cbInput;
            size_t      cbOutLeft = cbOutput2;
            const void *pvInputLeft = pvInput;
            void       *pvOutputLeft = pvOutput;
            size_t      cchNonRev;
#if defined(RT_OS_LINUX) || defined(RT_OS_HAIKU) || defined(RT_OS_SOLARIS) || (defined(RT_OS_DARWIN) && defined(_DARWIN_FEATURE_UNIX_CONFORMANCE)) /* there are different opinions about the constness of the input buffer. */
            cchNonRev = iconv(icHandle, (char **)&pvInputLeft, &cbInLeft, (char **)&pvOutputLeft, &cbOutLeft);
#else
            cchNonRev = iconv(icHandle, (const char **)&pvInputLeft, &cbInLeft, (char **)&pvOutputLeft, &cbOutLeft);
#endif
            if (cchNonRev != (size_t)-1)
            {
                if (!cbInLeft)
                {
                    /*
                     * We're done, just add the terminator and return.
                     * (Two terminators to support UCS-2 output, too.)
                     */
                    iconv_close(icHandle);
                    ((char *)pvOutputLeft)[0] = '\0';
                    if (fUcs2Term)
                        ((char *)pvOutputLeft)[1] = '\0';
                    *ppvOutput = pvOutput;
                    if (cchNonRev == 0)
                        return VINF_SUCCESS;
                    return VWRN_NO_TRANSLATION;
                }
                errno = E2BIG;
            }
            iconv_close(icHandle);

            /*
             * If we failed because of output buffer space we'll
             * increase the output buffer size and retry.
             */
            if (errno == E2BIG)
            {
                if (!cbOutput)
                {
                    RTMemTmpFree(pvOutput);
                    cbOutput2 *= 2;
                    pvOutput = RTMemTmpAlloc(cbOutput2 + sizeof(RTUTF16));
                    if (!pvOutput)
                        return VERR_NO_TMP_MEMORY;
                    continue;
                }
                return VERR_BUFFER_OVERFLOW;
            }
        }
        break;
    }

    /* failure */
    if (!cbOutput)
        RTMemTmpFree(pvOutput);
    return VERR_NO_TRANSLATION;
}
Exemple #23
0
int  VBOXCALL   supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename)
{
    pImage->pvNtSectionObj = NULL;
    pImage->hMemLock = NIL_RTR0MEMOBJ;

#ifdef VBOX_WITHOUT_NATIVE_R0_LOADER
# ifndef RT_ARCH_X86
#  error "VBOX_WITHOUT_NATIVE_R0_LOADER is only safe on x86."
# endif
    NOREF(pDevExt); NOREF(pszFilename); NOREF(pImage);
    return VERR_NOT_SUPPORTED;

#else
    /*
     * Convert the filename from DOS UTF-8 to NT UTF-16.
     */
    size_t cwcFilename;
    int rc = RTStrCalcUtf16LenEx(pszFilename, RTSTR_MAX, &cwcFilename);
    if (RT_FAILURE(rc))
        return rc;

    PRTUTF16 pwcsFilename = (PRTUTF16)RTMemTmpAlloc((4 + cwcFilename + 1) * sizeof(RTUTF16));
    if (!pwcsFilename)
        return VERR_NO_TMP_MEMORY;

    pwcsFilename[0] = '\\';
    pwcsFilename[1] = '?';
    pwcsFilename[2] = '?';
    pwcsFilename[3] = '\\';
    PRTUTF16 pwcsTmp = &pwcsFilename[4];
    rc = RTStrToUtf16Ex(pszFilename, RTSTR_MAX, &pwcsTmp, cwcFilename + 1, NULL);
    if (RT_SUCCESS(rc))
    {
        /*
         * Try load it.
         */
        MYSYSTEMGDIDRIVERINFO Info;
        RtlInitUnicodeString(&Info.Name, pwcsFilename);
        Info.ImageAddress           = NULL;
        Info.SectionPointer         = NULL;
        Info.EntryPointer           = NULL;
        Info.ExportSectionPointer   = NULL;
        Info.ImageLength            = 0;

        NTSTATUS rcNt = ZwSetSystemInformation(MY_SystemLoadGdiDriverInSystemSpaceInformation, &Info, sizeof(Info));
        if (NT_SUCCESS(rcNt))
        {
            pImage->pvImage = Info.ImageAddress;
            pImage->pvNtSectionObj = Info.SectionPointer;
            Log(("ImageAddress=%p SectionPointer=%p ImageLength=%#x cbImageBits=%#x rcNt=%#x '%ls'\n",
                 Info.ImageAddress, Info.SectionPointer, Info.ImageLength, pImage->cbImageBits, rcNt, Info.Name.Buffer));
# ifdef DEBUG_bird
            SUPR0Printf("ImageAddress=%p SectionPointer=%p ImageLength=%#x cbImageBits=%#x rcNt=%#x '%ws'\n",
                        Info.ImageAddress, Info.SectionPointer, Info.ImageLength, pImage->cbImageBits, rcNt, Info.Name.Buffer);
# endif
            if (pImage->cbImageBits == Info.ImageLength)
            {
                /*
                 * Lock down the entire image, just to be on the safe side.
                 */
                rc = RTR0MemObjLockKernel(&pImage->hMemLock, pImage->pvImage, pImage->cbImageBits, RTMEM_PROT_READ);
                if (RT_FAILURE(rc))
                {
                    pImage->hMemLock = NIL_RTR0MEMOBJ;
                    supdrvOSLdrUnload(pDevExt, pImage);
                }
            }
            else
            {
                supdrvOSLdrUnload(pDevExt, pImage);
                rc = VERR_LDR_MISMATCH_NATIVE;
            }
        }
        else
        {
            Log(("rcNt=%#x '%ls'\n", rcNt, pwcsFilename));
            SUPR0Printf("VBoxDrv: rcNt=%x '%ws'\n", rcNt, pwcsFilename);
            switch (rcNt)
            {
                case /* 0xc0000003 */ STATUS_INVALID_INFO_CLASS:
# ifdef RT_ARCH_AMD64
                    /* Unwind will crash and BSOD, so no fallback here! */
                    rc = VERR_NOT_IMPLEMENTED;
# else
                    /*
                     * Use the old way of loading the modules.
                     *
                     * Note! We do *NOT* try class 26 because it will probably
                     *       not work correctly on terminal servers and such.
                     */
                    rc = VERR_NOT_SUPPORTED;
# endif
                    break;
                case /* 0xc0000034 */ STATUS_OBJECT_NAME_NOT_FOUND:
                    rc = VERR_MODULE_NOT_FOUND;
                    break;
                case /* 0xC0000263 */ STATUS_DRIVER_ENTRYPOINT_NOT_FOUND:
                    rc = VERR_LDR_IMPORTED_SYMBOL_NOT_FOUND;
                    break;
                case    0xC0000428 /* STATUS_INVALID_IMAGE_HASH */ :
                    rc = VERR_LDR_IMAGE_HASH;
                    break;
                case    0xC000010E /* STATUS_IMAGE_ALREADY_LOADED */ :
                    Log(("WARNING: see @bugref{4853} for cause of this failure on Windows 7 x64\n"));
                    rc = VERR_ALREADY_LOADED;
                    break;
                default:
                    rc = VERR_LDR_GENERAL_FAILURE;
                    break;
            }

            pImage->pvNtSectionObj = NULL;
        }
    }

    RTMemTmpFree(pwcsFilename);
    NOREF(pDevExt);
    return rc;
#endif
}
/**
 * Deal with the 'slow' I/O control requests.
 *
 * @returns 0 on success, appropriate errno on failure.
 * @param   pSession    The session.
 * @param   ulCmd       The command.
 * @param   pvData      The request data.
 * @param   pTd         The calling thread.
 */
static int vgdrvFreeBSDIOCtlSlow(PVBOXGUESTSESSION pSession, u_long ulCmd, caddr_t pvData, struct thread *pTd)
{
    PVBGLREQHDR pHdr;
    uint32_t    cbReq = IOCPARM_LEN(ulCmd);
    void       *pvUser = NULL;

    /*
     * Buffered request?
     */
    if ((IOC_DIRMASK & ulCmd) == IOC_INOUT)
    {
        pHdr = (PVBGLREQHDR)pvData;
        if (RT_UNLIKELY(cbReq < sizeof(*pHdr)))
        {
            LogRel(("vgdrvFreeBSDIOCtlSlow: cbReq=%#x < %#x; ulCmd=%#lx\n", cbReq, (int)sizeof(*pHdr), ulCmd));
            return EINVAL;
        }
        if (RT_UNLIKELY(pHdr->uVersion != VBGLREQHDR_VERSION))
        {
            LogRel(("vgdrvFreeBSDIOCtlSlow: bad uVersion=%#x; ulCmd=%#lx\n", pHdr->uVersion, ulCmd));
            return EINVAL;
        }
        if (RT_UNLIKELY(   RT_MAX(pHdr->cbIn, pHdr->cbOut) != cbReq
                        || pHdr->cbIn < sizeof(*pHdr)
                        || (pHdr->cbOut < sizeof(*pHdr) && pHdr->cbOut != 0)))
        {
            LogRel(("vgdrvFreeBSDIOCtlSlow: max(%#x,%#x) != %#x; ulCmd=%#lx\n", pHdr->cbIn, pHdr->cbOut, cbReq, ulCmd));
            return EINVAL;
        }
    }
    /*
     * Big unbuffered request?
     */
    else if ((IOC_DIRMASK & ulCmd) == IOC_VOID && !cbReq)
    {
        /*
         * Read the header, validate it and figure out how much that needs to be buffered.
         */
        VBGLREQHDR Hdr;
        pvUser = *(void **)pvData;
        int rc = copyin(pvUser, &Hdr, sizeof(Hdr));
        if (RT_UNLIKELY(rc))
        {
            LogRel(("vgdrvFreeBSDIOCtlSlow: copyin(%p,Hdr,) -> %#x; ulCmd=%#lx\n", pvUser, rc, ulCmd));
            return rc;
        }
        if (RT_UNLIKELY(Hdr.uVersion != VBGLREQHDR_VERSION))
        {
            LogRel(("vgdrvFreeBSDIOCtlSlow: bad uVersion=%#x; ulCmd=%#lx\n", Hdr.uVersion, ulCmd));
            return EINVAL;
        }
        cbReq = RT_MAX(Hdr.cbIn, Hdr.cbOut);
        if (RT_UNLIKELY(   Hdr.cbIn < sizeof(Hdr)
                        || (Hdr.cbOut < sizeof(Hdr) && Hdr.cbOut != 0)
                        || cbReq > _1M*16))
        {
            LogRel(("vgdrvFreeBSDIOCtlSlow: max(%#x,%#x); ulCmd=%#lx\n", Hdr.cbIn, Hdr.cbOut, ulCmd));
            return EINVAL;
        }

        /*
         * Allocate buffer and copy in the data.
         */
        pHdr = (PVBGLREQHDR)RTMemTmpAlloc(cbReq);
        if (RT_UNLIKELY(!pHdr))
        {
            LogRel(("vgdrvFreeBSDIOCtlSlow: failed to allocate buffer of %d bytes; ulCmd=%#lx\n", cbReq, ulCmd));
            return ENOMEM;
        }
        rc = copyin(pvUser, pHdr, Hdr.cbIn);
        if (RT_UNLIKELY(rc))
        {
            LogRel(("vgdrvFreeBSDIOCtlSlow: copyin(%p,%p,%#x) -> %#x; ulCmd=%#lx\n",
                        pvUser, pHdr, Hdr.cbIn, rc, ulCmd));
            RTMemTmpFree(pHdr);
            return rc;
        }
        if (Hdr.cbIn < cbReq)
            RT_BZERO((uint8_t *)pHdr + Hdr.cbIn, cbReq - Hdr.cbIn);
    }
    else
    {
        Log(("vgdrvFreeBSDIOCtlSlow: huh? cbReq=%#x ulCmd=%#lx\n", cbReq, ulCmd));
        return EINVAL;
    }

    /*
     * Process the IOCtl.
     */
    int rc = VGDrvCommonIoCtl(ulCmd, &g_DevExt, pSession, pHdr, cbReq);
    if (RT_LIKELY(!rc))
    {
        /*
         * If unbuffered, copy back the result before returning.
         */
        if (pvUser)
        {
            uint32_t cbOut = pHdr->cbOut;
            if (cbOut > cbReq)
            {
                LogRel(("vgdrvFreeBSDIOCtlSlow: too much output! %#x > %#x; uCmd=%#lx!\n", cbOut, cbReq, ulCmd));
                cbOut = cbReq;
            }
            rc = copyout(pHdr, pvUser, cbOut);
            if (RT_UNLIKELY(rc))
                LogRel(("vgdrvFreeBSDIOCtlSlow: copyout(%p,%p,%#x) -> %d; uCmd=%#lx!\n", pHdr, pvUser, cbOut, rc, ulCmd));

            Log(("vgdrvFreeBSDIOCtlSlow: returns %d / %d ulCmd=%lx\n", 0, pHdr->rc, ulCmd));

            /* cleanup */
            RTMemTmpFree(pHdr);
        }
    }
    else
    {
        /*
         * The request failed, just clean up.
         */
        if (pvUser)
            RTMemTmpFree(pHdr);

        Log(("vgdrvFreeBSDIOCtlSlow: ulCmd=%lx pData=%p failed, rc=%d\n", ulCmd, pvData, rc));
        rc = EINVAL;
    }

    return rc;
}
Exemple #25
0
/**
 * Tests if the given string is a valid IPv6 address.
 *
 * @returns 0 if valid, some random number if not.  THIS IS NOT AN IPRT STATUS!
 * @param psz                  The string to test
 * @param pszResultAddress     plain address, optional read "valid addresses
 *                             and strings" above.
 * @param resultAddressSize    size of pszResultAddress
 * @param addressOnly          return only the plain address (no scope)
 *                             Ignored, and will always return the if id
 */
static int rtNetIpv6CheckAddrStr(const char *psz, char *pszResultAddress, size_t resultAddressSize, bool addressOnly, bool followRfc)
{
    int rc;
    int rc2;
    int returnValue;

    char *p = NULL, *pl = NULL;

    size_t memAllocMaxSize = RT_MAX(strlen(psz), resultAddressSize) + 40;

    char *pszAddressOutLocal = (char *)RTMemTmpAlloc(memAllocMaxSize);
    char *pszIfIdOutLocal = (char *)RTMemTmpAlloc(memAllocMaxSize);
    char *pszAddressRfcOutLocal = (char *)RTMemTmpAlloc(memAllocMaxSize);

    if (!pszAddressOutLocal || !pszIfIdOutLocal || !pszAddressRfcOutLocal)
        return VERR_NO_TMP_MEMORY;

    memset(pszAddressOutLocal, '\0', memAllocMaxSize);
    memset(pszIfIdOutLocal, '\0', memAllocMaxSize);
    memset(pszAddressRfcOutLocal, '\0', memAllocMaxSize);

    rc = rtStrParseAddrStr6(psz, strlen(psz), pszAddressOutLocal, memAllocMaxSize, NULL, pszIfIdOutLocal, memAllocMaxSize, NULL, NULL, followRfc);

    if (rc == 0)
        returnValue = VINF_SUCCESS;

    if (rc == 0 && pszResultAddress)
    {
        // convert the 32 characters to a valid, shortened ipv6 address

        rc2 = rtStrToIpAddr6Str((const char *)pszAddressOutLocal, pszAddressRfcOutLocal, memAllocMaxSize, NULL, 0, followRfc);

        if (rc2 != 0)
            returnValue = 951;

        // this is a temporary solution
        if (!returnValue && strlen(pszIfIdOutLocal) > 0) // the if identifier is copied over _ALWAYS_ && !addressOnly)
        {
            p = pszAddressRfcOutLocal + strlen(pszAddressRfcOutLocal);

            *p = '%';

            p++;

            pl = (char *)memcpy(p, pszIfIdOutLocal, strlen(pszIfIdOutLocal));

            if (!pl)
                returnValue = VERR_NOT_SUPPORTED;
        }

        pl = NULL;

        pl = (char *)memcpy(pszResultAddress, pszAddressRfcOutLocal, strlen(pszAddressRfcOutLocal));

        if (!pl)
            returnValue = VERR_NOT_SUPPORTED;
    }

    if (rc != 0)
        returnValue = VERR_NOT_SUPPORTED;

    if (pszAddressOutLocal)
        RTMemTmpFree(pszAddressOutLocal);

    if (pszAddressRfcOutLocal)
        RTMemTmpFree(pszAddressRfcOutLocal);

    if (pszIfIdOutLocal)
        RTMemTmpFree(pszIfIdOutLocal);

    return returnValue;

}
Exemple #26
0
/**
 * Worker for VBoxServiceGetFileVersionString.
 *
 * @returns VBox status code.
 * @param   pszFilename         ASCII & ANSI & UTF-8 compliant name.
 */
static int VBoxServiceGetFileVersion(const char *pszFilename,
                                     PDWORD pdwMajor,
                                     PDWORD pdwMinor,
                                     PDWORD pdwBuildNumber,
                                     PDWORD pdwRevisionNumber)
{
    int rc;

    *pdwMajor = *pdwMinor = *pdwBuildNumber = *pdwRevisionNumber = 0;

    /*
     * Get the file version info.
     */
    DWORD dwHandleIgnored;
    DWORD cbVerData = GetFileVersionInfoSizeA(pszFilename, &dwHandleIgnored);
    if (cbVerData)
    {
        LPTSTR pVerData = (LPTSTR)RTMemTmpAllocZ(cbVerData);
        if (pVerData)
        {
            if (GetFileVersionInfoA(pszFilename, dwHandleIgnored, cbVerData, pVerData))
            {
                /*
                 * Try query and parse the FileVersion string our selves first
                 * since this will give us the correct revision number when
                 * it goes beyond the range of an uint16_t / WORD.
                 */
                if (VBoxServiceGetFileVersionOwn(pVerData, pdwMajor, pdwMinor, pdwBuildNumber, pdwRevisionNumber))
                    rc = VINF_SUCCESS;
                else
                {
                    /* Fall back on VS_FIXEDFILEINFO */
                    UINT                 cbFileInfoIgnored = 0;
                    VS_FIXEDFILEINFO    *pFileInfo = NULL;
                    if (VerQueryValue(pVerData, "\\", (LPVOID *)&pFileInfo, &cbFileInfoIgnored))
                    {
                        *pdwMajor          = HIWORD(pFileInfo->dwFileVersionMS);
                        *pdwMinor          = LOWORD(pFileInfo->dwFileVersionMS);
                        *pdwBuildNumber    = HIWORD(pFileInfo->dwFileVersionLS);
                        *pdwRevisionNumber = LOWORD(pFileInfo->dwFileVersionLS);
                        rc = VINF_SUCCESS;
                    }
                    else
                    {
                        rc = RTErrConvertFromWin32(GetLastError());
                        VBoxServiceVerbose(3, "No file version value for file \"%s\" available! (%d / rc=%Rrc)\n",
                                           pszFilename,  GetLastError(), rc);
                    }
                }
            }
            else
            {
                rc = RTErrConvertFromWin32(GetLastError());
                VBoxServiceVerbose(0, "GetFileVersionInfo(%s) -> %u / %Rrc\n", pszFilename, GetLastError(), rc);
            }

            RTMemTmpFree(pVerData);
        }
        else
        {
            VBoxServiceVerbose(0, "Failed to allocate %u byte for file version info for '%s'\n", cbVerData, pszFilename);
            rc = VERR_NO_TMP_MEMORY;
        }
    }
    else
    {
        rc = RTErrConvertFromWin32(GetLastError());
        VBoxServiceVerbose(3, "GetFileVersionInfoSize(%s) -> %u / %Rrc\n", pszFilename, GetLastError(), rc);
    }
    return rc;
}
/**
 * Relocates the RC address space.
 *
 * @param   pUVM        The user mode VM handle.
 * @param   offDelta    The relocation delta.
 */
void dbgfR3AsRelocate(PUVM pUVM, RTGCUINTPTR offDelta)
{
    /*
     * We will relocate the raw-mode context modules by offDelta if they have
     * been injected into the the DBGF_AS_RC map.
     */
    if (   pUVM->dbgf.s.afAsAliasPopuplated[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_RC)]
        && offDelta != 0)
    {
        RTDBGAS hAs = pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_RC)];

        /* Take a snapshot of the modules as we might have overlapping
           addresses between the previous and new mapping. */
        RTDbgAsLockExcl(hAs);
        uint32_t cModules = RTDbgAsModuleCount(hAs);
        if (cModules > 0 && cModules < _4K)
        {
            struct DBGFASRELOCENTRY
            {
                RTDBGMOD    hDbgMod;
                RTRCPTR     uOldAddr;
            } *paEntries = (struct DBGFASRELOCENTRY *)RTMemTmpAllocZ(sizeof(paEntries[0]) * cModules);
            if (paEntries)
            {
                /* Snapshot. */
                for (uint32_t i = 0; i < cModules; i++)
                {
                    paEntries[i].hDbgMod = RTDbgAsModuleByIndex(hAs, i);
                    AssertLogRelMsg(paEntries[i].hDbgMod != NIL_RTDBGMOD, ("iModule=%#x\n", i));

                    RTDBGASMAPINFO  aMappings[1] = { { 0, 0 } };
                    uint32_t        cMappings = 1;
                    int rc = RTDbgAsModuleQueryMapByIndex(hAs, i, &aMappings[0], &cMappings, 0 /*fFlags*/);
                    if (RT_SUCCESS(rc) && cMappings == 1 && aMappings[0].iSeg == NIL_RTDBGSEGIDX)
                        paEntries[i].uOldAddr = (RTRCPTR)aMappings[0].Address;
                    else
                        AssertLogRelMsgFailed(("iModule=%#x rc=%Rrc cMappings=%#x.\n", i, rc, cMappings));
                }

                /* Unlink them. */
                for (uint32_t i = 0; i < cModules; i++)
                {
                    int rc = RTDbgAsModuleUnlink(hAs, paEntries[i].hDbgMod);
                    AssertLogRelMsg(RT_SUCCESS(rc), ("iModule=%#x rc=%Rrc hDbgMod=%p\n", i, rc, paEntries[i].hDbgMod));
                }

                /* Link them at the new locations. */
                for (uint32_t i = 0; i < cModules; i++)
                {
                    RTRCPTR uNewAddr = paEntries[i].uOldAddr + offDelta;
                    int rc = RTDbgAsModuleLink(hAs, paEntries[i].hDbgMod, uNewAddr,
                                               RTDBGASLINK_FLAGS_REPLACE);
                    AssertLogRelMsg(RT_SUCCESS(rc),
                                    ("iModule=%#x rc=%Rrc hDbgMod=%p %RRv -> %RRv\n", i, rc, paEntries[i].hDbgMod,
                                     paEntries[i].uOldAddr, uNewAddr));
                    RTDbgModRelease(paEntries[i].hDbgMod);
                }

                RTMemTmpFree(paEntries);
            }
            else
                AssertLogRelMsgFailed(("No memory for %#x modules.\n", cModules));
        }
        else
            AssertLogRelMsgFailed(("cModules=%#x\n", cModules));
        RTDbgAsUnlockExcl(hAs);
    }
}
Exemple #28
0
void vbglR3GRFree(VMMDevRequestHeader *pReq)
{
    RTMemTmpFree(pReq);
}
Exemple #29
0
RTDECL(int) RTSystemQueryDmiString(RTSYSDMISTR enmString, char *pszBuf, size_t cbBuf)
{
    AssertPtrReturn(pszBuf, VERR_INVALID_POINTER);
    AssertReturn(cbBuf > 0, VERR_INVALID_PARAMETER);
    *pszBuf = '\0';
    AssertReturn(enmString > RTSYSDMISTR_INVALID && enmString < RTSYSDMISTR_END, VERR_INVALID_PARAMETER);

    CFStringRef PropStringRef = NULL;
    switch (enmString)
    {
        case RTSYSDMISTR_PRODUCT_NAME:    PropStringRef = CFSTR(PROP_PRODUCT_NAME);    break;
        case RTSYSDMISTR_PRODUCT_VERSION: PropStringRef = CFSTR(PROP_PRODUCT_VERSION); break;
        case RTSYSDMISTR_PRODUCT_SERIAL:  PropStringRef = CFSTR(PROP_PRODUCT_SERIAL);  break;
        case RTSYSDMISTR_PRODUCT_UUID:    PropStringRef = CFSTR(PROP_PRODUCT_UUID);    break;
        case RTSYSDMISTR_MANUFACTURER:    PropStringRef = CFSTR(PROP_MANUFACTURER);    break;
        default:
            return VERR_NOT_SUPPORTED;
    }

    mach_port_t MasterPort;
    kern_return_t kr = IOMasterPort(MACH_PORT_NULL, &MasterPort);
    if (kr != kIOReturnSuccess)
    {
        if (kr == KERN_NO_ACCESS)
            return VERR_ACCESS_DENIED;
        return RTErrConvertFromDarwinIO(kr);
    }

    CFDictionaryRef ClassToMatch = IOServiceMatching(IOCLASS_PLATFORMEXPERTDEVICE);
    if (!ClassToMatch)
        return VERR_NOT_SUPPORTED;

    /* IOServiceGetMatchingServices will always consume ClassToMatch. */
    io_iterator_t Iterator;
    kr = IOServiceGetMatchingServices(MasterPort, ClassToMatch, &Iterator);
    if (kr != kIOReturnSuccess)
        return RTErrConvertFromDarwinIO(kr);

    int rc = VERR_NOT_SUPPORTED;
    io_service_t ServiceObject;
    while ((ServiceObject = IOIteratorNext(Iterator)))
    {
        if (   enmString == RTSYSDMISTR_PRODUCT_NAME
            || enmString == RTSYSDMISTR_PRODUCT_VERSION
            || enmString == RTSYSDMISTR_MANUFACTURER
           )
        {
            CFDataRef DataRef = (CFDataRef)IORegistryEntryCreateCFProperty(ServiceObject, PropStringRef,
                                                                           kCFAllocatorDefault, kNilOptions);
            if (DataRef)
            {
                size_t         cbData  = CFDataGetLength(DataRef);
                const char    *pchData = (const char *)CFDataGetBytePtr(DataRef);
                rc = RTStrCopyEx(pszBuf, cbBuf, pchData, cbData);
                CFRelease(DataRef);
                break;
            }
        }
        else
        {
            CFStringRef StringRef = (CFStringRef)IORegistryEntryCreateCFProperty(ServiceObject, PropStringRef,
                                                                                 kCFAllocatorDefault, kNilOptions);
            if (StringRef)
            {
                Boolean fRc = CFStringGetCString(StringRef, pszBuf, cbBuf, kCFStringEncodingUTF8);
                if (fRc)
                    rc = VINF_SUCCESS;
                else
                {
                    CFIndex cwc    = CFStringGetLength(StringRef);
                    size_t  cbTmp  = cwc + 1;
                    char   *pszTmp = (char *)RTMemTmpAlloc(cbTmp);
                    int     cTries = 1;
                    while (   pszTmp
                           && (fRc = CFStringGetCString(StringRef, pszTmp, cbTmp, kCFStringEncodingUTF8)) == FALSE
                           && cTries++ < 4)
                    {
                        RTMemTmpFree(pszTmp);
                        cbTmp *= 2;
                        pszTmp = (char *)RTMemTmpAlloc(cbTmp);
                    }
                    if (fRc)
                        rc = RTStrCopy(pszBuf, cbBuf, pszTmp);
                    else if (!pszTmp)
                        rc = VERR_NO_TMP_MEMORY;
                    else
                        rc = VERR_ACCESS_DENIED;
                    RTMemFree(pszTmp);
                }
                CFRelease(StringRef);
                break;
            }
        }
    }

    IOObjectRelease(ServiceObject);
    IOObjectRelease(Iterator);
    return rc;
}
Exemple #30
0
/**
 * Cleans up a GMMR0AllocatePages request.
 * @param   pReq        Pointer to the request (returned by GMMR3AllocatePagesPrepare).
 */
GMMR3DECL(void) GMMR3AllocatePagesCleanup(PGMMALLOCATEPAGESREQ pReq)
{
    RTMemTmpFree(pReq);
}