- Use MmUserProbeAddress in the system call handler to verify the
parametes we got from user-mode are valid and return
STATUS_ACCESS_VIOLATION if the check fails.
- Handle failure after PsConvertToGuiThread and return
STATUS_INVALID_SYSTEM_SERVICE and/or FALSE and/or -1 on failure.
- Made MCE/XMMI interrupts unexpected on-boot.
- Removed KiTrapUnknown and used KiTrap0F (15) instead, which is the
generic unexpected handler.
Modified: trunk/reactos/include/ndk/asm.h
Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s
_____
Modified: trunk/reactos/include/ndk/asm.h
--- trunk/reactos/include/ndk/asm.h 2006-01-17 22:34:20 UTC (rev
20941)
+++ trunk/reactos/include/ndk/asm.h 2006-01-17 22:41:39 UTC (rev
20942)
@@ -357,10 +357,12 @@
// NTSTATUS and Bugcheck Codes
//
#ifdef __ASM__
+#define STATUS_ACCESS_VIOLATION 0xC0000005
#define STATUS_INVALID_SYSTEM_SERVICE 0xC000001C
#define STATUS_NO_CALLBACK_ACTIVE 0xC0000258
-#define APC_INDEX_MISMATCH 1
+#define APC_INDEX_MISMATCH 0x01
#define IRQL_GT_ZERO_AT_SYSTEM_SERVICE 0x4A
+#define UNEXPECTED_KERNEL_MODE_TRAP 0x7F
#endif
//
_____
Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s
--- trunk/reactos/ntoskrnl/ke/i386/trap.s 2006-01-17 22:34:20 UTC
(rev 20941)
+++ trunk/reactos/ntoskrnl/ke/i386/trap.s 2006-01-17 22:41:39 UTC
(rev 20942)
@@ -16,8 +16,6 @@
* FIXMEs:
* - Figure out why ES/DS gets messed up in VMWare, when doing
KiServiceExit only,
* and only when called from user-mode, and returning to
user-mode.
- * - Use MmProbe when copying arguments to syscall.
- * - Handle failure after PsConvertToGuiThread.
* - Figure out what the DEBUGEIP hack is for and how it can
be moved away.
* - Add DR macro/save and VM macro/save.
* - Implement KiCallbackReturn, KiGetTickCount,
KiRaiseAssertion.
@@ -43,22 +41,22 @@
idt _KiTrap12, INT_32_DPL0 /* INT 0C: Stack Fault Exception
(#SS) */
idt _KiTrap13, INT_32_DPL0 /* INT 0D: General Protection (#GP)
*/
idt _KiTrap14, INT_32_DPL0 /* INT 0E: Page-Fault Exception
(#PF) */
-idt _KiTrap15, INT_32_DPL0 /* INT 0F: RESERVED
*/
+idt _KiTrap15, INT_32_DPL0 /* INT 0F: RESERVED [FIXME: HBIRR
HACK] */
idt _KiTrap16, INT_32_DPL0 /* INT 10: x87 FPU Error (#MF)
*/
idt _KiTrap17, INT_32_DPL0 /* INT 11: Align Check Exception
(#AC) */
-idt _KiTrap18, INT_32_DPL0 /* INT 12: Machine Check Exception
(#MC)*/
-idt _KiTrap19, INT_32_DPL0 /* INT 13: SIMD FPU Exception (#XF)
*/
+idt _KiTrap0F, INT_32_DPL0 /* INT 12: Machine Check Exception
(#MC)*/
+idt _KiTrap0F, INT_32_DPL0 /* INT 13: SIMD FPU Exception (#XF)
*/
.rept 22
-idt _KiTrapUnknown, INT_32_DPL0 /* INT 14-29: UNDEFINED INTERRUPTS
*/
+idt _KiTrap0F, INT_32_DPL0 /* INT 14-29: UNDEFINED INTERRUPTS
*/
.endr
idt _KiGetTickCount, INT_32_DPL3 /* INT 2A: Get Tick Count Handler
*/
idt _KiCallbackReturn, INT_32_DPL3 /* INT 2B: User-Mode Callback
Return */
idt _KiRaiseAssertion, INT_32_DPL3 /* INT 2C: Debug Assertion Handler
*/
idt _KiDebugService, INT_32_DPL3 /* INT 2D: Debug Service Handler
*/
idt _KiSystemService, INT_32_DPL3 /* INT 2E: System Call Service
Handler */
-idt _KiTrapUnknown, INT_32_DPL0 /* INT 2F: RESERVED
*/
+idt _KiTrap0F, INT_32_DPL0 /* INT 2F: RESERVED
*/
.rept 220
-idt _KiTrapUnknown, INT_32_DPL0 /* INT 30-FF: UNDEFINED INTERRUPTS
*/
+idt _KiTrap0F, INT_32_DPL0 /* INT 30-FF: UNDEFINED INTERRUPTS
*/
.endr
/* System call entrypoints:
*/
@@ -271,33 +269,28 @@
/* Allocate space on our stack */
sub esp, ecx
- /*
- * Copy the arguments from the user stack to our stack
- * FIXME: This needs to be probed with MmSystemRangeStart
- */
+ /* Set the size of the arguments and the destination */
shr ecx, 2
mov edi, esp
+
+ /* Make sure we're within the User Probe Address */
+ cmp esi, _MmUserProbeAddress
+ jnb AccessViolation
+
+CopyParams:
+ /* Copy the parameters */
rep movsd
#ifdef DBG
-
- /* Make sure this isn't a user-mode call at elevated IRQL */
- test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
- jz SkipCheck
- call _KeGetCurrentIrql@0
- or al, al
- jnz InvalidIrql
-
/*
* The following lines are for the benefit of GDB. It will see the
return
* address of the "call ebx" below, find the last label before it
and
* thinks that that's the start of the function. It will then check
to see
- * if it starts with a standard function prolog (push ebp, mov
ebp,esp).
+ * if it starts with a standard function prolog (push ebp, mov
ebp,esp1).
* When that standard function prolog is not found, it will stop
the
* stack backtrace. Since we do want to backtrace into usermode,
let's
* make GDB happy and create a standard prolog.
*/
-SkipCheck:
KiSystemService:
push ebp
mov ebp,esp
@@ -307,10 +300,11 @@
/* Do the System Call */
call ebx
+AfterSysCall:
#ifdef DBG
/* Make sure the user-mode call didn't return at elevated IRQL */
test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
- jz SkipCheck2
+ jz SkipCheck
mov esi, eax /* We need to save the syscall's return
val */
call _KeGetCurrentIrql@0
or al, al
@@ -329,7 +323,7 @@
jnz InvalidIndex
#endif
-SkipCheck2:
+SkipCheck:
/* Deallocate the kernel stack frame */
mov esp, ebp
@@ -363,7 +357,7 @@
KiBBTUnexpectedRange:
/* If this isn't a Win32K call, fail */
- cmp ecx, 0x10
+ cmp ecx, SERVICE_TABLE_TEST
jne InvalidCall
/* Set up Win32K Table */
@@ -371,7 +365,10 @@
push ebx
call _PsConvertToGuiThread@0
- /* FIXME: Handle failure */
+ /* Check return code */
+ or eax, eax
+
+ /* Restore registers */
pop eax
pop edx
@@ -379,15 +376,53 @@
mov ebp, esp
mov [esi+KTHREAD_TRAP_FRAME], ebp
- /* Try the Call again */
- jmp SharedCode
+ /* Try the Call again, if we suceeded */
+ jz SharedCode
+ /*
+ * The Shadow Table should have a special byte table which tells us
+ * whether we should return FALSE, -1 or
STATUS_INVALID_SYSTEM_SERVICE.
+ */
+
+ /* Get the table limit and base */
+ lea edx, _KeServiceDescriptorTableShadow + SERVICE_TABLE_TEST
+ mov ecx, [edx+SERVICE_DESCRIPTOR_LIMIT]
+ mov edx, [edx+SERVICE_DESCRIPTOR_BASE]
+
+ /* Get the table address and add our index into the array */
+ lea edx, [edx+ecx*4]
+ and eax, SERVICE_NUMBER_MASK
+ add edx, eax
+
+ /* Find out what we should return */
+ movsx eax, byte ptr [edx]
+ or eax, eax
+
+ /* Return either 0 or -1, we've set it in EAX */
+ jle KeReturnFromSystemCall
+
+ /* Set STATUS_INVALID_SYSTEM_SERVICE */
+ mov eax, STATUS_INVALID_SYSTEM_SERVICE
+ jmp KeReturnFromSystemCall
+
InvalidCall:
/* Invalid System Call */
mov eax, STATUS_INVALID_SYSTEM_SERVICE
jmp KeReturnFromSystemCall
+AccessViolation:
+
+ /* Check if this came from kernel-mode */
+ test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
+
+ /* It's fine, go ahead with it */
+ jz CopyParams
+
+ /* Caller sent invalid parameters, fail here */
+ mov eax, STATUS_ACCESS_VIOLATION
+ jmp AfterSysCall
+
BadStack:
/* Restore ESP0 stack */
@@ -974,57 +1009,34 @@
jne _Kei386EoiHelper@0
jmp _KiV86Complete
-_KiTrap18:
+_KiTrap0F:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG(18)
+ TRAP_PROLOG(15)
+ sti
- /* Call the C exception handler */
- push 18
- push ebp
- call _KiTrapHandler
- add esp, 8
+ /* Raise a fatal exception */
+ mov eax, 15
+ jmp _KiSystemFatalException
- /* Check for v86 recovery */
- cmp eax, 1
+.func KiSystemFatalException
+_KiSystemFatalException:
- /* Return to caller */
- jne _Kei386EoiHelper@0
- jmp _KiV86Complete
-
-_KiTrap19:
- /* Push error code */
- push 0
-
- /* Enter trap */
- TRAP_PROLOG(19)
-
- /* Call the C exception handler */
- push 19
+ /* Push the trap frame */
push ebp
- call _KiTrapHandler
- add esp, 8
- /* Check for v86 recovery */
- cmp eax, 1
-
- /* Return to caller */
- jne _Kei386EoiHelper@0
- jmp _KiV86Complete
-
-_KiTrapUnknown:
- /* Push error code */
+ /* Push empty parameters */
push 0
+ push 0
+ push 0
- /* Enter trap */
- TRAP_PROLOG(255)
+ /* Push trap number and bugcheck code */
+ push eax
+ push UNEXPECTED_KERNEL_MODE_TRAP
+ call _KeBugCheckWithTf@24
+ ret
+.endfunc
- /* Check for v86 recovery */
- cmp eax, 1
- /* Return to caller */
- jne _Kei386EoiHelper@0
- jmp _KiV86Complete
-