From d76f2f540b144a4363a2f24c1a5b049b6d827c90 Mon Sep 17 00:00:00 2001
From: John Hodge <tpg@mutabah.net>
Date: Sun, 15 Jan 2012 19:08:14 +0800
Subject: [PATCH] Modules/UHCI - Fixed edge case NULL dereference

- Also changed backtrace code to practically ignore eip (for bad jumps)
---
 Kernel/arch/x86/errors.c |  6 ++++--
 Modules/USB/UHCI/uhci.c  | 13 +++++++++++--
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/Kernel/arch/x86/errors.c b/Kernel/arch/x86/errors.c
index c1c3ae67..1139fe40 100644
--- a/Kernel/arch/x86/errors.c
+++ b/Kernel/arch/x86/errors.c
@@ -207,7 +207,8 @@ void Error_Backtrace(Uint eip, Uint ebp)
 	//	LogF("Backtrace: User - 0x%x\n", eip);
 	//	return;
 	//}
-	
+
+	#if 0	
 	if(eip > 0xE0000000)
 	{
 		LogF("Backtrace: Data Area - 0x%x\n", eip);
@@ -219,7 +220,8 @@ void Error_Backtrace(Uint eip, Uint ebp)
 		LogF("Backtrace: Kernel Module - 0x%x\n", eip);
 		return;
 	}
-	
+	#endif	
+
 	//str = Debug_GetSymbol(eip, &delta);
 //	if(str == NULL)
 		LogF("Backtrace: 0x%x", eip);
diff --git a/Modules/USB/UHCI/uhci.c b/Modules/USB/UHCI/uhci.c
index 9ef8b0bc..7b40b143 100644
--- a/Modules/USB/UHCI/uhci.c
+++ b/Modules/USB/UHCI/uhci.c
@@ -151,8 +151,16 @@ tUHCI_TD *UHCI_int_GetTDFromPhys(tPAddr PAddr)
 {
 	// TODO: Fix this to work with a non-contiguous pool
 	static tPAddr	td_pool_base;
+	const int pool_size = NUM_TDs;
+	 int	offset;
 	if(!td_pool_base)	td_pool_base = MM_GetPhysAddr( (tVAddr)gaUHCI_TDPool );
-	return gaUHCI_TDPool + (PAddr - td_pool_base) / sizeof(gaUHCI_TDPool[0]);
+	offset = (PAddr - td_pool_base) / sizeof(gaUHCI_TDPool[0]);
+	if( offset < 0 || offset >= pool_size )
+	{
+		Log_Error("UHCI", "TD PAddr %P not from pool", PAddr);
+		return NULL;
+	}
+	return gaUHCI_TDPool + offset;
 }
 
 void UHCI_int_AppendTD(tUHCI_Controller *Cont, tUHCI_TD *TD)
@@ -375,7 +383,7 @@ void UHCI_InterruptHandler(int IRQ, void *Ptr)
 		{
 			link = Host->FrameList[frame];
 			Host->FrameList[frame] = 1;
-			while( !(link & 1) )
+			while( link && !(link & 1) )
 			{
 				tUHCI_TD *td = UHCI_int_GetTDFromPhys(link);
 				 int	byte_count = (td->Control&0x7FF)+1;
@@ -385,6 +393,7 @@ void UHCI_InterruptHandler(int IRQ, void *Ptr)
 				if(td->_info.bCopyData)
 				{
 					void *ptr = (void*)MM_MapTemp(td->BufferPointer);
+					Log_Debug("UHCI", "td->_info.DataPtr = %p", td->_info.DataPtr);
 					memcpy(td->_info.DataPtr, ptr, byte_count);
 					MM_FreeTemp((tVAddr)ptr);
 				}
-- 
GitLab