mirror of
https://github.com/reactos/reactos.git
synced 2024-10-06 01:13:38 +00:00
- 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. svn path=/trunk/; revision=20942
This commit is contained in:
parent
419e7bb9d5
commit
12d35a7b84
|
@ -357,10 +357,12 @@ Author:
|
||||||
// NTSTATUS and Bugcheck Codes
|
// NTSTATUS and Bugcheck Codes
|
||||||
//
|
//
|
||||||
#ifdef __ASM__
|
#ifdef __ASM__
|
||||||
|
#define STATUS_ACCESS_VIOLATION 0xC0000005
|
||||||
#define STATUS_INVALID_SYSTEM_SERVICE 0xC000001C
|
#define STATUS_INVALID_SYSTEM_SERVICE 0xC000001C
|
||||||
#define STATUS_NO_CALLBACK_ACTIVE 0xC0000258
|
#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 IRQL_GT_ZERO_AT_SYSTEM_SERVICE 0x4A
|
||||||
|
#define UNEXPECTED_KERNEL_MODE_TRAP 0x7F
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
* FIXMEs:
|
* FIXMEs:
|
||||||
* - Figure out why ES/DS gets messed up in VMWare, when doing KiServiceExit only,
|
* - 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.
|
* 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.
|
* - Figure out what the DEBUGEIP hack is for and how it can be moved away.
|
||||||
* - Add DR macro/save and VM macro/save.
|
* - Add DR macro/save and VM macro/save.
|
||||||
* - Implement KiCallbackReturn, KiGetTickCount, KiRaiseAssertion.
|
* - Implement KiCallbackReturn, KiGetTickCount, KiRaiseAssertion.
|
||||||
|
@ -43,22 +41,22 @@ idt _KiTrap11, INT_32_DPL0 /* INT 0B: Segment Not Present (#NP) */
|
||||||
idt _KiTrap12, INT_32_DPL0 /* INT 0C: Stack Fault Exception (#SS) */
|
idt _KiTrap12, INT_32_DPL0 /* INT 0C: Stack Fault Exception (#SS) */
|
||||||
idt _KiTrap13, INT_32_DPL0 /* INT 0D: General Protection (#GP) */
|
idt _KiTrap13, INT_32_DPL0 /* INT 0D: General Protection (#GP) */
|
||||||
idt _KiTrap14, INT_32_DPL0 /* INT 0E: Page-Fault Exception (#PF) */
|
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 _KiTrap16, INT_32_DPL0 /* INT 10: x87 FPU Error (#MF) */
|
||||||
idt _KiTrap17, INT_32_DPL0 /* INT 11: Align Check Exception (#AC) */
|
idt _KiTrap17, INT_32_DPL0 /* INT 11: Align Check Exception (#AC) */
|
||||||
idt _KiTrap18, INT_32_DPL0 /* INT 12: Machine Check Exception (#MC)*/
|
idt _KiTrap0F, 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 13: SIMD FPU Exception (#XF) */
|
||||||
.rept 22
|
.rept 22
|
||||||
idt _KiTrapUnknown, INT_32_DPL0 /* INT 14-29: UNDEFINED INTERRUPTS */
|
idt _KiTrap0F, INT_32_DPL0 /* INT 14-29: UNDEFINED INTERRUPTS */
|
||||||
.endr
|
.endr
|
||||||
idt _KiGetTickCount, INT_32_DPL3 /* INT 2A: Get Tick Count Handler */
|
idt _KiGetTickCount, INT_32_DPL3 /* INT 2A: Get Tick Count Handler */
|
||||||
idt _KiCallbackReturn, INT_32_DPL3 /* INT 2B: User-Mode Callback Return */
|
idt _KiCallbackReturn, INT_32_DPL3 /* INT 2B: User-Mode Callback Return */
|
||||||
idt _KiRaiseAssertion, INT_32_DPL3 /* INT 2C: Debug Assertion Handler */
|
idt _KiRaiseAssertion, INT_32_DPL3 /* INT 2C: Debug Assertion Handler */
|
||||||
idt _KiDebugService, INT_32_DPL3 /* INT 2D: Debug Service Handler */
|
idt _KiDebugService, INT_32_DPL3 /* INT 2D: Debug Service Handler */
|
||||||
idt _KiSystemService, INT_32_DPL3 /* INT 2E: System Call 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
|
.rept 220
|
||||||
idt _KiTrapUnknown, INT_32_DPL0 /* INT 30-FF: UNDEFINED INTERRUPTS */
|
idt _KiTrap0F, INT_32_DPL0 /* INT 30-FF: UNDEFINED INTERRUPTS */
|
||||||
.endr
|
.endr
|
||||||
|
|
||||||
/* System call entrypoints: */
|
/* System call entrypoints: */
|
||||||
|
@ -271,33 +269,28 @@ NoCountTable:
|
||||||
/* Allocate space on our stack */
|
/* Allocate space on our stack */
|
||||||
sub esp, ecx
|
sub esp, ecx
|
||||||
|
|
||||||
/*
|
/* Set the size of the arguments and the destination */
|
||||||
* Copy the arguments from the user stack to our stack
|
|
||||||
* FIXME: This needs to be probed with MmSystemRangeStart
|
|
||||||
*/
|
|
||||||
shr ecx, 2
|
shr ecx, 2
|
||||||
mov edi, esp
|
mov edi, esp
|
||||||
|
|
||||||
|
/* Make sure we're within the User Probe Address */
|
||||||
|
cmp esi, _MmUserProbeAddress
|
||||||
|
jnb AccessViolation
|
||||||
|
|
||||||
|
CopyParams:
|
||||||
|
/* Copy the parameters */
|
||||||
rep movsd
|
rep movsd
|
||||||
|
|
||||||
#ifdef DBG
|
#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
|
* 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
|
* 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
|
* 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
|
* When that standard function prolog is not found, it will stop the
|
||||||
* stack backtrace. Since we do want to backtrace into usermode, let's
|
* stack backtrace. Since we do want to backtrace into usermode, let's
|
||||||
* make GDB happy and create a standard prolog.
|
* make GDB happy and create a standard prolog.
|
||||||
*/
|
*/
|
||||||
SkipCheck:
|
|
||||||
KiSystemService:
|
KiSystemService:
|
||||||
push ebp
|
push ebp
|
||||||
mov ebp,esp
|
mov ebp,esp
|
||||||
|
@ -307,10 +300,11 @@ KiSystemService:
|
||||||
/* Do the System Call */
|
/* Do the System Call */
|
||||||
call ebx
|
call ebx
|
||||||
|
|
||||||
|
AfterSysCall:
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
/* Make sure the user-mode call didn't return at elevated IRQL */
|
/* Make sure the user-mode call didn't return at elevated IRQL */
|
||||||
test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
|
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 */
|
mov esi, eax /* We need to save the syscall's return val */
|
||||||
call _KeGetCurrentIrql@0
|
call _KeGetCurrentIrql@0
|
||||||
or al, al
|
or al, al
|
||||||
|
@ -329,7 +323,7 @@ KiSystemService:
|
||||||
jnz InvalidIndex
|
jnz InvalidIndex
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SkipCheck2:
|
SkipCheck:
|
||||||
|
|
||||||
/* Deallocate the kernel stack frame */
|
/* Deallocate the kernel stack frame */
|
||||||
mov esp, ebp
|
mov esp, ebp
|
||||||
|
@ -363,7 +357,7 @@ _KiServiceExit:
|
||||||
KiBBTUnexpectedRange:
|
KiBBTUnexpectedRange:
|
||||||
|
|
||||||
/* If this isn't a Win32K call, fail */
|
/* If this isn't a Win32K call, fail */
|
||||||
cmp ecx, 0x10
|
cmp ecx, SERVICE_TABLE_TEST
|
||||||
jne InvalidCall
|
jne InvalidCall
|
||||||
|
|
||||||
/* Set up Win32K Table */
|
/* Set up Win32K Table */
|
||||||
|
@ -371,7 +365,10 @@ KiBBTUnexpectedRange:
|
||||||
push ebx
|
push ebx
|
||||||
call _PsConvertToGuiThread@0
|
call _PsConvertToGuiThread@0
|
||||||
|
|
||||||
/* FIXME: Handle failure */
|
/* Check return code */
|
||||||
|
or eax, eax
|
||||||
|
|
||||||
|
/* Restore registers */
|
||||||
pop eax
|
pop eax
|
||||||
pop edx
|
pop edx
|
||||||
|
|
||||||
|
@ -379,8 +376,34 @@ KiBBTUnexpectedRange:
|
||||||
mov ebp, esp
|
mov ebp, esp
|
||||||
mov [esi+KTHREAD_TRAP_FRAME], ebp
|
mov [esi+KTHREAD_TRAP_FRAME], ebp
|
||||||
|
|
||||||
/* Try the Call again */
|
/* Try the Call again, if we suceeded */
|
||||||
jmp SharedCode
|
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:
|
InvalidCall:
|
||||||
|
|
||||||
|
@ -388,6 +411,18 @@ InvalidCall:
|
||||||
mov eax, STATUS_INVALID_SYSTEM_SERVICE
|
mov eax, STATUS_INVALID_SYSTEM_SERVICE
|
||||||
jmp KeReturnFromSystemCall
|
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:
|
BadStack:
|
||||||
|
|
||||||
/* Restore ESP0 stack */
|
/* Restore ESP0 stack */
|
||||||
|
@ -974,57 +1009,34 @@ _KiTrap17:
|
||||||
jne _Kei386EoiHelper@0
|
jne _Kei386EoiHelper@0
|
||||||
jmp _KiV86Complete
|
jmp _KiV86Complete
|
||||||
|
|
||||||
_KiTrap18:
|
_KiTrap0F:
|
||||||
/* Push error code */
|
/* Push error code */
|
||||||
push 0
|
push 0
|
||||||
|
|
||||||
/* Enter trap */
|
/* Enter trap */
|
||||||
TRAP_PROLOG(18)
|
TRAP_PROLOG(15)
|
||||||
|
sti
|
||||||
|
|
||||||
/* Call the C exception handler */
|
/* Raise a fatal exception */
|
||||||
push 18
|
mov eax, 15
|
||||||
|
jmp _KiSystemFatalException
|
||||||
|
|
||||||
|
.func KiSystemFatalException
|
||||||
|
_KiSystemFatalException:
|
||||||
|
|
||||||
|
/* Push the trap frame */
|
||||||
push ebp
|
push ebp
|
||||||
call _KiTrapHandler
|
|
||||||
add esp, 8
|
|
||||||
|
|
||||||
/* Check for v86 recovery */
|
/* Push empty parameters */
|
||||||
cmp eax, 1
|
push 0
|
||||||
|
push 0
|
||||||
/* Return to caller */
|
|
||||||
jne _Kei386EoiHelper@0
|
|
||||||
jmp _KiV86Complete
|
|
||||||
|
|
||||||
_KiTrap19:
|
|
||||||
/* Push error code */
|
|
||||||
push 0
|
push 0
|
||||||
|
|
||||||
/* Enter trap */
|
/* Push trap number and bugcheck code */
|
||||||
TRAP_PROLOG(19)
|
push eax
|
||||||
|
push UNEXPECTED_KERNEL_MODE_TRAP
|
||||||
|
call _KeBugCheckWithTf@24
|
||||||
|
ret
|
||||||
|
.endfunc
|
||||||
|
|
||||||
/* Call the C exception handler */
|
|
||||||
push 19
|
|
||||||
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 0
|
|
||||||
|
|
||||||
/* Enter trap */
|
|
||||||
TRAP_PROLOG(255)
|
|
||||||
|
|
||||||
/* Check for v86 recovery */
|
|
||||||
cmp eax, 1
|
|
||||||
|
|
||||||
/* Return to caller */
|
|
||||||
jne _Kei386EoiHelper@0
|
|
||||||
jmp _KiV86Complete
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue