int main() { RTR3Init(); printf("tstLog: Requires manual inspection of the log output!\n"); RTLogPrintf("%%Rrc %d: %Rrc\n", VERR_INVALID_PARAMETER, VERR_INVALID_PARAMETER); RTLogPrintf("%%Rrs %d: %Rrs\n", VERR_INVALID_PARAMETER, VERR_INVALID_PARAMETER); RTLogPrintf("%%Rrf %d: %Rrf\n", VERR_INVALID_PARAMETER, VERR_INVALID_PARAMETER); RTLogPrintf("%%Rra %d: %Rra\n", VERR_INVALID_PARAMETER, VERR_INVALID_PARAMETER); static uint8_t au8Hex[256]; for (unsigned iHex = 0; iHex < sizeof(au8Hex); iHex++) au8Hex[iHex] = (uint8_t)iHex; RTLogPrintf("%%Rhxs : %Rhxs\n", &au8Hex[0]); RTLogPrintf("%%.32Rhxs: %.32Rhxs\n", &au8Hex[0]); RTLogPrintf("%%Rhxd :\n%Rhxd\n", &au8Hex[0]); RTLogPrintf("%%.64Rhxd:\n%.64Rhxd\n", &au8Hex[0]); RTLogPrintf("%%.*Rhxd:\n%.*Rhxd\n", 64, &au8Hex[0]); RTLogPrintf("%%32.256Rhxd : \n%32.256Rhxd\n", &au8Hex[0]); RTLogPrintf("%%32.*Rhxd : \n%32.*Rhxd\n", 256, &au8Hex[0]); RTLogPrintf("%%7.32Rhxd : \n%7.32Rhxd\n", &au8Hex[0]); RTLogPrintf("%%7.*Rhxd : \n%7.*Rhxd\n", 32, &au8Hex[0]); RTLogPrintf("%%*.*Rhxd : \n%*.*Rhxd\n", 7, 32, &au8Hex[0]); RTLogPrintf("%%RGp: %RGp\n", (RTGCPHYS)0x87654321); RTLogPrintf("%%RGv: %RGv\n", (RTGCPTR)0x87654321); RTLogPrintf("%%RHp: %RHp\n", (RTGCPHYS)0x87654321); RTLogPrintf("%%RHv: %RHv\n", (RTGCPTR)0x87654321); RTLogPrintf("%%RI8 : %RI8\n", (uint8_t)808); RTLogPrintf("%%RI16: %RI16\n", (uint16_t)16016); RTLogPrintf("%%RI32: %RI32\n", _1G); RTLogPrintf("%%RI64: %RI64\n", _1E); RTLogPrintf("%%RU8 : %RU8\n", (uint8_t)808); RTLogPrintf("%%RU16: %RU16\n", (uint16_t)16016); RTLogPrintf("%%RU32: %RU32\n", _2G32); RTLogPrintf("%%RU64: %RU64\n", _2E); RTLogPrintf("%%RX8 : %RX8 %#RX8\n", (uint8_t)808, (uint8_t)808); RTLogPrintf("%%RX16: %RX16 %#RX16\n", (uint16_t)16016, (uint16_t)16016); RTLogPrintf("%%RX32: %RX32 %#RX32\n", _2G32, _2G32); RTLogPrintf("%%RX64: %RX64 %#RX64\n", _2E, _2E); RTLogFlush(NULL); return 0; }
RTDECL(void) RTAssertMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction) { /* * Fill in the globals. */ ASMAtomicUoWritePtr(&g_pszRTAssertExpr, pszExpr); ASMAtomicUoWritePtr(&g_pszRTAssertFile, pszFile); ASMAtomicUoWritePtr(&g_pszRTAssertFunction, pszFunction); ASMAtomicUoWriteU32(&g_u32RTAssertLine, uLine); RTStrPrintf(g_szRTAssertMsg1, sizeof(g_szRTAssertMsg1), "\n!!Assertion Failed!!\n" "Expression: %s\n" "Location : %s(%d) %s\n", pszExpr, pszFile, uLine, pszFunction); /* * If not quiet, make noise. */ if (!RTAssertAreQuiet()) { RTERRVARS SavedErrVars; RTErrVarsSave(&SavedErrVars); #ifdef IN_RING0 # ifdef IN_GUEST_R0 RTLogBackdoorPrintf("\n!!Assertion Failed!!\n" "Expression: %s\n" "Location : %s(%d) %s\n", pszExpr, pszFile, uLine, pszFunction); # endif /** @todo fully integrate this with the logger... play safe a bit for now. */ rtR0AssertNativeMsg1(pszExpr, uLine, pszFile, pszFunction); #else /* !IN_RING0 */ # if !defined(IN_RING3) && !defined(LOG_NO_COM) # if 0 /* Enable this iff you have a COM port and really want this debug info. */ RTLogComPrintf("\n!!Assertion Failed!!\n" "Expression: %s\n" "Location : %s(%d) %s\n", pszExpr, pszFile, uLine, pszFunction); # endif # endif PRTLOGGER pLog = RTLogRelGetDefaultInstance(); if (pLog) { RTLogRelPrintf("\n!!Assertion Failed!!\n" "Expression: %s\n" "Location : %s(%d) %s\n", pszExpr, pszFile, uLine, pszFunction); # ifndef IN_RC /* flushing is done automatically in RC */ RTLogFlush(pLog); # endif } # ifndef LOG_ENABLED if (!pLog) # endif { pLog = RTLogDefaultInstance(); if (pLog) { RTLogPrintf("\n!!Assertion Failed!!\n" "Expression: %s\n" "Location : %s(%d) %s\n", pszExpr, pszFile, uLine, pszFunction); # ifndef IN_RC /* flushing is done automatically in RC */ RTLogFlush(pLog); # endif } } # ifdef IN_RING3 /* print to stderr, helps user and gdb debugging. */ fprintf(stderr, "\n!!Assertion Failed!!\n" "Expression: %s\n" "Location : %s(%d) %s\n", VALID_PTR(pszExpr) ? pszExpr : "<none>", VALID_PTR(pszFile) ? pszFile : "<none>", uLine, VALID_PTR(pszFunction) ? pszFunction : ""); fflush(stderr); # endif #endif /* !IN_RING0 */ RTErrVarsRestore(&SavedErrVars); } }
/** * Internal free. */ RTDECL(void) rtR3MemFree(const char *pszOp, RTMEMTYPE enmType, void *pv, void *pvCaller, RT_SRC_POS_DECL) { /* * Simple case. */ if (!pv) return; /* * Check watch points. */ for (unsigned i = 0; i < RT_ELEMENTS(gapvRTMemFreeWatch); i++) if (gapvRTMemFreeWatch[i] == pv) RTAssertDoPanic(); #ifdef RTALLOC_EFENCE_TRACE /* * Find the block. */ PRTMEMBLOCK pBlock = rtmemBlockRemove(pv); if (pBlock) { if (gfRTMemFreeLog) RTLogPrintf("RTMem %s: pv=%p pvCaller=%p cbUnaligned=%#x\n", pszOp, pv, pvCaller, pBlock->cbUnaligned); # ifdef RTALLOC_EFENCE_NOMAN_FILLER /* * Check whether the no man's land is untouched. */ # ifdef RTALLOC_EFENCE_IN_FRONT void *pvWrong = ASMMemIsAll8((char *)pv + pBlock->cbUnaligned, RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) - pBlock->cbUnaligned, RTALLOC_EFENCE_NOMAN_FILLER); # else /* Alignment must match allocation alignment in rtMemAlloc(). */ void *pvWrong = ASMMemIsAll8((char *)pv + pBlock->cbUnaligned, pBlock->cbAligned - pBlock->cbUnaligned, RTALLOC_EFENCE_NOMAN_FILLER); if (pvWrong) RTAssertDoPanic(); pvWrong = ASMMemIsAll8((void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK), RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) - pBlock->cbAligned, RTALLOC_EFENCE_NOMAN_FILLER); # endif if (pvWrong) RTAssertDoPanic(); # endif # ifdef RTALLOC_EFENCE_FREE_FILL /* * Fill the user part of the block. */ memset(pv, RTALLOC_EFENCE_FREE_FILL, pBlock->cbUnaligned); # endif # if defined(RTALLOC_EFENCE_FREE_DELAYED) && RTALLOC_EFENCE_FREE_DELAYED > 0 /* * We're doing delayed freeing. * That means we'll expand the E-fence to cover the entire block. */ int rc = RTMemProtect(pv, pBlock->cbAligned, RTMEM_PROT_NONE); if (RT_SUCCESS(rc)) { /* * Insert it into the free list and process pending frees. */ rtmemBlockDelayInsert(pBlock); while ((pBlock = rtmemBlockDelayRemove()) != NULL) { pv = pBlock->Core.Key; # ifdef RTALLOC_EFENCE_IN_FRONT void *pvBlock = (char *)pv - RTALLOC_EFENCE_SIZE; # else void *pvBlock = (void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK); # endif size_t cbBlock = RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE; rc = RTMemProtect(pvBlock, cbBlock, RTMEM_PROT_READ | RTMEM_PROT_WRITE); if (RT_SUCCESS(rc)) RTMemPageFree(pvBlock, RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE); else rtmemComplain(pszOp, "RTMemProtect(%p, %#x, RTMEM_PROT_READ | RTMEM_PROT_WRITE) -> %d\n", pvBlock, cbBlock, rc); rtmemBlockFree(pBlock); } } else rtmemComplain(pszOp, "Failed to expand the efence of pv=%p cb=%d, rc=%d.\n", pv, pBlock, rc); # else /* !RTALLOC_EFENCE_FREE_DELAYED */ /* * Turn of the E-fence and free it. */ # ifdef RTALLOC_EFENCE_IN_FRONT void *pvBlock = (char *)pv - RTALLOC_EFENCE_SIZE; void *pvEFence = pvBlock; # else void *pvBlock = (void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK); void *pvEFence = (char *)pv + pBlock->cb; # endif int rc = RTMemProtect(pvEFence, RTALLOC_EFENCE_SIZE, RTMEM_PROT_READ | RTMEM_PROT_WRITE); if (RT_SUCCESS(rc)) RTMemPageFree(pvBlock, RT_ALIGN_Z(pBlock->cbAligned, PAGE_SIZE) + RTALLOC_EFENCE_SIZE); else rtmemComplain(pszOp, "RTMemProtect(%p, %#x, RTMEM_PROT_READ | RTMEM_PROT_WRITE) -> %d\n", pvEFence, RTALLOC_EFENCE_SIZE, rc); rtmemBlockFree(pBlock); # endif /* !RTALLOC_EFENCE_FREE_DELAYED */ } else rtmemComplain(pszOp, "pv=%p not found! Incorrect free!\n", pv); #else /* !RTALLOC_EFENCE_TRACE */ /* * We have no size tracking, so we're not doing any freeing because * we cannot if the E-fence is after the block. * Let's just expand the E-fence to the first page of the user bit * since we know that it's around. */ int rc = RTMemProtect((void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK), PAGE_SIZE, RTMEM_PROT_NONE); if (RT_FAILURE(rc)) rtmemComplain(pszOp, "RTMemProtect(%p, PAGE_SIZE, RTMEM_PROT_NONE) -> %d\n", (void *)((uintptr_t)pv & ~PAGE_OFFSET_MASK), rc); #endif /* !RTALLOC_EFENCE_TRACE */ }
static DECLCALLBACK(int) doit(PVM pVM) { RTPrintf(TESTCASE ": testing...\n"); SetupSelectors(pVM); /* * Loading the module and resolve the entry point. */ int rc = PDMR3LdrLoadRC(pVM, NULL, "tstMicroRC.gc"); if (RT_FAILURE(rc)) { RTPrintf(TESTCASE ": Failed to load tstMicroRC.gc, rc=%Rra\n", rc); return rc; } RTRCPTR RCPtrEntry; rc = PDMR3LdrGetSymbolRC(pVM, "tstMicroRC.gc", "tstMicroRC", &RCPtrEntry); if (RT_FAILURE(rc)) { RTPrintf(TESTCASE ": Failed to resolve the 'tstMicroRC' entry point in tstMicroRC.gc, rc=%Rra\n", rc); return rc; } RTRCPTR RCPtrStart; rc = PDMR3LdrGetSymbolRC(pVM, "tstMicroRC.gc", "tstMicroRCAsmStart", &RCPtrStart); if (RT_FAILURE(rc)) { RTPrintf(TESTCASE ": Failed to resolve the 'tstMicroRCAsmStart' entry point in tstMicroRC.gc, rc=%Rra\n", rc); return rc; } RTRCPTR RCPtrEnd; rc = PDMR3LdrGetSymbolRC(pVM, "tstMicroRC.gc", "tstMicroRCAsmEnd", &RCPtrEnd); if (RT_FAILURE(rc)) { RTPrintf(TESTCASE ": Failed to resolve the 'tstMicroRCAsmEnd' entry point in tstMicroRC.gc, rc=%Rra\n", rc); return rc; } /* * Allocate and initialize the instance data. */ PTSTMICRO pTst; rc = MMHyperAlloc(pVM, RT_ALIGN_Z(sizeof(*pTst), PAGE_SIZE), PAGE_SIZE, MM_TAG_VM, (void **)&pTst); if (RT_FAILURE(rc)) { RTPrintf(TESTCASE ": Failed to resolve allocate instance memory (%d bytes), rc=%Rra\n", sizeof(*pTst), rc); return rc; } pTst->RCPtr = MMHyperR3ToRC(pVM, pTst); pTst->RCPtrStack = MMHyperR3ToRC(pVM, &pTst->au8Stack[sizeof(pTst->au8Stack) - 32]); /* the page must be writable from user mode */ rc = PGMMapModifyPage(pVM, pTst->RCPtr, sizeof(*pTst), X86_PTE_US | X86_PTE_RW, ~(uint64_t)(X86_PTE_US | X86_PTE_RW)); if (RT_FAILURE(rc)) { RTPrintf(TESTCASE ": PGMMapModifyPage -> rc=%Rra\n", rc); return rc; } /* all the code must be executable from R3. */ rc = PGMMapModifyPage(pVM, RCPtrStart, RCPtrEnd - RCPtrStart + PAGE_SIZE, X86_PTE_US, ~(uint64_t)X86_PTE_US); if (RT_FAILURE(rc)) { RTPrintf(TESTCASE ": PGMMapModifyPage -> rc=%Rra\n", rc); return rc; } DBGFR3PagingDumpEx(pVM->pUVM, 0 /*idCpu*/, DBGFPGDMP_FLAGS_CURRENT_CR3 | DBGFPGDMP_FLAGS_CURRENT_MODE | DBGFPGDMP_FLAGS_SHADOW | DBGFPGDMP_FLAGS_HEADER | DBGFPGDMP_FLAGS_PRINT_CR3, 0 /*cr3*/, 0 /*u64FirstAddr*/, UINT64_MAX /*u64LastAddr*/, 99 /*cMaxDepth*/, NULL); #if 0 /* * Disassemble the assembly... */ RTGCPTR GCPtr = RCPtrStart; while (GCPtr < RCPtrEnd) { size_t cb = 0; char sz[256]; int rc = DBGFR3DisasInstrEx(pVM, CPUMGetHyperCS(pVM), GCPtr, 0, sz, sizeof(sz), &cb); if (RT_SUCCESS(rc)) RTLogPrintf("%s\n", sz); else { RTLogPrintf("%RGv rc=%Rrc\n", GCPtr, rc); cb = 1; } GCPtr += cb; } #endif #ifdef VBOX_WITH_RAW_MODE /* * Do the profiling. */ /* execute the instruction profiling tests */ PrintHeaderInstr(); int i; for (i = TSTMICROTEST_OVERHEAD; i < TSTMICROTEST_TRAP_FIRST; i++) { TSTMICROTEST enmTest = (TSTMICROTEST)i; uint64_t cMin = ~0; uint64_t cMax = 0; uint64_t cTotal = 0; unsigned cSamples = 0; rc = VINF_SUCCESS; for (int c = 0; c < 100; c++) { int rc2 = VMMR3CallRC(pVM, RCPtrEntry, 2, pTst->RCPtr, enmTest); if (RT_SUCCESS(rc2)) { uint64_t u64 = pTst->aResults[enmTest].cTotalTicks; if (cMin > u64) cMin = u64; if (cMax < u64) cMax = u64; cTotal += u64; cSamples++; } else if (RT_SUCCESS(rc)) rc = rc2; } uint64_t cAvg = cTotal / (cSamples ? cSamples : 1); pTst->aResults[enmTest].cTotalTicks = cAvg; PrintResultInstr(pTst, enmTest, rc, cMin, cAvg, cMax); /* store the overhead */ if (enmTest == TSTMICROTEST_OVERHEAD) pTst->u64Overhead = cMin; } #endif #ifdef VBOX_WITH_RAW_MODE /* execute the trap/cycle profiling tests. */ RTPrintf("\n"); PrintHeaderTraps(); /* don't disable rdtsc in R1/R2/R3! */ CPUMR3SetCR4Feature(pVM, 0, ~X86_CR4_TSD); for (i = TSTMICROTEST_TRAP_FIRST; i < TSTMICROTEST_MAX; i++) { TSTMICROTEST enmTest = (TSTMICROTEST)i; rc = VMMR3CallRC(pVM, RCPtrEntry, 2, pTst->RCPtr, enmTest); PrintResultTrap(pTst, enmTest, rc); } #endif RTPrintf(TESTCASE ": done!\n"); return VINF_SUCCESS; }
/** * 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_DARWIN) RTLogPrintf("rtCheckCredentials\n"); /* * Resolve user to UID and GID. */ char szBuf[_4K]; struct passwd Pw; struct passwd *pPw; if (getpwnam_r(pszUser, &Pw, szBuf, sizeof(szBuf), &pPw) != 0) return VERR_AUTHENTICATION_FAILURE; if (!pPw) return VERR_AUTHENTICATION_FAILURE; *pUid = pPw->pw_uid; *pGid = pPw->pw_gid; /* * Use PAM for the authentication. * Note! libpam.2.dylib was introduced with 10.6.x (OpenPAM). */ void *hModPam = dlopen("libpam.dylib", RTLD_LAZY | RTLD_GLOBAL); if (hModPam) { int (*pfnPamStart)(const char *, const char *, struct pam_conv *, pam_handle_t **); int (*pfnPamAuthenticate)(pam_handle_t *, int); int (*pfnPamAcctMgmt)(pam_handle_t *, int); int (*pfnPamSetItem)(pam_handle_t *, int, const void *); int (*pfnPamEnd)(pam_handle_t *, int); *(void **)&pfnPamStart = dlsym(hModPam, "pam_start"); *(void **)&pfnPamAuthenticate = dlsym(hModPam, "pam_authenticate"); *(void **)&pfnPamAcctMgmt = dlsym(hModPam, "pam_acct_mgmt"); *(void **)&pfnPamSetItem = dlsym(hModPam, "pam_set_item"); *(void **)&pfnPamEnd = dlsym(hModPam, "pam_end"); ASMCompilerBarrier(); if ( pfnPamStart && pfnPamAuthenticate && pfnPamAcctMgmt && pfnPamSetItem && pfnPamEnd) { #define pam_start pfnPamStart #define pam_authenticate pfnPamAuthenticate #define pam_acct_mgmt pfnPamAcctMgmt #define pam_set_item pfnPamSetItem #define pam_end pfnPamEnd /* Do the PAM stuff. Note! Abusing 'login' here for now... */ pam_handle_t *hPam = NULL; RTPROCPAMARGS PamConvArgs = { pszUser, pszPasswd }; struct pam_conv PamConversation; RT_ZERO(PamConversation); PamConversation.appdata_ptr = &PamConvArgs; PamConversation.conv = rtPamConv; int rc = pam_start("login", pszUser, &PamConversation, &hPam); if (rc == PAM_SUCCESS) { rc = pam_set_item(hPam, PAM_RUSER, pszUser); if (rc == PAM_SUCCESS) rc = pam_authenticate(hPam, 0); if (rc == PAM_SUCCESS) { rc = pam_acct_mgmt(hPam, 0); if ( rc == PAM_SUCCESS || rc == PAM_AUTHINFO_UNAVAIL /*??*/) { pam_end(hPam, PAM_SUCCESS); dlclose(hModPam); return VINF_SUCCESS; } Log(("rtCheckCredentials: pam_acct_mgmt -> %d\n", rc)); } else Log(("rtCheckCredentials: pam_authenticate -> %d\n", rc)); pam_end(hPam, rc); } else Log(("rtCheckCredentials: pam_start -> %d\n", rc)); } else Log(("rtCheckCredentials: failed to resolve symbols: %p %p %p %p %p\n", pfnPamStart, pfnPamAuthenticate, pfnPamAcctMgmt, pfnPamSetItem, pfnPamEnd)); dlclose(hModPam); } else Log(("rtCheckCredentials: Loading libpam.dylib failed\n")); return VERR_AUTHENTICATION_FAILURE; #elif 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 }