diff options
Diffstat (limited to 'src/VBox/Runtime')
-rw-r--r-- | src/VBox/Runtime/common/efi/efisignaturedb.cpp | 54 | ||||
-rw-r--r-- | src/VBox/Runtime/common/vfs/vfsmemory.cpp | 31 | ||||
-rw-r--r-- | src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c | 14 | ||||
-rw-r--r-- | src/VBox/Runtime/r3/win/nocrt-startup-common-win.cpp | 19 | ||||
-rw-r--r-- | src/VBox/Runtime/r3/win/nocrt-startup-exe-win.cpp | 4 |
5 files changed, 107 insertions, 15 deletions
diff --git a/src/VBox/Runtime/common/efi/efisignaturedb.cpp b/src/VBox/Runtime/common/efi/efisignaturedb.cpp index b75445f0..9cfcbd24 100644 --- a/src/VBox/Runtime/common/efi/efisignaturedb.cpp +++ b/src/VBox/Runtime/common/efi/efisignaturedb.cpp @@ -47,6 +47,7 @@ #include <iprt/list.h> #include <iprt/mem.h> #include <iprt/sg.h> +#include <iprt/uuid.h> #include <iprt/formats/efi-signature.h> @@ -157,7 +158,7 @@ static PCRTEFISIGDBDESC rtEfiSigDbGetDescByGuid(PCEFI_GUID pGuid) /** - * Validates the given signature lsit header. + * Validates the given signature list header. * * @returns Flag whether the list header is considered valid. * @param pLstHdr The list header to validate. @@ -265,7 +266,44 @@ static int rtEfiSigDbLoadSigList(PRTEFISIGDBINT pThis, RTVFSFILE hVfsFileIn, uin /** - * Variant for written a list of signatures where each signature gets its own signature list header + * De-duplicate a signature database. + * + * @returns IPRT status code. + * @param pThis The signature database instance. + */ +static int rtEfiSigDbDeduplicate(PRTEFISIGDBINT pThis) +{ + /** @todo This currently deduplicates list nodes as a whole, not looking into signature lists. + * Good enough for the X.509 certificates which matter most to eliminate multiple enrollments. */ + for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aLstSigTypes); i++) + { + PRTEFISIGNATURE pIt, pItNext; + RTListForEachSafe(&pThis->aLstSigTypes[i], pIt, pItNext, RTEFISIGNATURE, NdLst) + { + PRTEFISIGNATURE pIt2; + RTListForEach(&pThis->aLstSigTypes[i], pIt2, RTEFISIGNATURE, NdLst) + { + /* Compare up to element before pIt. */ + if (pIt == pIt2) + break; + if ( pIt->cbSignature == pIt2->cbSignature + && !RTUuidCompare(&pIt->UuidOwner, &pIt2->UuidOwner) + && !memcmp(&pIt->abSignature[0], &pIt2->abSignature[0], pIt->cbSignature)) + { + RTListNodeRemove(&pIt->NdLst); + RTMemFree(pIt); + break; + } + } + } + } + + return VINF_SUCCESS; +} + + +/** + * Variant for writing a list of signatures where each signature gets its own signature list header * (for types where each signature can differ in size like X.509). * * @returns IPRT status code. @@ -455,6 +493,10 @@ RTDECL(int) RTEfiSigDbAddFromExistingDb(RTEFISIGDB hEfiSigDb, RTVFSFILE hVfsFile && cbFile); } + int rc2 = rtEfiSigDbDeduplicate(pThis); + if (RT_SUCCESS(rc)) + rc = rc2; + return rc; } @@ -491,6 +533,10 @@ RTDECL(int) RTEfiSigDbAddSignatureFromFile(RTEFISIGDB hEfiSigDb, RTEFISIGTYPE en rc = VERR_INVALID_PARAMETER; } + int rc2 = rtEfiSigDbDeduplicate(pThis); + if (RT_SUCCESS(rc)) + rc = rc2; + return rc; } @@ -522,6 +568,10 @@ RTDECL(int) RTEfiSigDbAddSignatureFromBuf(RTEFISIGDB hEfiSigDb, RTEFISIGTYPE enm else rc = VERR_INVALID_PARAMETER; + int rc2 = rtEfiSigDbDeduplicate(pThis); + if (RT_SUCCESS(rc)) + rc = rc2; + return rc; } diff --git a/src/VBox/Runtime/common/vfs/vfsmemory.cpp b/src/VBox/Runtime/common/vfs/vfsmemory.cpp index a044f3d8..0d4f687d 100644 --- a/src/VBox/Runtime/common/vfs/vfsmemory.cpp +++ b/src/VBox/Runtime/common/vfs/vfsmemory.cpp @@ -704,10 +704,35 @@ static DECLCALLBACK(int) rtVfsMemFile_SetSize(void *pvThis, uint64_t cbFile, uin AssertReturn(RTVFSFILE_SIZE_F_IS_VALID(fFlags), VERR_INVALID_PARAMETER); PRTVFSMEMFILE pThis = (PRTVFSMEMFILE)pvThis; - if ( (fFlags & RTVFSFILE_SIZE_F_ACTION_MASK) == RTVFSFILE_SIZE_F_NORMAL - && (RTFOFF)cbFile >= pThis->Base.ObjInfo.cbObject) + if ((fFlags & RTVFSFILE_SIZE_F_ACTION_MASK) == RTVFSFILE_SIZE_F_NORMAL) { - /* Growing is just a matter of increasing the size of the object. */ + if ((RTFOFF)cbFile < pThis->Base.ObjInfo.cbObject) + { + /* Remove any extent beyond the file size. */ + bool fHit; + PRTVFSMEMEXTENT pExtent = rtVfsMemFile_LocateExtent(pThis, cbFile, &fHit); + if ( fHit + && cbFile < (pExtent->off + pExtent->cb)) + { + /* Clear the data in this extent. */ + uint64_t cbRemaining = cbFile - pExtent->off; + memset(&pExtent->abData[cbRemaining], 0, pExtent->cb - cbRemaining); + pExtent = RTListGetNext(&pThis->ExtentHead, pExtent, RTVFSMEMEXTENT, Entry); + } + + while (pExtent) + { + PRTVFSMEMEXTENT pFree = pExtent; + pExtent = RTListGetNext(&pThis->ExtentHead, pExtent, RTVFSMEMEXTENT, Entry); + + RTListNodeRemove(&pFree->Entry); + RTMemFree(pFree); + } + + pThis->pCurExt = NULL; + } + /* else: Growing is just a matter of increasing the size of the object. */ + pThis->Base.ObjInfo.cbObject = cbFile; return VINF_SUCCESS; } diff --git a/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c index 70c5e3dc..77459ab2 100644 --- a/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c +++ b/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c @@ -216,7 +216,7 @@ static pgprot_t rtR0MemObjLinuxConvertProt(unsigned fProt, bool fKernel) #if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64) if (fKernel) { -# if RTLNX_VER_MIN(6,6,0) +# if RTLNX_VER_MIN(6,6,0) || RTLNX_SUSE_MAJ_PREREQ(15, 6) /* In kernel 6.6 mk_pte() macro was fortified with additional * check which does not allow to use our custom mask anymore * (see kernel commit ae1f05a617dcbc0a732fbeba0893786cd009536c). @@ -1367,7 +1367,7 @@ DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3P fWrite, /* force write access. */ # endif &pMemLnx->apPages[0] /* Page array. */ -# if GET_USER_PAGES_API < KERNEL_VERSION(6, 5, 0) +# if GET_USER_PAGES_API < KERNEL_VERSION(6, 5, 0) && !RTLNX_SUSE_MAJ_PREREQ(15, 6) , papVMAs /* vmas */ # endif ); @@ -1413,10 +1413,8 @@ DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3P fWrite, /* Write to memory. */ fWrite, /* force write access. */ # endif - &pMemLnx->apPages[0] /* Page array. */ -# if GET_USER_PAGES_API < KERNEL_VERSION(6, 5, 0) - , papVMAs /* vmas */ -# endif + &pMemLnx->apPages[0], /* Page array. */ + papVMAs /* vmas */ ); #endif /* GET_USER_PAGES_API < KERNEL_VERSION(4, 6, 0) */ if (rc == cPages) @@ -1440,7 +1438,7 @@ DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3P while (rc-- > 0) { flush_dcache_page(pMemLnx->apPages[rc]); -# if GET_USER_PAGES_API < KERNEL_VERSION(6, 5, 0) +# if GET_USER_PAGES_API < KERNEL_VERSION(6, 5, 0) && !RTLNX_SUSE_MAJ_PREREQ(15, 6) && !RTLNX_RHEL_RANGE(9,5, 9,99) # if RTLNX_VER_MIN(6,3,0) vm_flags_set(papVMAs[rc], VM_DONTCOPY | VM_LOCKED); # else @@ -1923,7 +1921,7 @@ DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ p /* Thes flags help making 100% sure some bad stuff wont happen (swap, core, ++). * See remap_pfn_range() in mm/memory.c */ -#if RTLNX_VER_MIN(6,3,0) +#if RTLNX_VER_MIN(6,3,0) || RTLNX_RHEL_RANGE(9,5, 9,99) vm_flags_set(vma, VM_DONTEXPAND | VM_DONTDUMP); #elif RTLNX_VER_MIN(3,7,0) vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; diff --git a/src/VBox/Runtime/r3/win/nocrt-startup-common-win.cpp b/src/VBox/Runtime/r3/win/nocrt-startup-common-win.cpp index 598339db..0fdcafbf 100644 --- a/src/VBox/Runtime/r3/win/nocrt-startup-common-win.cpp +++ b/src/VBox/Runtime/r3/win/nocrt-startup-common-win.cpp @@ -147,18 +147,33 @@ void rtVccWinInitBssOnNt3(void *pvImageBase) memset(pbToZero, 0, cbToZero); else { +# if 1 /* This dynamic stupidity is because of stupid AV heuristics. */ + static decltype(NtProtectVirtualMemory) *s_pfnNtProtectVirtualMemory = NULL; + if (!s_pfnNtProtectVirtualMemory) + s_pfnNtProtectVirtualMemory + = (decltype(NtProtectVirtualMemory) *)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), + "NtProtectVirtualMemory"); + if (!s_pfnNtProtectVirtualMemory) + { + RT_BREAKPOINT(); + continue; + } +# else +# define s_pfnNtProtectVirtualMemory NtProtectVirtualMemory +# endif + /* The section is not writable, so temporarily make it writable. */ PVOID pvAligned = pbToZero - ((uintptr_t)pbToZero & PAGE_OFFSET_MASK); ULONG cbAligned = RT_ALIGN_32(cbToZero + ((uintptr_t)pbToZero & PAGE_OFFSET_MASK), PAGE_SIZE); ULONG fNewProt = paSHdrs[i].Characteristics & IMAGE_SCN_MEM_EXECUTE ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE; ULONG fOldProt = fNewProt; - NTSTATUS rcNt = NtProtectVirtualMemory(NtCurrentProcess(), &pvAligned, &cbAligned, fNewProt, &fOldProt); + NTSTATUS rcNt = s_pfnNtProtectVirtualMemory(NtCurrentProcess(), &pvAligned, &cbAligned, fNewProt, &fOldProt); if (NT_SUCCESS(rcNt)) { memset(pbToZero, 0, cbToZero); - rcNt = NtProtectVirtualMemory(NtCurrentProcess(), &pvAligned, &cbAligned, fOldProt, &fNewProt); + rcNt = s_pfnNtProtectVirtualMemory(NtCurrentProcess(), &pvAligned, &cbAligned, fOldProt, &fNewProt); } else RT_BREAKPOINT(); diff --git a/src/VBox/Runtime/r3/win/nocrt-startup-exe-win.cpp b/src/VBox/Runtime/r3/win/nocrt-startup-exe-win.cpp index 543ea05c..110eae30 100644 --- a/src/VBox/Runtime/r3/win/nocrt-startup-exe-win.cpp +++ b/src/VBox/Runtime/r3/win/nocrt-startup-exe-win.cpp @@ -81,7 +81,11 @@ static int rtTerminateProcess(int32_t rcExit, bool fDoAtExit) * Terminate. */ for (;;) +#if 1 /* Using NtTerminateProcess triggers heuristics in some annoying AV scanner. */ + TerminateProcess(NtCurrentProcess(), rcExit); +#else NtTerminateProcess(NtCurrentProcess(), rcExit); +#endif } |