summaryrefslogtreecommitdiffstats
path: root/src/VBox/Runtime
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Runtime')
-rw-r--r--src/VBox/Runtime/common/efi/efisignaturedb.cpp54
-rw-r--r--src/VBox/Runtime/common/vfs/vfsmemory.cpp31
-rw-r--r--src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c14
-rw-r--r--src/VBox/Runtime/r3/win/nocrt-startup-common-win.cpp19
-rw-r--r--src/VBox/Runtime/r3/win/nocrt-startup-exe-win.cpp4
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
}