Changeset 2938 in kBuild
- Timestamp:
- Sep 19, 2016 4:50:47 PM (8 years ago)
- Location:
- trunk/src/kWorker
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kWorker/Makefile.kmk
r2934 r2938 49 49 kWorker_LDFLAGS.win = \ 50 50 /BASE:0x10000 /DYNAMICBASE:NO /FIXED 51 #kWorker_LDFLAGS.win.x86 = \ 52 # /SAFESEH:NO - doesn't help anyone. 51 53 52 54 -
trunk/src/kWorker/kWorker.c
r2936 r2938 87 87 #define WITH_LOG_FILE 88 88 89 /** @def WITH_HISTORY 90 * Keep history of the last jobs. For debugging. */ 91 #define WITH_HISTORY 92 93 89 94 #ifndef NDEBUG 90 95 # define KW_LOG_ENABLED 91 96 #endif 92 93 97 94 98 /** @def KW_LOG … … 844 848 845 849 850 #ifdef WITH_HISTORY 851 /** The job history. */ 852 static char *g_apszHistory[32]; 853 /** Index of the next history entry. */ 854 static unsigned g_iHistoryNext = 0; 855 #endif 856 857 846 858 /********************************************************************************************************************************* 847 859 * Internal Functions * … … 853 865 static void kwSandboxConsoleWriteA(PKWSANDBOX pSandbox, PKWOUTPUTSTREAMBUF pLineBuf, const char *pchBuffer, KU32 cchToWrite); 854 866 #endif 867 855 868 856 869 … … 4296 4309 || kHlpStrICompAscii(g_aSandboxGetProcReplacements[i].pszModule, &pMod->pszPath[pMod->offFilename]) == 0) 4297 4310 { 4298 if ( pMod->fExe 4299 || !g_aSandboxGetProcReplacements[i].fOnlyExe) 4311 if ( !g_aSandboxGetProcReplacements[i].fOnlyExe 4312 || (KUPTR)_ReturnAddress() - (KUPTR)g_Sandbox.pTool->u.Sandboxed.pExe->hOurMod 4313 < g_Sandbox.pTool->u.Sandboxed.pExe->cbImage) 4300 4314 { 4301 4315 uValue = g_aSandboxGetProcReplacements[i].pfnReplacement; … … 7555 7569 /* 7556 7570 * 7571 * Structured exception handling. 7572 * Structured exception handling. 7573 * Structured exception handling. 7574 * 7575 */ 7576 #if defined(KBUILD_OS_WINDOWS) && defined(KBUILD_ARCH_X86) 7577 7578 # define EH_NONCONTINUABLE KU32_C(0x00000001) 7579 # define EH_UNWINDING KU32_C(0x00000002) 7580 # define EH_EXIT_UNWIND KU32_C(0x00000004) 7581 # define EH_STACK_INVALID KU32_C(0x00000008) 7582 # define EH_NESTED_CALL KU32_C(0x00000010) 7583 7584 typedef KU32 (__cdecl * volatile PFNXCPTHANDLER)(PEXCEPTION_RECORD, struct _EXCEPTION_REGISTRATION_RECORD*, PCONTEXT, 7585 struct _EXCEPTION_REGISTRATION_RECORD * volatile *); 7586 typedef struct _EXCEPTION_REGISTRATION_RECORD 7587 { 7588 struct _EXCEPTION_REGISTRATION_RECORD * volatile pPrevRegRec; 7589 PFNXCPTHANDLER pfnXcptHandler; 7590 }; 7591 7592 7593 /** 7594 * Calls @a pfnHandler. 7595 */ 7596 static KU32 kwSandboxXcptCallHandler(PEXCEPTION_RECORD pXcptRec, struct _EXCEPTION_REGISTRATION_RECORD *pRegRec, 7597 PCONTEXT pXcptCtx, struct _EXCEPTION_REGISTRATION_RECORD * volatile * ppRegRec, 7598 PFNXCPTHANDLER pfnHandler) 7599 { 7600 # if 1 7601 /* This is a more robust version that isn't subject to calling 7602 convension cleanup disputes and such. */ 7603 KU32 uSavedEdi; 7604 KU32 uSavedEsi; 7605 KU32 uSavedEbx; 7606 KU32 rcHandler; 7607 7608 __asm 7609 { 7610 mov [uSavedEdi], edi 7611 mov [uSavedEsi], esi 7612 mov [uSavedEbx], ebx 7613 mov esi, esp 7614 mov edi, esp 7615 mov edi, [pXcptRec] 7616 mov edx, [pRegRec] 7617 mov eax, [pXcptCtx] 7618 mov ebx, [ppRegRec] 7619 mov ecx, [pfnHandler] 7620 sub esp, 16 7621 and esp, 0fffffff0h 7622 mov [esp ], edi 7623 mov [esp + 4], edx 7624 mov [esp + 8], eax 7625 mov [esp + 12], ebx 7626 mov edi, esi 7627 call ecx 7628 mov esp, esi 7629 cmp esp, edi 7630 je stack_ok 7631 int 3 7632 stack_ok: 7633 mov edi, [uSavedEdi] 7634 mov esi, [uSavedEsi] 7635 mov ebx, [uSavedEbx] 7636 mov [rcHandler], eax 7637 } 7638 return rcHandler; 7639 # else 7640 return pfnHandler(pXcptRec, pRegRec, pXctpCtx, ppRegRec); 7641 # endif 7642 } 7643 7644 7645 /** 7646 * Vectored exception handler that emulates x86 chained exception handler. 7647 * 7648 * This is necessary because the RtlIsValidHandler check fails for self loaded 7649 * code and prevents cl.exe from working. (On AMD64 we can register function 7650 * tables, but on X86 cooking your own handling seems to be the only viabke 7651 * alternative.) 7652 * 7653 * @returns EXCEPTION_CONTINUE_SEARCH or EXCEPTION_CONTINUE_EXECUTION. 7654 * @param pXcptPtrs The exception details. 7655 */ 7656 static LONG CALLBACK kwSandboxVecXcptEmulateChained(PEXCEPTION_POINTERS pXcptPtrs) 7657 { 7658 PNT_TIB pTib = (PNT_TIB)NtCurrentTeb(); 7659 KW_LOG(("kwSandboxVecXcptEmulateChained: %#x\n", pXcptPtrs->ExceptionRecord->ExceptionCode)); 7660 if (g_Sandbox.fRunning) 7661 { 7662 HANDLE const hCurProc = GetCurrentProcess(); 7663 PEXCEPTION_RECORD pXcptRec = pXcptPtrs->ExceptionRecord; 7664 PCONTEXT pXcptCtx = pXcptPtrs->ContextRecord; 7665 struct _EXCEPTION_REGISTRATION_RECORD * pRegRec = pTib->ExceptionList; 7666 while (((KUPTR)pRegRec & (sizeof(void *) - 3)) == 0 && pRegRec != NULL) 7667 { 7668 /* Read the exception record in a safe manner. */ 7669 struct _EXCEPTION_REGISTRATION_RECORD RegRec; 7670 DWORD cbActuallyRead = 0; 7671 if ( ReadProcessMemory(hCurProc, pRegRec, &RegRec, sizeof(RegRec), &cbActuallyRead) 7672 && cbActuallyRead == sizeof(RegRec)) 7673 { 7674 struct _EXCEPTION_REGISTRATION_RECORD * volatile pDispRegRec = NULL; 7675 KU32 rcHandler; 7676 KW_LOG(("kwSandboxVecXcptEmulateChained: calling %p, pRegRec=%p, pPrevRegRec=%p\n", 7677 RegRec.pfnXcptHandler, pRegRec, RegRec.pPrevRegRec)); 7678 rcHandler = kwSandboxXcptCallHandler(pXcptRec, pRegRec, pXcptCtx, &pDispRegRec, RegRec.pfnXcptHandler); 7679 KW_LOG(("kwSandboxVecXcptEmulateChained: rcHandler=%#x pDispRegRec=%p\n", rcHandler, pDispRegRec)); 7680 if (rcHandler == ExceptionContinueExecution) 7681 { 7682 kHlpAssert(!(pXcptPtrs->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)); 7683 KW_LOG(("kwSandboxVecXcptEmulateChained: returning EXCEPTION_CONTINUE_EXECUTION!\n")); 7684 return EXCEPTION_CONTINUE_EXECUTION; 7685 } 7686 7687 if (rcHandler == ExceptionContinueSearch) 7688 kHlpAssert(!(pXcptPtrs->ExceptionRecord->ExceptionFlags & 8 /*EXCEPTION_STACK_INVALID*/)); 7689 else if (rcHandler == ExceptionNestedException) 7690 kHlpAssertMsgFailed(("Nested exceptions.\n")); 7691 else 7692 kHlpAssertMsgFailed(("Invalid return %#x (%d).\n", rcHandler, rcHandler)); 7693 } 7694 else 7695 { 7696 KW_LOG(("kwSandboxVecXcptEmulateChained: Bad xcpt chain entry at %p! Stopping search.\n", pRegRec)); 7697 break; 7698 } 7699 7700 /* 7701 * Next. 7702 */ 7703 pRegRec = RegRec.pPrevRegRec; 7704 } 7705 } 7706 return EXCEPTION_CONTINUE_SEARCH; 7707 } 7708 7709 7710 /** NtDll,Kernel32 - RtlUnwind */ 7711 static VOID WINAPI kwSandbox_ntdll_RtlUnwind(struct _EXCEPTION_REGISTRATION_RECORD *pStopXcptRec, PVOID pvTargetIp, 7712 PEXCEPTION_RECORD pXcptRec, PVOID pvReturnValue) 7713 { 7714 PNT_TIB pTib = (PNT_TIB)NtCurrentTeb(); 7715 KW_LOG(("kwSandbox_ntdll_RtlUnwind: pStopXcptRec=%p pvTargetIp=%p pXctpRec=%p pvReturnValue=%p%s\n", 7716 pStopXcptRec, pvTargetIp, pXcptRec, pvReturnValue, g_Sandbox.fRunning ? "" : " [sandbox not running]")); 7717 if (g_Sandbox.fRunning) 7718 { 7719 HANDLE const hCurProc = GetCurrentProcess(); 7720 PCONTEXT pXcptCtx = NULL; 7721 struct _EXCEPTION_REGISTRATION_RECORD * pRegRec = pTib->ExceptionList; 7722 7723 /* 7724 * Update / create an exception record. 7725 */ 7726 if (pXcptRec) 7727 pXcptRec->ExceptionFlags |= EH_UNWINDING; 7728 else 7729 { 7730 pXcptRec = (PEXCEPTION_RECORD)alloca(sizeof(*pXcptRec)); 7731 kHlpMemSet(pXcptRec, 0, sizeof(*pXcptRec)); 7732 pXcptRec->ExceptionCode = STATUS_UNWIND; 7733 pXcptRec->ExceptionFlags = EH_UNWINDING; 7734 } 7735 if (!pStopXcptRec) 7736 pXcptRec->ExceptionFlags |= EH_EXIT_UNWIND; 7737 7738 /* 7739 * Walk the chain till we find pStopXctpRec. 7740 */ 7741 while ( ((KUPTR)pRegRec & (sizeof(void *) - 3)) == 0 7742 && pRegRec != NULL 7743 && pRegRec != pStopXcptRec) 7744 { 7745 /* Read the exception record in a safe manner. */ 7746 struct _EXCEPTION_REGISTRATION_RECORD RegRec; 7747 DWORD cbActuallyRead = 0; 7748 if ( ReadProcessMemory(hCurProc, pRegRec, &RegRec, sizeof(RegRec), &cbActuallyRead) 7749 && cbActuallyRead == sizeof(RegRec)) 7750 { 7751 struct _EXCEPTION_REGISTRATION_RECORD * volatile pDispRegRec = NULL; 7752 KU32 rcHandler; 7753 KW_LOG(("kwSandbox_ntdll_RtlUnwind: calling %p, pRegRec=%p, pPrevRegRec=%p\n", 7754 RegRec.pfnXcptHandler, pRegRec, RegRec.pPrevRegRec)); 7755 rcHandler = kwSandboxXcptCallHandler(pXcptRec, pRegRec, pXcptCtx, &pDispRegRec, RegRec.pfnXcptHandler); 7756 KW_LOG(("kwSandbox_ntdll_RtlUnwind: rcHandler=%#x pDispRegRec=%p\n", rcHandler, pDispRegRec)); 7757 7758 if (rcHandler == ExceptionContinueSearch) 7759 kHlpAssert(!(pXcptRec->ExceptionFlags & 8 /*EXCEPTION_STACK_INVALID*/)); 7760 else if (rcHandler == ExceptionCollidedUnwind) 7761 kHlpAssertMsgFailed(("Implement collided unwind!\n")); 7762 else 7763 kHlpAssertMsgFailed(("Invalid return %#x (%d).\n", rcHandler, rcHandler)); 7764 } 7765 else 7766 { 7767 KW_LOG(("kwSandbox_ntdll_RtlUnwind: Bad xcpt chain entry at %p! Stopping search.\n", pRegRec)); 7768 break; 7769 } 7770 7771 /* 7772 * Pop next. 7773 */ 7774 pTib->ExceptionList = RegRec.pPrevRegRec; 7775 pRegRec = RegRec.pPrevRegRec; 7776 } 7777 return; 7778 } 7779 7780 RtlUnwind(pStopXcptRec, pvTargetIp, pXcptRec, pvReturnValue); 7781 } 7782 7783 #endif /* WINDOWS + X86 */ 7784 7785 7786 /* 7787 * 7557 7788 * Misc function only intercepted while debugging. 7558 7789 * Misc function only intercepted while debugging. … … 7655 7886 { TUPLE("HeapDestroy"), NULL, (KUPTR)kwSandbox_Kernel32_HeapDestroy, K_TRUE /*fOnlyExe*/ }, 7656 7887 7657 { TUPLE("FlsAlloc"), NULL, (KUPTR)kwSandbox_Kernel32_FlsAlloc },7658 { TUPLE("FlsFree"), NULL, (KUPTR)kwSandbox_Kernel32_FlsFree },7659 { TUPLE("TlsAlloc"), NULL, (KUPTR)kwSandbox_Kernel32_TlsAlloc },7660 { TUPLE("TlsFree"), NULL, (KUPTR)kwSandbox_Kernel32_TlsFree },7888 { TUPLE("FlsAlloc"), NULL, (KUPTR)kwSandbox_Kernel32_FlsAlloc, K_TRUE /*fOnlyExe*/ }, 7889 { TUPLE("FlsFree"), NULL, (KUPTR)kwSandbox_Kernel32_FlsFree, K_TRUE /*fOnlyExe*/ }, 7890 { TUPLE("TlsAlloc"), NULL, (KUPTR)kwSandbox_Kernel32_TlsAlloc, K_TRUE /*fOnlyExe*/ }, 7891 { TUPLE("TlsFree"), NULL, (KUPTR)kwSandbox_Kernel32_TlsFree, K_TRUE /*fOnlyExe*/ }, 7661 7892 7662 7893 { TUPLE("SetConsoleCtrlHandler"), NULL, (KUPTR)kwSandbox_Kernel32_SetConsoleCtrlHandler }, 7894 7895 #if defined(KBUILD_OS_WINDOWS) && defined(KBUILD_ARCH_X86) 7896 { TUPLE("RtlUnwind"), NULL, (KUPTR)kwSandbox_ntdll_RtlUnwind }, 7897 #endif 7898 7663 7899 7664 7900 #ifdef WITH_HASH_MD5_CACHE … … 7785 8021 { TUPLE("RtlPcToFileHeader"), NULL, (KUPTR)kwSandbox_ntdll_RtlPcToFileHeader }, 7786 8022 8023 #if defined(KBUILD_OS_WINDOWS) && defined(KBUILD_ARCH_X86) 8024 { TUPLE("RtlUnwind"), NULL, (KUPTR)kwSandbox_ntdll_RtlUnwind }, 8025 #endif 7787 8026 7788 8027 /* … … 7813 8052 * Kernel32.dll and friends. 7814 8053 */ 7815 { TUPLE("FlsAlloc"), NULL, (KUPTR)kwSandbox_Kernel32_FlsAlloc },7816 { TUPLE("FlsFree"), NULL, (KUPTR)kwSandbox_Kernel32_FlsFree },7817 { TUPLE("TlsAlloc"), NULL, (KUPTR)kwSandbox_Kernel32_TlsAlloc },7818 { TUPLE("TlsFree"), NULL, (KUPTR)kwSandbox_Kernel32_TlsFree },8054 { TUPLE("FlsAlloc"), NULL, (KUPTR)kwSandbox_Kernel32_FlsAlloc, K_TRUE /*fOnlyExe*/ }, 8055 { TUPLE("FlsFree"), NULL, (KUPTR)kwSandbox_Kernel32_FlsFree, K_TRUE /*fOnlyExe*/ }, 8056 { TUPLE("TlsAlloc"), NULL, (KUPTR)kwSandbox_Kernel32_TlsAlloc, K_TRUE /*fOnlyExe*/ }, 8057 { TUPLE("TlsFree"), NULL, (KUPTR)kwSandbox_Kernel32_TlsFree, K_TRUE /*fOnlyExe*/ }, 7819 8058 }; 7820 8059 /** Number of entries in g_aSandboxGetProcReplacements. */ … … 7895 8134 #endif 7896 8135 } 7897 7898 7899 #if defined(KBUILD_OS_WINDOWS) && defined(KBUILD_ARCH_X86)7900 typedef struct _EXCEPTION_REGISTRATION_RECORD7901 {7902 struct _EXCEPTION_REGISTRATION_RECORD * volatile PrevStructure;7903 KU32 (__cdecl * volatile ExceptionHandler)(PEXCEPTION_RECORD, struct _EXCEPTION_REGISTRATION_RECORD*, PCONTEXT,7904 struct _EXCEPTION_REGISTRATION_RECORD * volatile *);7905 };7906 7907 /**7908 * Vectored exception handler that emulates x86 chained exception handler.7909 *7910 * This is necessary because the RtlIsValidHandler check fails for self loaded7911 * code and prevents cl.exe from working. (On AMD64 we can register function7912 * tables, but on X86 cooking your own handling seems to be the only viabke7913 * alternative.)7914 *7915 * @returns EXCEPTION_CONTINUE_SEARCH or EXCEPTION_CONTINUE_EXECUTION.7916 * @param pXcptPtrs The exception details.7917 */7918 static LONG CALLBACK kwSandboxVecXcptEmulateChained(PEXCEPTION_POINTERS pXcptPtrs)7919 {7920 PNT_TIB pTib = (PNT_TIB)NtCurrentTeb();7921 KW_LOG(("kwSandboxVecXcptEmulateChained: %#x\n", pXcptPtrs->ExceptionRecord->ExceptionCode));7922 if (g_Sandbox.fRunning)7923 {7924 PEXCEPTION_RECORD pXcptRec = pXcptPtrs->ExceptionRecord;7925 PCONTEXT pXcptCtx = pXcptPtrs->ContextRecord;7926 struct _EXCEPTION_REGISTRATION_RECORD * volatile *ppRegRec = &pTib->ExceptionList;7927 struct _EXCEPTION_REGISTRATION_RECORD * pRegRec = *ppRegRec;7928 while (((KUPTR)pRegRec & (sizeof(void *) - 3)) == 0 && pRegRec != NULL)7929 {7930 #if 17931 /* This is a more robust version that isn't subject to calling7932 convension cleanup disputes and such. */7933 KU32 uSavedEdi;7934 KU32 uSavedEsi;7935 KU32 uSavedEbx;7936 KU32 rcHandler;7937 __asm7938 {7939 mov [uSavedEdi], edi7940 mov [uSavedEsi], esi7941 mov [uSavedEbx], ebx7942 mov esi, esp7943 mov edi, esp7944 mov ecx, [pXcptRec]7945 mov edx, [pRegRec]7946 mov eax, [pXcptCtx]7947 mov ebx, [ppRegRec]7948 sub esp, 167949 and esp, 0fffffff0h7950 mov [esp ], ecx7951 mov [esp + 4], edx7952 mov [esp + 8], eax7953 mov [esp + 12], ebx7954 call dword ptr [edx + 4]7955 mov esp, esi7956 cmp esp, edi7957 je stack_ok7958 int 37959 stack_ok:7960 mov edi, [uSavedEdi]7961 mov esi, [uSavedEsi]7962 mov ebx, [uSavedEbx]7963 mov [rcHandler], eax7964 }7965 #else7966 KU32 rcHandler = pRegRec->ExceptionHandler(pXcptPtrs->ExceptionRecord, pRegRec, pXcptPtrs->ContextRecord, ppRegRec);7967 #endif7968 if (rcHandler == ExceptionContinueExecution)7969 {7970 kHlpAssert(!(pXcptPtrs->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE));7971 return EXCEPTION_CONTINUE_EXECUTION;7972 }7973 if (rcHandler == ExceptionContinueSearch)7974 kHlpAssert(!(pXcptPtrs->ExceptionRecord->ExceptionFlags & 8 /*EXCEPTION_STACK_INVALID*/));7975 else if (rcHandler == ExceptionNestedException)7976 kHlpAssertMsgFailed(("Nested exceptions.\n"));7977 else7978 kHlpAssertMsgFailed(("Invalid return %#x (%d).\n", rcHandler, rcHandler));7979 7980 /*7981 * Next.7982 */7983 ppRegRec = &pRegRec->PrevStructure;7984 pRegRec = pRegRec->PrevStructure;7985 }7986 }7987 return EXCEPTION_CONTINUE_SEARCH;7988 }7989 #endif /* WINDOWS + X86 */7990 8136 7991 8137 … … 8198 8344 return kwErrPrintfRc(KERR_NO_MEMORY, "Error setting up environment variables: kwSandboxGrowEnv failed\n"); 8199 8345 8346 8200 8347 /* 8201 8348 * Invalidate the volatile parts of cache (kBuild output directory, … … 8203 8350 */ 8204 8351 kFsCacheInvalidateCustomBoth(g_pFsCache); 8352 8353 #ifdef WITH_HISTORY 8354 /* 8355 * Record command line in debug history. 8356 */ 8357 kHlpFree(g_apszHistory[g_iHistoryNext]); 8358 g_apszHistory[g_iHistoryNext] = kHlpStrDup(pSandbox->pszCmdLine); 8359 g_iHistoryNext = (g_iHistoryNext + 1) % K_ELEMENTS(g_apszHistory); 8360 #endif 8361 8205 8362 return 0; 8206 8363 }
Note:
See TracChangeset
for help on using the changeset viewer.