aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlistair Strachan <alistair.strachan@imgtec.com>2012-06-14 11:15:15 +0100
committerAndroid Partner Code Review <android-gerrit-partner@google.com>2012-06-14 21:42:49 -0700
commitd00c00ef81aba03db7d7ebcdbc0ca7c11de5d2ec (patch)
tree0121157401454281ad8441c2a592ff900c4af2c5
parentcc92b070b828b739cb5653407f8d22ca04762de2 (diff)
downloadkernel_samsung_crespo-d00c00ef81aba03db7d7ebcdbc0ca7c11de5d2ec.zip
kernel_samsung_crespo-d00c00ef81aba03db7d7ebcdbc0ca7c11de5d2ec.tar.gz
kernel_samsung_crespo-d00c00ef81aba03db7d7ebcdbc0ca7c11de5d2ec.tar.bz2
gpu: pvr: Harden MMU code's use-after-free checks.
Add signature words to MMU_CONTEXT and MMU_PT_INFO. These words are initialized at alloc time and zeroed at free time. They are checked any time a page table is validated before being freed. Change-Id: I74aa57c1e8b48e89bfbb1f4f8a4120c54859122f
-rw-r--r--drivers/gpu/pvr/sgx/mmu.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/drivers/gpu/pvr/sgx/mmu.c b/drivers/gpu/pvr/sgx/mmu.c
index 75dc436..0847312 100644
--- a/drivers/gpu/pvr/sgx/mmu.c
+++ b/drivers/gpu/pvr/sgx/mmu.c
@@ -43,6 +43,9 @@ extern IMG_UINT32 ui32BridgeLockPID;
#define UINT32_MAX_VALUE 0xFFFFFFFFUL
+#define PT_INFO_LIST_SIGNATURE 0xDEADBE01
+#define MMU_CONTEXT_SIGNATURE 0xDEADBE02
+
#define SGX_MAX_PD_ENTRIES (1<<(SGX_FEATURE_ADDRESS_SPACE_SIZE - SGX_MMU_PT_SHIFT - SGX_MMU_PAGE_SHIFT))
#if defined(FIX_HW_BRN_31620)
@@ -79,17 +82,21 @@ extern IMG_UINT32 ui32BridgeLockPID;
typedef struct _MMU_PT_INFO_
{
-
+ IMG_UINT32 ui32Signature1;
+
IMG_VOID *hPTPageOSMemHandle;
IMG_CPU_VIRTADDR PTPageCpuVAddr;
IMG_UINT32 ui32ValidPTECount;
+
+ IMG_UINT32 ui32Signature2;
} MMU_PT_INFO;
struct _MMU_CONTEXT_
{
-
+ IMG_UINT32 ui32Signature1;
+
PVRSRV_DEVICE_NODE *psDeviceNode;
@@ -116,6 +123,8 @@ struct _MMU_CONTEXT_
MMU_PT_INFO *apsPTInfoListSave[SGX_MAX_PD_ENTRIES];
#endif
struct _MMU_CONTEXT_ *psNext;
+
+ IMG_UINT32 ui32Signature2;
};
struct _MMU_HEAP_
@@ -751,12 +760,20 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOS
ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
{
- if(ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount > 0)
+ PVR_ASSERT(pMMUHeap->psMMUContext->ui32Signature1 == MMU_CONTEXT_SIGNATURE);
+ PVR_ASSERT(pMMUHeap->psMMUContext->ui32Signature2 == MMU_CONTEXT_SIGNATURE);
+
+ if(ppsPTInfoList[ui32PTIndex])
{
- DumpPT(ppsPTInfoList[ui32PTIndex]);
+ if(ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount > 0)
+ {
+ DumpPT(ppsPTInfoList[ui32PTIndex]);
+ }
+
+ PVR_ASSERT(ppsPTInfoList[ui32PTIndex]->ui32Signature1 == PT_INFO_LIST_SIGNATURE);
+ PVR_ASSERT(ppsPTInfoList[ui32PTIndex]->ui32Signature2 == PT_INFO_LIST_SIGNATURE);
+ PVR_ASSERT(ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount == 0);
}
-
- PVR_ASSERT(ppsPTInfoList[ui32PTIndex] == IMG_NULL || ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount == 0);
}
#if defined(PDUMP)
@@ -891,7 +908,8 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOS
if(bOSFreePT)
{
-
+ ppsPTInfoList[ui32PTIndex]->ui32Signature1 = 0;
+ ppsPTInfoList[ui32PTIndex]->ui32Signature2 = 0;
OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
sizeof(MMU_PT_INFO),
ppsPTInfoList[ui32PTIndex],
@@ -1121,6 +1139,8 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT
return IMG_FALSE;
}
OSMemSet (ppsPTInfoList[i], 0, sizeof(MMU_PT_INFO));
+ ppsPTInfoList[i]->ui32Signature1 = PT_INFO_LIST_SIGNATURE;
+ ppsPTInfoList[i]->ui32Signature2 = PT_INFO_LIST_SIGNATURE;
#if defined(FIX_HW_BRN_31620)
}
#endif
@@ -1418,7 +1438,8 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I
return PVRSRV_ERROR_OUT_OF_MEMORY;
}
OSMemSet (psMMUContext, 0, sizeof(MMU_CONTEXT));
-
+ psMMUContext->ui32Signature1 = MMU_CONTEXT_SIGNATURE;
+ psMMUContext->ui32Signature2 = MMU_CONTEXT_SIGNATURE;
psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
psMMUContext->psDevInfo = psDevInfo;
@@ -2204,7 +2225,8 @@ MMU_Finalise (MMU_CONTEXT *psMMUContext)
ppsMMUContext = &((*ppsMMUContext)->psNext);
}
-
+ psMMUContext->ui32Signature1 = 0;
+ psMMUContext->ui32Signature2 = 0;
OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_CONTEXT), psMMUContext, IMG_NULL);
}